1 /*
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 "art_field-inl.h"
18 #include "art_method-inl.h"
19 #include "callee_save_frame.h"
20 #include "dex_file-inl.h"
21 #include "entrypoints/entrypoint_utils-inl.h"
22 #include "mirror/class-inl.h"
23
24 #include <stdint.h>
25
26 namespace art {
27
artGetByteStaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)28 extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx, ArtMethod* referrer,
29 Thread* self)
30 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
31 ScopedQuickEntrypointChecks sqec(self);
32 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
33 if (LIKELY(field != nullptr)) {
34 return field->GetByte(field->GetDeclaringClass());
35 }
36 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int8_t));
37 if (LIKELY(field != nullptr)) {
38 return field->GetByte(field->GetDeclaringClass());
39 }
40 return 0; // Will throw exception by checking with Thread::Current.
41 }
42
artGetBooleanStaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)43 extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx, ArtMethod* referrer,
44 Thread* self)
45 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
46 ScopedQuickEntrypointChecks sqec(self);
47 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
48 if (LIKELY(field != nullptr)) {
49 return field->GetBoolean(field->GetDeclaringClass());
50 }
51 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int8_t));
52 if (LIKELY(field != nullptr)) {
53 return field->GetBoolean(field->GetDeclaringClass());
54 }
55 return 0; // Will throw exception by checking with Thread::Current.
56 }
57
artGetShortStaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)58 extern "C" int16_t artGetShortStaticFromCode(uint32_t field_idx, ArtMethod* referrer,
59 Thread* self)
60 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
61 ScopedQuickEntrypointChecks sqec(self);
62 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
63 if (LIKELY(field != nullptr)) {
64 return field->GetShort(field->GetDeclaringClass());
65 }
66 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int16_t));
67 if (LIKELY(field != nullptr)) {
68 return field->GetShort(field->GetDeclaringClass());
69 }
70 return 0; // Will throw exception by checking with Thread::Current.
71 }
72
artGetCharStaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)73 extern "C" uint16_t artGetCharStaticFromCode(uint32_t field_idx,
74 ArtMethod* referrer,
75 Thread* self)
76 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
77 ScopedQuickEntrypointChecks sqec(self);
78 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
79 if (LIKELY(field != nullptr)) {
80 return field->GetChar(field->GetDeclaringClass());
81 }
82 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int16_t));
83 if (LIKELY(field != nullptr)) {
84 return field->GetChar(field->GetDeclaringClass());
85 }
86 return 0; // Will throw exception by checking with Thread::Current.
87 }
88
artGet32StaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)89 extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
90 ArtMethod* referrer,
91 Thread* self)
92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93 ScopedQuickEntrypointChecks sqec(self);
94 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
95 if (LIKELY(field != nullptr)) {
96 return field->Get32(field->GetDeclaringClass());
97 }
98 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int32_t));
99 if (LIKELY(field != nullptr)) {
100 return field->Get32(field->GetDeclaringClass());
101 }
102 return 0; // Will throw exception by checking with Thread::Current.
103 }
104
artGet64StaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)105 extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
106 ArtMethod* referrer,
107 Thread* self)
108 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
109 ScopedQuickEntrypointChecks sqec(self);
110 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
111 if (LIKELY(field != nullptr)) {
112 return field->Get64(field->GetDeclaringClass());
113 }
114 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int64_t));
115 if (LIKELY(field != nullptr)) {
116 return field->Get64(field->GetDeclaringClass());
117 }
118 return 0; // Will throw exception by checking with Thread::Current.
119 }
120
artGetObjStaticFromCode(uint32_t field_idx,ArtMethod * referrer,Thread * self)121 extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
122 ArtMethod* referrer,
123 Thread* self)
124 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125 ScopedQuickEntrypointChecks sqec(self);
126 ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
127 sizeof(mirror::HeapReference<mirror::Object>));
128 if (LIKELY(field != nullptr)) {
129 return field->GetObj(field->GetDeclaringClass());
130 }
131 field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, self,
132 sizeof(mirror::HeapReference<mirror::Object>));
133 if (LIKELY(field != nullptr)) {
134 return field->GetObj(field->GetDeclaringClass());
135 }
136 return nullptr; // Will throw exception by checking with Thread::Current.
137 }
138
artGetByteInstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)139 extern "C" int8_t artGetByteInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
140 ArtMethod* referrer, Thread* self)
141 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
142 ScopedQuickEntrypointChecks sqec(self);
143 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
144 if (LIKELY(field != nullptr && obj != nullptr)) {
145 return field->GetByte(obj);
146 }
147 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
148 sizeof(int8_t));
149 if (LIKELY(field != nullptr)) {
150 if (UNLIKELY(obj == nullptr)) {
151 ThrowNullPointerExceptionForFieldAccess(field, true);
152 } else {
153 return field->GetByte(obj);
154 }
155 }
156 return 0; // Will throw exception by checking with Thread::Current.
157 }
158
artGetBooleanInstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)159 extern "C" uint8_t artGetBooleanInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
160 ArtMethod* referrer, Thread* self)
161 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
162 ScopedQuickEntrypointChecks sqec(self);
163 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
164 if (LIKELY(field != nullptr && obj != nullptr)) {
165 return field->GetBoolean(obj);
166 }
167 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
168 sizeof(int8_t));
169 if (LIKELY(field != nullptr)) {
170 if (UNLIKELY(obj == nullptr)) {
171 ThrowNullPointerExceptionForFieldAccess(field, true);
172 } else {
173 return field->GetBoolean(obj);
174 }
175 }
176 return 0; // Will throw exception by checking with Thread::Current.
177 }
artGetShortInstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)178 extern "C" int16_t artGetShortInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
179 ArtMethod* referrer, Thread* self)
180 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
181 ScopedQuickEntrypointChecks sqec(self);
182 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
183 if (LIKELY(field != nullptr && obj != nullptr)) {
184 return field->GetShort(obj);
185 }
186 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
187 sizeof(int16_t));
188 if (LIKELY(field != nullptr)) {
189 if (UNLIKELY(obj == nullptr)) {
190 ThrowNullPointerExceptionForFieldAccess(field, true);
191 } else {
192 return field->GetShort(obj);
193 }
194 }
195 return 0; // Will throw exception by checking with Thread::Current.
196 }
197
artGetCharInstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)198 extern "C" uint16_t artGetCharInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
199 ArtMethod* referrer, Thread* self)
200 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
201 ScopedQuickEntrypointChecks sqec(self);
202 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
203 if (LIKELY(field != nullptr && obj != nullptr)) {
204 return field->GetChar(obj);
205 }
206 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
207 sizeof(int16_t));
208 if (LIKELY(field != nullptr)) {
209 if (UNLIKELY(obj == nullptr)) {
210 ThrowNullPointerExceptionForFieldAccess(field, true);
211 } else {
212 return field->GetChar(obj);
213 }
214 }
215 return 0; // Will throw exception by checking with Thread::Current.
216 }
217
artGet32InstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)218 extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
219 ArtMethod* referrer, Thread* self)
220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
221 ScopedQuickEntrypointChecks sqec(self);
222 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
223 if (LIKELY(field != nullptr && obj != nullptr)) {
224 return field->Get32(obj);
225 }
226 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
227 sizeof(int32_t));
228 if (LIKELY(field != nullptr)) {
229 if (UNLIKELY(obj == nullptr)) {
230 ThrowNullPointerExceptionForFieldAccess(field, true);
231 } else {
232 return field->Get32(obj);
233 }
234 }
235 return 0; // Will throw exception by checking with Thread::Current.
236 }
237
artGet64InstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)238 extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
239 ArtMethod* referrer, Thread* self)
240 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
241 ScopedQuickEntrypointChecks sqec(self);
242 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
243 if (LIKELY(field != nullptr && obj != nullptr)) {
244 return field->Get64(obj);
245 }
246 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
247 sizeof(int64_t));
248 if (LIKELY(field != nullptr)) {
249 if (UNLIKELY(obj == nullptr)) {
250 ThrowNullPointerExceptionForFieldAccess(field, true);
251 } else {
252 return field->Get64(obj);
253 }
254 }
255 return 0; // Will throw exception by checking with Thread::Current.
256 }
257
artGetObjInstanceFromCode(uint32_t field_idx,mirror::Object * obj,ArtMethod * referrer,Thread * self)258 extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
259 ArtMethod* referrer,
260 Thread* self)
261 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
262 ScopedQuickEntrypointChecks sqec(self);
263 ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
264 sizeof(mirror::HeapReference<mirror::Object>));
265 if (LIKELY(field != nullptr && obj != nullptr)) {
266 return field->GetObj(obj);
267 }
268 field = FindFieldFromCode<InstanceObjectRead, true>(
269 field_idx, referrer, self, sizeof(mirror::HeapReference<mirror::Object>));
270 if (LIKELY(field != nullptr)) {
271 if (UNLIKELY(obj == nullptr)) {
272 ThrowNullPointerExceptionForFieldAccess(field, true);
273 } else {
274 return field->GetObj(obj);
275 }
276 }
277 return nullptr; // Will throw exception by checking with Thread::Current.
278 }
279
artSet8StaticFromCode(uint32_t field_idx,uint32_t new_value,ArtMethod * referrer,Thread * self)280 extern "C" int artSet8StaticFromCode(uint32_t field_idx, uint32_t new_value,
281 ArtMethod* referrer, Thread* self)
282 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
283 ScopedQuickEntrypointChecks sqec(self);
284 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int8_t));
285 if (LIKELY(field != nullptr)) {
286 Primitive::Type type = field->GetTypeAsPrimitiveType();
287 // Compiled code can't use transactional mode.
288 if (type == Primitive::kPrimBoolean) {
289 field->SetBoolean<false>(field->GetDeclaringClass(), new_value);
290 } else {
291 DCHECK_EQ(Primitive::kPrimByte, type);
292 field->SetByte<false>(field->GetDeclaringClass(), new_value);
293 }
294 return 0; // success
295 }
296 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int8_t));
297 if (LIKELY(field != nullptr)) {
298 Primitive::Type type = field->GetTypeAsPrimitiveType();
299 // Compiled code can't use transactional mode.
300 if (type == Primitive::kPrimBoolean) {
301 field->SetBoolean<false>(field->GetDeclaringClass(), new_value);
302 } else {
303 DCHECK_EQ(Primitive::kPrimByte, type);
304 field->SetByte<false>(field->GetDeclaringClass(), new_value);
305 }
306 return 0; // success
307 }
308 return -1; // failure
309 }
310
artSet16StaticFromCode(uint32_t field_idx,uint16_t new_value,ArtMethod * referrer,Thread * self)311 extern "C" int artSet16StaticFromCode(uint32_t field_idx, uint16_t new_value,
312 ArtMethod* referrer, Thread* self)
313 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
314 ScopedQuickEntrypointChecks sqec(self);
315 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int16_t));
316 if (LIKELY(field != nullptr)) {
317 Primitive::Type type = field->GetTypeAsPrimitiveType();
318 // Compiled code can't use transactional mode.
319 if (type == Primitive::kPrimChar) {
320 field->SetChar<false>(field->GetDeclaringClass(), new_value);
321 } else {
322 DCHECK_EQ(Primitive::kPrimShort, type);
323 field->SetShort<false>(field->GetDeclaringClass(), new_value);
324 }
325 return 0; // success
326 }
327 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int16_t));
328 if (LIKELY(field != nullptr)) {
329 Primitive::Type type = field->GetTypeAsPrimitiveType();
330 // Compiled code can't use transactional mode.
331 if (type == Primitive::kPrimChar) {
332 field->SetChar<false>(field->GetDeclaringClass(), new_value);
333 } else {
334 DCHECK_EQ(Primitive::kPrimShort, type);
335 field->SetShort<false>(field->GetDeclaringClass(), new_value);
336 }
337 return 0; // success
338 }
339 return -1; // failure
340 }
341
artSet32StaticFromCode(uint32_t field_idx,uint32_t new_value,ArtMethod * referrer,Thread * self)342 extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
343 ArtMethod* referrer, Thread* self)
344 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
345 ScopedQuickEntrypointChecks sqec(self);
346 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
347 if (LIKELY(field != nullptr)) {
348 // Compiled code can't use transactional mode.
349 field->Set32<false>(field->GetDeclaringClass(), new_value);
350 return 0; // success
351 }
352 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int32_t));
353 if (LIKELY(field != nullptr)) {
354 // Compiled code can't use transactional mode.
355 field->Set32<false>(field->GetDeclaringClass(), new_value);
356 return 0; // success
357 }
358 return -1; // failure
359 }
360
artSet64StaticFromCode(uint32_t field_idx,ArtMethod * referrer,uint64_t new_value,Thread * self)361 extern "C" int artSet64StaticFromCode(uint32_t field_idx, ArtMethod* referrer,
362 uint64_t new_value, Thread* self)
363 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
364 ScopedQuickEntrypointChecks sqec(self);
365 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
366 if (LIKELY(field != nullptr)) {
367 // Compiled code can't use transactional mode.
368 field->Set64<false>(field->GetDeclaringClass(), new_value);
369 return 0; // success
370 }
371 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int64_t));
372 if (LIKELY(field != nullptr)) {
373 // Compiled code can't use transactional mode.
374 field->Set64<false>(field->GetDeclaringClass(), new_value);
375 return 0; // success
376 }
377 return -1; // failure
378 }
379
artSetObjStaticFromCode(uint32_t field_idx,mirror::Object * new_value,ArtMethod * referrer,Thread * self)380 extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
381 ArtMethod* referrer, Thread* self)
382 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
383 ScopedQuickEntrypointChecks sqec(self);
384 ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
385 sizeof(mirror::HeapReference<mirror::Object>));
386 if (LIKELY(field != nullptr)) {
387 if (LIKELY(!field->IsPrimitiveType())) {
388 // Compiled code can't use transactional mode.
389 field->SetObj<false>(field->GetDeclaringClass(), new_value);
390 return 0; // success
391 }
392 }
393 field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, self,
394 sizeof(mirror::HeapReference<mirror::Object>));
395 if (LIKELY(field != nullptr)) {
396 // Compiled code can't use transactional mode.
397 field->SetObj<false>(field->GetDeclaringClass(), new_value);
398 return 0; // success
399 }
400 return -1; // failure
401 }
402
artSet8InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint8_t new_value,ArtMethod * referrer,Thread * self)403 extern "C" int artSet8InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint8_t new_value,
404 ArtMethod* referrer, Thread* self)
405 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
406 ScopedQuickEntrypointChecks sqec(self);
407 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t));
408 if (LIKELY(field != nullptr && obj != nullptr)) {
409 Primitive::Type type = field->GetTypeAsPrimitiveType();
410 // Compiled code can't use transactional mode.
411 if (type == Primitive::kPrimBoolean) {
412 field->SetBoolean<false>(obj, new_value);
413 } else {
414 DCHECK_EQ(Primitive::kPrimByte, type);
415 field->SetByte<false>(obj, new_value);
416 }
417 return 0; // success
418 }
419 {
420 StackHandleScope<1> hs(self);
421 HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
422 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
423 sizeof(int8_t));
424 }
425 if (LIKELY(field != nullptr)) {
426 if (UNLIKELY(obj == nullptr)) {
427 ThrowNullPointerExceptionForFieldAccess(field, false);
428 } else {
429 Primitive::Type type = field->GetTypeAsPrimitiveType();
430 // Compiled code can't use transactional mode.
431 if (type == Primitive::kPrimBoolean) {
432 field->SetBoolean<false>(obj, new_value);
433 } else {
434 field->SetByte<false>(obj, new_value);
435 }
436 return 0; // success
437 }
438 }
439 return -1; // failure
440 }
441
artSet16InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint16_t new_value,ArtMethod * referrer,Thread * self)442 extern "C" int artSet16InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint16_t new_value,
443 ArtMethod* referrer, Thread* self)
444 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
445 ScopedQuickEntrypointChecks sqec(self);
446 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int16_t));
447 if (LIKELY(field != nullptr && obj != nullptr)) {
448 Primitive::Type type = field->GetTypeAsPrimitiveType();
449 // Compiled code can't use transactional mode.
450 if (type == Primitive::kPrimChar) {
451 field->SetChar<false>(obj, new_value);
452 } else {
453 DCHECK_EQ(Primitive::kPrimShort, type);
454 field->SetShort<false>(obj, new_value);
455 }
456 return 0; // success
457 }
458 {
459 StackHandleScope<1> hs(self);
460 HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
461 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
462 sizeof(int16_t));
463 }
464 if (LIKELY(field != nullptr)) {
465 if (UNLIKELY(obj == nullptr)) {
466 ThrowNullPointerExceptionForFieldAccess(field, false);
467 } else {
468 Primitive::Type type = field->GetTypeAsPrimitiveType();
469 // Compiled code can't use transactional mode.
470 if (type == Primitive::kPrimChar) {
471 field->SetChar<false>(obj, new_value);
472 } else {
473 DCHECK_EQ(Primitive::kPrimShort, type);
474 field->SetShort<false>(obj, new_value);
475 }
476 return 0; // success
477 }
478 }
479 return -1; // failure
480 }
481
artSet32InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint32_t new_value,ArtMethod * referrer,Thread * self)482 extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
483 ArtMethod* referrer, Thread* self)
484 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
485 ScopedQuickEntrypointChecks sqec(self);
486 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
487 if (LIKELY(field != nullptr && obj != nullptr)) {
488 // Compiled code can't use transactional mode.
489 field->Set32<false>(obj, new_value);
490 return 0; // success
491 }
492 {
493 StackHandleScope<1> hs(self);
494 HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
495 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
496 sizeof(int32_t));
497 }
498 if (LIKELY(field != nullptr)) {
499 if (UNLIKELY(obj == nullptr)) {
500 ThrowNullPointerExceptionForFieldAccess(field, false);
501 } else {
502 // Compiled code can't use transactional mode.
503 field->Set32<false>(obj, new_value);
504 return 0; // success
505 }
506 }
507 return -1; // failure
508 }
509
artSet64InstanceFromCode(uint32_t field_idx,mirror::Object * obj,uint64_t new_value,ArtMethod * referrer,Thread * self)510 extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
511 ArtMethod* referrer, Thread* self)
512 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
513 ScopedQuickEntrypointChecks sqec(self);
514 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t));
515 if (LIKELY(field != nullptr && obj != nullptr)) {
516 // Compiled code can't use transactional mode.
517 field->Set64<false>(obj, new_value);
518 return 0; // success
519 }
520 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
521 sizeof(int64_t));
522 if (LIKELY(field != nullptr)) {
523 if (UNLIKELY(obj == nullptr)) {
524 ThrowNullPointerExceptionForFieldAccess(field, false);
525 } else {
526 // Compiled code can't use transactional mode.
527 field->Set64<false>(obj, new_value);
528 return 0; // success
529 }
530 }
531 return -1; // failure
532 }
533
artSetObjInstanceFromCode(uint32_t field_idx,mirror::Object * obj,mirror::Object * new_value,ArtMethod * referrer,Thread * self)534 extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
535 mirror::Object* new_value,
536 ArtMethod* referrer, Thread* self)
537 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
538 ScopedQuickEntrypointChecks sqec(self);
539 ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
540 sizeof(mirror::HeapReference<mirror::Object>));
541 if (LIKELY(field != nullptr && obj != nullptr)) {
542 // Compiled code can't use transactional mode.
543 field->SetObj<false>(obj, new_value);
544 return 0; // success
545 }
546 field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, self,
547 sizeof(mirror::HeapReference<mirror::Object>));
548 if (LIKELY(field != nullptr)) {
549 if (UNLIKELY(obj == nullptr)) {
550 ThrowNullPointerExceptionForFieldAccess(field, false);
551 } else {
552 // Compiled code can't use transactional mode.
553 field->SetObj<false>(obj, new_value);
554 return 0; // success
555 }
556 }
557 return -1; // failure
558 }
559
560 } // namespace art
561