blob: 5821063cf6423be5143b3389841c42547095e2e6 [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 Rogers62d6c772013-02-27 08:32:07 -080089 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
90 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -070091 } else {
92 return field->Get32(obj);
93 }
94 }
95 return 0; // Will throw exception by checking with Thread::Current
96}
97
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080098extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
99 const mirror::AbstractMethod* referrer, Thread* self,
100 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700101 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800102 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700103 if (LIKELY(field != NULL && obj != NULL)) {
104 return field->Get64(obj);
105 }
106 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700107 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700108 if (LIKELY(field != NULL)) {
109 if (UNLIKELY(obj == NULL)) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800110 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
111 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700112 } else {
113 return field->Get64(obj);
114 }
115 }
116 return 0; // Will throw exception by checking with Thread::Current
117}
118
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800119extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
120 const mirror::AbstractMethod* referrer,
121 Thread* self,
122 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700123 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800124 mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700125 if (LIKELY(field != NULL && obj != NULL)) {
126 return field->GetObj(obj);
127 }
128 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800129 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700130 if (LIKELY(field != NULL)) {
131 if (UNLIKELY(obj == NULL)) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800132 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
133 ThrowNullPointerExceptionForFieldAccess(throw_location, field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700134 } else {
135 return field->GetObj(obj);
136 }
137 }
138 return NULL; // Will throw exception by checking with Thread::Current
139}
140
141extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142 const mirror::AbstractMethod* referrer, Thread* self,
143 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700144 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800145 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700146 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700147 field->Set32(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700148 return 0; // success
149 }
150 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700151 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700152 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700153 field->Set32(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700154 return 0; // success
155 }
156 return -1; // failure
157}
158
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800159extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
160 uint64_t new_value, Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700161 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800162 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700163 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700164 field->Set64(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700165 return 0; // success
166 }
167 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700168 field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700169 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700170 field->Set64(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700171 return 0; // success
172 }
173 return -1; // failure
174}
175
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800176extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
177 const mirror::AbstractMethod* referrer, Thread* self,
178 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700179 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800180 mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
181 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700182 if (LIKELY(field != NULL)) {
183 if (LIKELY(!FieldHelper(field).IsPrimitiveType())) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700184 field->SetObj(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700185 return 0; // success
186 }
187 }
188 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800189 field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700190 if (LIKELY(field != NULL)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700191 field->SetObj(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700192 return 0; // success
193 }
194 return -1; // failure
195}
196
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800197extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
198 const mirror::AbstractMethod* referrer, Thread* self,
199 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700200 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800201 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700202 if (LIKELY(field != NULL && obj != NULL)) {
203 field->Set32(obj, new_value);
204 return 0; // success
205 }
206 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers08f753d2012-08-24 14:35:25 -0700207 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700208 if (LIKELY(field != NULL)) {
209 if (UNLIKELY(obj == NULL)) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800210 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
211 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700212 } else {
213 field->Set32(obj, new_value);
214 return 0; // success
215 }
216 }
217 return -1; // failure
218}
219
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800220extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
221 Thread* self, mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700222 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800223 mirror::AbstractMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly);
224 mirror::AbstractMethod* referrer =
225 sp[callee_save->GetFrameSizeInBytes() / sizeof(mirror::AbstractMethod*)];
226 mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
227 sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700228 if (LIKELY(field != NULL && obj != NULL)) {
229 field->Set64(obj, new_value);
230 return 0; // success
231 }
232 *sp = callee_save;
233 self->SetTopOfStack(sp, 0);
Ian Rogers08f753d2012-08-24 14:35:25 -0700234 field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t));
Ian Rogers57b86d42012-03-27 16:05:41 -0700235 if (LIKELY(field != NULL)) {
236 if (UNLIKELY(obj == NULL)) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800237 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
238 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700239 } else {
240 field->Set64(obj, new_value);
241 return 0; // success
242 }
243 }
244 return -1; // failure
245}
246
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800247extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
248 mirror::Object* new_value,
249 const mirror::AbstractMethod* referrer, Thread* self,
250 mirror::AbstractMethod** sp)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700251 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800252 mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
253 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700254 if (LIKELY(field != NULL && obj != NULL)) {
255 field->SetObj(obj, new_value);
256 return 0; // success
257 }
258 FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800259 field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite,
260 sizeof(mirror::Object*));
Ian Rogers57b86d42012-03-27 16:05:41 -0700261 if (LIKELY(field != NULL)) {
262 if (UNLIKELY(obj == NULL)) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800263 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
264 ThrowNullPointerExceptionForFieldAccess(throw_location, field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700265 } else {
266 field->SetObj(obj, new_value);
267 return 0; // success
268 }
269 }
270 return -1; // failure
271}
272
273} // namespace art