blob: 7361d34b6a648b3583c94407bc98a30cf091c5aa [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
Mathieu Chartierc7853442015-03-27 14:35:38 -070017#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070018#include "art_method-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070019#include "callee_save_frame.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070020#include "dex_file-inl.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070021#include "entrypoints/entrypoint_utils-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include "mirror/class-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070023
24#include <stdint.h>
25
26namespace art {
27
Mathieu Chartiere401d142015-04-22 13:56:20 -070028extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx, ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070029 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070030 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070031 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070032 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070033 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070034 return field->GetByte(field->GetDeclaringClass());
35 }
Fred Shih37f05ef2014-07-16 18:38:08 -070036 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070037 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070038 return field->GetByte(field->GetDeclaringClass());
39 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070040 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070041}
42
Mathieu Chartiere401d142015-04-22 13:56:20 -070043extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx, ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070044 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070045 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070046 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070047 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070048 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070049 return field->GetBoolean(field->GetDeclaringClass());
50 }
Fred Shih37f05ef2014-07-16 18:38:08 -070051 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070052 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070053 return field->GetBoolean(field->GetDeclaringClass());
54 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070055 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070056}
57
Mathieu Chartiere401d142015-04-22 13:56:20 -070058extern "C" int16_t artGetShortStaticFromCode(uint32_t field_idx, ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070059 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070060 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070061 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070062 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070063 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070064 return field->GetShort(field->GetDeclaringClass());
65 }
Fred Shih37f05ef2014-07-16 18:38:08 -070066 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070067 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070068 return field->GetShort(field->GetDeclaringClass());
69 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070070 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070071}
72
73extern "C" uint16_t artGetCharStaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -070074 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070075 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070076 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070077 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070078 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070079 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070080 return field->GetChar(field->GetDeclaringClass());
81 }
Fred Shih37f05ef2014-07-16 18:38:08 -070082 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070083 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070084 return field->GetChar(field->GetDeclaringClass());
85 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070086 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070087}
88
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080089extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -070090 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070091 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070092 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070093 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070094 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070095 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070096 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -070097 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +020098 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070099 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700100 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700101 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700102 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700103}
104
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800105extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700106 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700107 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700108 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700109 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700110 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700111 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700112 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700113 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200114 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700115 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700116 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700117 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700118 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700119}
120
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800121extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700122 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700123 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700124 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700125 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700126 ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
127 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700128 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700129 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700130 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200131 field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, self,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800132 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700133 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700134 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700135 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700136 return nullptr; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700137}
138
Fred Shih37f05ef2014-07-16 18:38:08 -0700139extern "C" int8_t artGetByteInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700140 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700141 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700142 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700143 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700144 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700145 return field->GetByte(obj);
146 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700147 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
148 sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700149 if (LIKELY(field != nullptr)) {
150 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000151 ThrowNullPointerExceptionForFieldAccess(field, true);
Fred Shih37f05ef2014-07-16 18:38:08 -0700152 } else {
153 return field->GetByte(obj);
154 }
155 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700156 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700157}
158
159extern "C" uint8_t artGetBooleanInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700160 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700161 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700162 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700163 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700164 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700165 return field->GetBoolean(obj);
166 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700167 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
168 sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700169 if (LIKELY(field != nullptr)) {
170 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000171 ThrowNullPointerExceptionForFieldAccess(field, true);
Fred Shih37f05ef2014-07-16 18:38:08 -0700172 } else {
173 return field->GetBoolean(obj);
174 }
175 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700176 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700177}
178extern "C" int16_t artGetShortInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700179 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700180 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700181 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700182 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700183 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700184 return field->GetShort(obj);
185 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700186 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
187 sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700188 if (LIKELY(field != nullptr)) {
189 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000190 ThrowNullPointerExceptionForFieldAccess(field, true);
Fred Shih37f05ef2014-07-16 18:38:08 -0700191 } else {
192 return field->GetShort(obj);
193 }
194 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700195 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700196}
197
198extern "C" uint16_t artGetCharInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700199 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700200 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700201 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700202 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700203 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700204 return field->GetChar(obj);
205 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700206 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
207 sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700208 if (LIKELY(field != nullptr)) {
209 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000210 ThrowNullPointerExceptionForFieldAccess(field, true);
Fred Shih37f05ef2014-07-16 18:38:08 -0700211 } else {
212 return field->GetChar(obj);
213 }
214 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700215 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700216}
217
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800218extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700219 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700220 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700221 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700222 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700223 if (LIKELY(field != nullptr && obj != nullptr)) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700224 return field->Get32(obj);
225 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200226 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
227 sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700228 if (LIKELY(field != nullptr)) {
229 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000230 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700231 } else {
232 return field->Get32(obj);
233 }
234 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700235 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700236}
237
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800238extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700239 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700240 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700241 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700242 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700243 if (LIKELY(field != nullptr && obj != nullptr)) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700244 return field->Get64(obj);
245 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200246 field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, self,
247 sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700248 if (LIKELY(field != nullptr)) {
249 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000250 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700251 } else {
252 return field->Get64(obj);
253 }
254 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700255 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700256}
257
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800258extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700259 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700260 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700261 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700262 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700263 ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
264 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700265 if (LIKELY(field != nullptr && obj != nullptr)) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700266 return field->GetObj(obj);
267 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700268 field = FindFieldFromCode<InstanceObjectRead, true>(
269 field_idx, referrer, self, sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700270 if (LIKELY(field != nullptr)) {
271 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000272 ThrowNullPointerExceptionForFieldAccess(field, true);
Ian Rogers57b86d42012-03-27 16:05:41 -0700273 } else {
274 return field->GetObj(obj);
275 }
276 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700277 return nullptr; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700278}
279
Fred Shih37f05ef2014-07-16 18:38:08 -0700280extern "C" int artSet8StaticFromCode(uint32_t field_idx, uint32_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700281 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700282 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700283 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700284 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700285 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700286 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 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700296 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700297 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700298 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
311extern "C" int artSet16StaticFromCode(uint32_t field_idx, uint16_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700312 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700313 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700314 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700315 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700316 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700317 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 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700327 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700328 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700329 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
Ian Rogers57b86d42012-03-27 16:05:41 -0700342extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700343 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700344 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700345 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700346 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700347 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100348 // Compiled code can't use transactional mode.
349 field->Set32<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700350 return 0; // success
351 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200352 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700353 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100354 // Compiled code can't use transactional mode.
355 field->Set32<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700356 return 0; // success
357 }
358 return -1; // failure
359}
360
Mathieu Chartiere401d142015-04-22 13:56:20 -0700361extern "C" int artSet64StaticFromCode(uint32_t field_idx, ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700362 uint64_t new_value, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700363 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700364 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700365 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700366 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100367 // Compiled code can't use transactional mode.
368 field->Set64<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700369 return 0; // success
370 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200371 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700372 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100373 // Compiled code can't use transactional mode.
374 field->Set64<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700375 return 0; // success
376 }
377 return -1; // failure
378}
379
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800380extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700381 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700382 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700383 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700384 ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
385 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700386 if (LIKELY(field != nullptr)) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700387 if (LIKELY(!field->IsPrimitiveType())) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100388 // Compiled code can't use transactional mode.
389 field->SetObj<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700390 return 0; // success
391 }
392 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200393 field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, self,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800394 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700395 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100396 // Compiled code can't use transactional mode.
397 field->SetObj<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700398 return 0; // success
399 }
400 return -1; // failure
401}
402
Fred Shih37f05ef2014-07-16 18:38:08 -0700403extern "C" int artSet8InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint8_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700404 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700405 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700406 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700407 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700408 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700409 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 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700419 {
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 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700425 if (LIKELY(field != nullptr)) {
426 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000427 ThrowNullPointerExceptionForFieldAccess(field, false);
Fred Shih37f05ef2014-07-16 18:38:08 -0700428 } 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
442extern "C" int artSet16InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint16_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700443 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700444 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700445 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700446 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700447 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700448 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 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700458 {
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 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700464 if (LIKELY(field != nullptr)) {
465 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000466 ThrowNullPointerExceptionForFieldAccess(field, false);
Fred Shih37f05ef2014-07-16 18:38:08 -0700467 } 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
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800482extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700483 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700484 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700485 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700486 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700487 if (LIKELY(field != nullptr && obj != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100488 // Compiled code can't use transactional mode.
489 field->Set32<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700490 return 0; // success
491 }
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700492 {
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 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700498 if (LIKELY(field != nullptr)) {
499 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000500 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700501 } else {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100502 // Compiled code can't use transactional mode.
503 field->Set32<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700504 return 0; // success
505 }
506 }
507 return -1; // failure
508}
509
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800510extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700511 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700512 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700513 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700514 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700515 if (LIKELY(field != nullptr && obj != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100516 // Compiled code can't use transactional mode.
517 field->Set64<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700518 return 0; // success
519 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200520 field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, self,
521 sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700522 if (LIKELY(field != nullptr)) {
523 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000524 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700525 } else {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100526 // Compiled code can't use transactional mode.
527 field->Set64<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700528 return 0; // success
529 }
530 }
531 return -1; // failure
532}
533
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800534extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
535 mirror::Object* new_value,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700536 ArtMethod* referrer, Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700537 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700538 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700539 ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
540 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700541 if (LIKELY(field != nullptr && obj != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100542 // Compiled code can't use transactional mode.
543 field->SetObj<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700544 return 0; // success
545 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200546 field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, self,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800547 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700548 if (LIKELY(field != nullptr)) {
549 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000550 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700551 } else {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100552 // Compiled code can't use transactional mode.
553 field->SetObj<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700554 return 0; // success
555 }
556 }
557 return -1; // failure
558}
559
Man Cao1aee9002015-07-14 22:31:42 -0700560// TODO: Currently the read barrier does not have a fast path. Ideally the slow path should only
Man Cao63069212015-08-21 15:51:39 -0700561// take one parameter "ref", which is given by the fast path.
Man Cao1aee9002015-07-14 22:31:42 -0700562extern "C" mirror::Object* artReadBarrierSlow(mirror::Object* ref ATTRIBUTE_UNUSED,
563 mirror::Object* obj, uint32_t offset) {
564 DCHECK(kUseReadBarrier);
565 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(obj) + offset;
566 mirror::HeapReference<mirror::Object>* ref_addr =
567 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
568 return ReadBarrier::Barrier<mirror::Object, kWithReadBarrier, true>(obj, MemberOffset(offset),
569 ref_addr);
570}
571
Ian Rogers57b86d42012-03-27 16:05:41 -0700572} // namespace art