blob: 43d5c9bccec54d54d70d033cde122fe4f4da29b5 [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 Rogers4f6ad8a2013-03-18 15:27:28 -070018#include "dex_file-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019#include "mirror/abstract_method-inl.h"
20#include "mirror/class-inl.h"
21#include "mirror/field-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070022#include "runtime_support.h"
23
24#include <stdint.h>
25
26namespace art {
27
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080028extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
29 const mirror::AbstractMethod* referrer,
30 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070031 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080032 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070033 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070034 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070035 }
36 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -070037 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070038 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070039 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070040 }
41 return 0; // Will throw exception by checking with Thread::Current
42}
43
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080044extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
45 const mirror::AbstractMethod* referrer,
46 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070047 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080048 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070049 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070050 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070051 }
52 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -070053 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070054 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070055 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070056 }
57 return 0; // Will throw exception by checking with Thread::Current
58}
59
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080060extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
61 const mirror::AbstractMethod* referrer,
62 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070063 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080064 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
65 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -070066 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070067 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070068 }
69 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080070 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -070071 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070072 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070073 }
74 return NULL; // Will throw exception by checking with Thread::Current
75}
76
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080077extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
78 const mirror::AbstractMethod* referrer, Thread* self,
79 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -070080 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080081 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070082 if (LIKELY(field != NULL && obj != NULL)) {
83 return field->Get32(obj);
84 }
85 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -070086 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -070087 if (LIKELY(field != NULL)) {
88 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -070089 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -070090 } else {
91 return field->Get32(obj);
92 }
93 }
94 return 0; // Will throw exception by checking with Thread::Current
95}
96
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080097extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
98 const mirror::AbstractMethod* referrer, Thread* self,
99 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700100 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800101 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700102 if (LIKELY(field != NULL && obj != NULL)) {
103 return field->Get64(obj);
104 }
105 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700106 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700107 if (LIKELY(field != NULL)) {
108 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700109 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700110 } else {
111 return field->Get64(obj);
112 }
113 }
114 return 0; // Will throw exception by checking with Thread::Current
115}
116
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800117extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
118 const mirror::AbstractMethod* referrer,
119 Thread* self,
120 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700121 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800122 mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700123 if (LIKELY(field != NULL && obj != NULL)) {
124 return field->GetObj(obj);
125 }
126 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800127 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700128 if (LIKELY(field != NULL)) {
129 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700130 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700131 } else {
132 return field->GetObj(obj);
133 }
134 }
135 return NULL; // Will throw exception by checking with Thread::Current
136}
137
138extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800139 const mirror::AbstractMethod* referrer, Thread* self,
140 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700141 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700143 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700144 field->Set32(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700145 return 0; // success
146 }
147 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700148 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700149 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700150 field->Set32(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700151 return 0; // success
152 }
153 return -1; // failure
154}
155
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
157 uint64_t new_value, Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700158 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800159 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700160 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700161 field->Set64(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700162 return 0; // success
163 }
164 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700165 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700166 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700167 field->Set64(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700168 return 0; // success
169 }
170 return -1; // failure
171}
172
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800173extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
174 const mirror::AbstractMethod* referrer, Thread* self,
175 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700176 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800177 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
178 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700179 if (LIKELY(field != NULL)) {
180 if (LIKELY(!FieldHelper(field).IsPrimitiveType())) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700181 field->SetObj(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700182 return 0; // success
183 }
184 }
185 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800186 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700187 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700188 field->SetObj(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700189 return 0; // success
190 }
191 return -1; // failure
192}
193
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800194extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
195 const mirror::AbstractMethod* referrer, Thread* self,
196 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700197 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800198 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700199 if (LIKELY(field != NULL && obj != NULL)) {
200 field->Set32(obj, new_value);
201 return 0; // success
202 }
203 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700204 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700205 if (LIKELY(field != NULL)) {
206 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700207 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700208 } else {
209 field->Set32(obj, new_value);
210 return 0; // success
211 }
212 }
213 return -1; // failure
214}
215
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800216extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
217 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700218 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800219 mirror::AbstractMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly);
220 mirror::AbstractMethod* referrer =
221 sp[callee_save->GetFrameSizeInBytes() / sizeof(mirror::AbstractMethod*)];
222 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
223 sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700224 if (LIKELY(field != NULL && obj != NULL)) {
225 field->Set64(obj, new_value);
226 return 0; // success
227 }
228 *sp = callee_save;
229 self->SetTopOfStack(sp, 0);
Ian Rogers08f753d2012-08-24 14:35:25 -0700230 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700231 if (LIKELY(field != NULL)) {
232 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700233 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700234 } else {
235 field->Set64(obj, new_value);
236 return 0; // success
237 }
238 }
239 return -1; // failure
240}
241
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800242extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
243 mirror::Object* new_value,
244 const mirror::AbstractMethod* referrer, Thread* self,
245 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700246 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800247 mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
248 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700249 if (LIKELY(field != NULL && obj != NULL)) {
250 field->SetObj(obj, new_value);
251 return 0; // success
252 }
253 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800254 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite,
255 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700256 if (LIKELY(field != NULL)) {
257 if (UNLIKELY(obj == NULL)) {
Ian Rogers87e552d2012-08-31 15:54:48 -0700258 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700259 } else {
260 field->SetObj(obj, new_value);
261 return 0; // success
262 }
263 }
264 return -1; // failure
265}
266
267} // namespace art