blob: a564fa95dfb4d353e633c3955e808b54b01588a8 [file] [log] [blame]
Ian Rogers57b86d42012-03-27 16:05:41 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "callee_save_frame.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080018#include "mirror/abstract_method-inl.h"
19#include "mirror/class-inl.h"
20#include "mirror/field-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070021#include "runtime_support.h"
22
23#include <stdint.h>
24
25namespace art {
26
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
28 const mirror::AbstractMethod* referrer,
29 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070030 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070032 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070033 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070034 }
35 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -070036 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070037 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070038 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070039 }
40 return 0; // Will throw exception by checking with Thread::Current
41}
42
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
44 const mirror::AbstractMethod* referrer,
45 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070046 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070048 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070049 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070050 }
51 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -070052 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070053 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070054 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070055 }
56 return 0; // Will throw exception by checking with Thread::Current
57}
58
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
60 const mirror::AbstractMethod* referrer,
61 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070062 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080063 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
64 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -070065 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070066 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070067 }
68 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080069 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -070070 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070071 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070072 }
73 return NULL; // Will throw exception by checking with Thread::Current
74}
75
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080076extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
77 const mirror::AbstractMethod* referrer, Thread* self,
78 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070079 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080080 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070081 if (LIKELY(field != NULL && obj != NULL)) {
82 return field->Get32(obj);
83 }
84 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -070085 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070086 if (LIKELY(field != NULL)) {
87 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -070088 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -070089 } else {
90 return field->Get32(obj);
91 }
92 }
93 return 0; // Will throw exception by checking with Thread::Current
94}
95
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080096extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
97 const mirror::AbstractMethod* referrer, Thread* self,
98 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070099 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800100 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700101 if (LIKELY(field != NULL && obj != NULL)) {
102 return field->Get64(obj);
103 }
104 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700105 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700106 if (LIKELY(field != NULL)) {
107 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700108 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700109 } else {
110 return field->Get64(obj);
111 }
112 }
113 return 0; // Will throw exception by checking with Thread::Current
114}
115
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800116extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
117 const mirror::AbstractMethod* referrer,
118 Thread* self,
119 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700120 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800121 mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700122 if (LIKELY(field != NULL && obj != NULL)) {
123 return field->GetObj(obj);
124 }
125 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800126 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700127 if (LIKELY(field != NULL)) {
128 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700129 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700130 } else {
131 return field->GetObj(obj);
132 }
133 }
134 return NULL; // Will throw exception by checking with Thread::Current
135}
136
137extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800138 const mirror::AbstractMethod* referrer, Thread* self,
139 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700140 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800141 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700142 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700143 field->Set32(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700144 return 0; // success
145 }
146 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700147 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700148 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700149 field->Set32(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700150 return 0; // success
151 }
152 return -1; // failure
153}
154
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800155extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
156 uint64_t new_value, Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700157 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800158 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700159 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700160 field->Set64(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700161 return 0; // success
162 }
163 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700164 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700165 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700166 field->Set64(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700167 return 0; // success
168 }
169 return -1; // failure
170}
171
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800172extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
173 const mirror::AbstractMethod* referrer, Thread* self,
174 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700175 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800176 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
177 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700178 if (LIKELY(field != NULL)) {
179 if (LIKELY(!FieldHelper(field).IsPrimitiveType())) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700180 field->SetObj(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700181 return 0; // success
182 }
183 }
184 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700186 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700187 field->SetObj(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700188 return 0; // success
189 }
190 return -1; // failure
191}
192
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800193extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
194 const mirror::AbstractMethod* referrer, Thread* self,
195 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700196 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800197 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700198 if (LIKELY(field != NULL && obj != NULL)) {
199 field->Set32(obj, new_value);
200 return 0; // success
201 }
202 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700203 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700204 if (LIKELY(field != NULL)) {
205 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700206 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700207 } else {
208 field->Set32(obj, new_value);
209 return 0; // success
210 }
211 }
212 return -1; // failure
213}
214
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800215extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
216 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700217 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800218 mirror::AbstractMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly);
219 mirror::AbstractMethod* referrer =
220 sp[callee_save->GetFrameSizeInBytes() / sizeof(mirror::AbstractMethod*)];
221 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
222 sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700223 if (LIKELY(field != NULL && obj != NULL)) {
224 field->Set64(obj, new_value);
225 return 0; // success
226 }
227 *sp = callee_save;
228 self->SetTopOfStack(sp, 0);
Ian Rogers08f753d2012-08-24 14:35:25 -0700229 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700230 if (LIKELY(field != NULL)) {
231 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700232 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700233 } else {
234 field->Set64(obj, new_value);
235 return 0; // success
236 }
237 }
238 return -1; // failure
239}
240
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800241extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
242 mirror::Object* new_value,
243 const mirror::AbstractMethod* referrer, Thread* self,
244 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700245 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800246 mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
247 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700248 if (LIKELY(field != NULL && obj != NULL)) {
249 field->SetObj(obj, new_value);
250 return 0; // success
251 }
252 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800253 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite,
254 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700255 if (LIKELY(field != NULL)) {
256 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700257 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700258 } else {
259 field->SetObj(obj, new_value);
260 return 0; // success
261 }
262 }
263 return -1; // failure
264}
265
266} // namespace art