blob: bb90667381123f7ddde98dd7d193dc1adea03b32 [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
Roland Levillain0d5a2812015-11-13 10:07:31 +000017#include <stdint.h>
18
Mathieu Chartierc7853442015-03-27 14:35:38 -070019#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070020#include "art_method-inl.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070021#include "callee_save_frame.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070022#include "dex_file-inl.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070023#include "entrypoints/entrypoint_utils-inl.h"
Roland Levillain0d5a2812015-11-13 10:07:31 +000024#include "gc_root-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "mirror/class-inl.h"
Roland Levillain0d5a2812015-11-13 10:07:31 +000026#include "mirror/object_reference.h"
Ian Rogers57b86d42012-03-27 16:05:41 -070027
28namespace art {
29
Mathieu Chartierbf369182016-02-04 18:13:32 -080030template<FindFieldType type, bool kAccessCheck>
31ALWAYS_INLINE static inline ArtField* FindInstanceField(uint32_t field_idx,
32 ArtMethod* referrer,
33 Thread* self,
34 size_t size,
35 mirror::Object** obj)
36 REQUIRES(!Roles::uninterruptible_)
37 SHARED_REQUIRES(Locks::mutator_lock_) {
38 StackHandleScope<1> hs(self);
39 HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj));
40 ArtField* field = FindFieldFromCode<type, kAccessCheck>(field_idx, referrer, self, size);
41 if (LIKELY(field != nullptr) && UNLIKELY(h.Get() == nullptr)) {
42 ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/FindFieldTypeIsRead(type));
43 return nullptr;
44 }
45 return field;
46}
47
48extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx,
49 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070050 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070051 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070052 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070053 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070054 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070055 return field->GetByte(field->GetDeclaringClass());
56 }
Fred Shih37f05ef2014-07-16 18:38:08 -070057 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070058 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070059 return field->GetByte(field->GetDeclaringClass());
60 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070061 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070062}
63
Mathieu Chartierbf369182016-02-04 18:13:32 -080064extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx,
65 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070066 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070067 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070068 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070069 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070070 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070071 return field->GetBoolean(field->GetDeclaringClass());
72 }
Fred Shih37f05ef2014-07-16 18:38:08 -070073 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070074 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070075 return field->GetBoolean(field->GetDeclaringClass());
76 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070077 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070078}
79
Mathieu Chartierbf369182016-02-04 18:13:32 -080080extern "C" int16_t artGetShortStaticFromCode(uint32_t field_idx,
81 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070082 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070083 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070084 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -070085 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070086 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070087 return field->GetShort(field->GetDeclaringClass());
88 }
Fred Shih37f05ef2014-07-16 18:38:08 -070089 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070090 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -070091 return field->GetShort(field->GetDeclaringClass());
92 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070093 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -070094}
95
96extern "C" uint16_t artGetCharStaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -070097 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -070098 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -070099 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700100 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700101 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700102 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700103 return field->GetChar(field->GetDeclaringClass());
104 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700105 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700106 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700107 return field->GetChar(field->GetDeclaringClass());
108 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700109 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700110}
111
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800112extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700113 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700114 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700115 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700116 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700117 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700118 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700119 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700120 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200121 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700122 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700123 return field->Get32(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700124 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700125 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700126}
127
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700129 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700130 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700131 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700132 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700133 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700134 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700135 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700136 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200137 field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, self, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700138 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700139 return field->Get64(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700140 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700141 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700142}
143
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800144extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700145 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700146 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700147 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700148 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierbf369182016-02-04 18:13:32 -0800149 ArtField* field = FindFieldFast(field_idx,
150 referrer,
151 StaticObjectRead,
Mathieu Chartierc7853442015-03-27 14:35:38 -0700152 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700153 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700154 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700155 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800156 field = FindFieldFromCode<StaticObjectRead, true>(field_idx,
157 referrer,
158 self,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800159 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700160 if (LIKELY(field != nullptr)) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700161 return field->GetObj(field->GetDeclaringClass());
Ian Rogers57b86d42012-03-27 16:05:41 -0700162 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700163 return nullptr; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700164}
165
Mathieu Chartierbf369182016-02-04 18:13:32 -0800166extern "C" int8_t artGetByteInstanceFromCode(uint32_t field_idx,
167 mirror::Object* obj,
168 ArtMethod* referrer,
169 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700170 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700171 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700172 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700173 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700174 return field->GetByte(obj);
175 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800176 field = FindInstanceField<InstancePrimitiveRead, true>(field_idx,
177 referrer,
178 self,
179 sizeof(int8_t),
180 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700181 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800182 return field->GetByte(obj);
Fred Shih37f05ef2014-07-16 18:38:08 -0700183 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700184 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700185}
186
Mathieu Chartierbf369182016-02-04 18:13:32 -0800187extern "C" uint8_t artGetBooleanInstanceFromCode(uint32_t field_idx,
188 mirror::Object* obj,
189 ArtMethod* referrer,
190 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700191 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700192 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700193 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700194 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700195 return field->GetBoolean(obj);
196 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800197 field = FindInstanceField<InstancePrimitiveRead, true>(field_idx,
198 referrer,
199 self,
200 sizeof(int8_t),
201 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700202 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800203 return field->GetBoolean(obj);
Fred Shih37f05ef2014-07-16 18:38:08 -0700204 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700205 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700206}
Mathieu Chartierbf369182016-02-04 18:13:32 -0800207extern "C" int16_t artGetShortInstanceFromCode(uint32_t field_idx,
208 mirror::Object* obj,
209 ArtMethod* referrer,
210 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700211 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700212 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700213 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700214 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700215 return field->GetShort(obj);
216 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800217 field = FindInstanceField<InstancePrimitiveRead, true>(field_idx,
218 referrer,
219 self,
220 sizeof(int16_t),
221 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700222 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800223 return field->GetShort(obj);
Fred Shih37f05ef2014-07-16 18:38:08 -0700224 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700225 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700226}
227
Mathieu Chartierbf369182016-02-04 18:13:32 -0800228extern "C" uint16_t artGetCharInstanceFromCode(uint32_t field_idx,
229 mirror::Object* obj,
230 ArtMethod* referrer,
231 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700232 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700233 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700234 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700235 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700236 return field->GetChar(obj);
237 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800238 field = FindInstanceField<InstancePrimitiveRead, true>(field_idx,
239 referrer,
240 self,
241 sizeof(int16_t),
242 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700243 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800244 return field->GetChar(obj);
Fred Shih37f05ef2014-07-16 18:38:08 -0700245 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700246 return 0; // Will throw exception by checking with Thread::Current.
Fred Shih37f05ef2014-07-16 18:38:08 -0700247}
248
Mathieu Chartierbf369182016-02-04 18:13:32 -0800249extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx,
250 mirror::Object* obj,
251 ArtMethod* referrer,
252 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700253 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700254 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700255 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700256 if (LIKELY(field != nullptr && obj != nullptr)) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700257 return field->Get32(obj);
258 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800259 field = FindInstanceField<InstancePrimitiveRead, true>(field_idx,
260 referrer,
261 self,
262 sizeof(int32_t),
263 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700264 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800265 return field->Get32(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700266 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700267 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700268}
269
Mathieu Chartierbf369182016-02-04 18:13:32 -0800270extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx,
271 mirror::Object* obj,
272 ArtMethod* referrer,
273 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700274 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700275 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700276 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700277 if (LIKELY(field != nullptr && obj != nullptr)) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700278 return field->Get64(obj);
279 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800280 field = FindInstanceField<InstancePrimitiveRead, true>(field_idx,
281 referrer,
282 self,
283 sizeof(int64_t),
284 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700285 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800286 return field->Get64(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700287 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700288 return 0; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700289}
290
Mathieu Chartierbf369182016-02-04 18:13:32 -0800291extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx,
292 mirror::Object* obj,
Mathieu Chartiere401d142015-04-22 13:56:20 -0700293 ArtMethod* referrer,
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700294 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700295 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700296 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierbf369182016-02-04 18:13:32 -0800297 ArtField* field = FindFieldFast(field_idx,
298 referrer,
299 InstanceObjectRead,
Mathieu Chartierc7853442015-03-27 14:35:38 -0700300 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700301 if (LIKELY(field != nullptr && obj != nullptr)) {
Ian Rogers57b86d42012-03-27 16:05:41 -0700302 return field->GetObj(obj);
303 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800304 field = FindInstanceField<InstanceObjectRead, true>(field_idx,
305 referrer,
306 self,
307 sizeof(mirror::HeapReference<mirror::Object>),
308 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700309 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800310 return field->GetObj(obj);
Ian Rogers57b86d42012-03-27 16:05:41 -0700311 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700312 return nullptr; // Will throw exception by checking with Thread::Current.
Ian Rogers57b86d42012-03-27 16:05:41 -0700313}
314
Mathieu Chartierbf369182016-02-04 18:13:32 -0800315extern "C" int artSet8StaticFromCode(uint32_t field_idx,
316 uint32_t new_value,
317 ArtMethod* referrer,
318 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700319 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700320 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700321 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700322 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700323 Primitive::Type type = field->GetTypeAsPrimitiveType();
324 // Compiled code can't use transactional mode.
325 if (type == Primitive::kPrimBoolean) {
326 field->SetBoolean<false>(field->GetDeclaringClass(), new_value);
327 } else {
328 DCHECK_EQ(Primitive::kPrimByte, type);
329 field->SetByte<false>(field->GetDeclaringClass(), new_value);
330 }
331 return 0; // success
332 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700333 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700334 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700335 Primitive::Type type = field->GetTypeAsPrimitiveType();
336 // Compiled code can't use transactional mode.
337 if (type == Primitive::kPrimBoolean) {
338 field->SetBoolean<false>(field->GetDeclaringClass(), new_value);
339 } else {
340 DCHECK_EQ(Primitive::kPrimByte, type);
341 field->SetByte<false>(field->GetDeclaringClass(), new_value);
342 }
343 return 0; // success
344 }
345 return -1; // failure
346}
347
Mathieu Chartierbf369182016-02-04 18:13:32 -0800348extern "C" int artSet16StaticFromCode(uint32_t field_idx,
349 uint16_t new_value,
350 ArtMethod* referrer,
351 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700352 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700353 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700354 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700355 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700356 Primitive::Type type = field->GetTypeAsPrimitiveType();
357 // Compiled code can't use transactional mode.
358 if (type == Primitive::kPrimChar) {
359 field->SetChar<false>(field->GetDeclaringClass(), new_value);
360 } else {
361 DCHECK_EQ(Primitive::kPrimShort, type);
362 field->SetShort<false>(field->GetDeclaringClass(), new_value);
363 }
364 return 0; // success
365 }
Fred Shih37f05ef2014-07-16 18:38:08 -0700366 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700367 if (LIKELY(field != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700368 Primitive::Type type = field->GetTypeAsPrimitiveType();
369 // Compiled code can't use transactional mode.
370 if (type == Primitive::kPrimChar) {
371 field->SetChar<false>(field->GetDeclaringClass(), new_value);
372 } else {
373 DCHECK_EQ(Primitive::kPrimShort, type);
374 field->SetShort<false>(field->GetDeclaringClass(), new_value);
375 }
376 return 0; // success
377 }
378 return -1; // failure
379}
380
Mathieu Chartierbf369182016-02-04 18:13:32 -0800381extern "C" int artSet32StaticFromCode(uint32_t field_idx,
382 uint32_t new_value,
383 ArtMethod* referrer,
384 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700385 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700386 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700387 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700388 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100389 // Compiled code can't use transactional mode.
390 field->Set32<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700391 return 0; // success
392 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200393 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700394 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100395 // Compiled code can't use transactional mode.
396 field->Set32<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700397 return 0; // success
398 }
399 return -1; // failure
400}
401
Mathieu Chartierbf369182016-02-04 18:13:32 -0800402extern "C" int artSet64StaticFromCode(uint32_t field_idx,
403 ArtMethod* referrer,
404 uint64_t new_value,
405 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700406 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700407 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700408 ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700409 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100410 // Compiled code can't use transactional mode.
411 field->Set64<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700412 return 0; // success
413 }
Sebastien Hertzd4beb6b2013-10-02 17:07:20 +0200414 field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, self, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700415 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100416 // Compiled code can't use transactional mode.
417 field->Set64<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700418 return 0; // success
419 }
420 return -1; // failure
421}
422
Mathieu Chartierbf369182016-02-04 18:13:32 -0800423extern "C" int artSetObjStaticFromCode(uint32_t field_idx,
424 mirror::Object* new_value,
425 ArtMethod* referrer,
426 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700427 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700428 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierbf369182016-02-04 18:13:32 -0800429 ArtField* field = FindFieldFast(field_idx,
430 referrer,
431 StaticObjectWrite,
Mathieu Chartierc7853442015-03-27 14:35:38 -0700432 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700433 if (LIKELY(field != nullptr)) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700434 if (LIKELY(!field->IsPrimitiveType())) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100435 // Compiled code can't use transactional mode.
436 field->SetObj<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700437 return 0; // success
438 }
439 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800440 {
441 StackHandleScope<1> hs(self);
442 HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&new_value));
443 field = FindFieldFromCode<StaticObjectWrite, true>(
444 field_idx,
445 referrer,
446 self,
447 sizeof(mirror::HeapReference<mirror::Object>));
448 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700449 if (LIKELY(field != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100450 // Compiled code can't use transactional mode.
451 field->SetObj<false>(field->GetDeclaringClass(), new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700452 return 0; // success
453 }
454 return -1; // failure
455}
456
Mathieu Chartierbf369182016-02-04 18:13:32 -0800457extern "C" int artSet8InstanceFromCode(uint32_t field_idx,
458 mirror::Object* obj,
459 uint8_t new_value,
460 ArtMethod* referrer,
461 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700462 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700463 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700464 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700465 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700466 Primitive::Type type = field->GetTypeAsPrimitiveType();
467 // Compiled code can't use transactional mode.
468 if (type == Primitive::kPrimBoolean) {
469 field->SetBoolean<false>(obj, new_value);
470 } else {
471 DCHECK_EQ(Primitive::kPrimByte, type);
472 field->SetByte<false>(obj, new_value);
473 }
474 return 0; // success
475 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800476 field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx,
477 referrer,
478 self,
479 sizeof(int8_t),
480 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700481 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800482 Primitive::Type type = field->GetTypeAsPrimitiveType();
483 // Compiled code can't use transactional mode.
484 if (type == Primitive::kPrimBoolean) {
485 field->SetBoolean<false>(obj, new_value);
Fred Shih37f05ef2014-07-16 18:38:08 -0700486 } else {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800487 field->SetByte<false>(obj, new_value);
Fred Shih37f05ef2014-07-16 18:38:08 -0700488 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800489 return 0; // success
Fred Shih37f05ef2014-07-16 18:38:08 -0700490 }
491 return -1; // failure
492}
493
Mathieu Chartierbf369182016-02-04 18:13:32 -0800494extern "C" int artSet16InstanceFromCode(uint32_t field_idx,
495 mirror::Object* obj,
496 uint16_t new_value,
497 ArtMethod* referrer,
498 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700499 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700500 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700501 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int16_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700502 if (LIKELY(field != nullptr && obj != nullptr)) {
Fred Shih37f05ef2014-07-16 18:38:08 -0700503 Primitive::Type type = field->GetTypeAsPrimitiveType();
504 // Compiled code can't use transactional mode.
505 if (type == Primitive::kPrimChar) {
506 field->SetChar<false>(obj, new_value);
507 } else {
508 DCHECK_EQ(Primitive::kPrimShort, type);
509 field->SetShort<false>(obj, new_value);
510 }
511 return 0; // success
512 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800513 field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx,
514 referrer,
515 self,
516 sizeof(int16_t),
517 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700518 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800519 Primitive::Type type = field->GetTypeAsPrimitiveType();
520 // Compiled code can't use transactional mode.
521 if (type == Primitive::kPrimChar) {
522 field->SetChar<false>(obj, new_value);
Fred Shih37f05ef2014-07-16 18:38:08 -0700523 } else {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800524 DCHECK_EQ(Primitive::kPrimShort, type);
525 field->SetShort<false>(obj, new_value);
Fred Shih37f05ef2014-07-16 18:38:08 -0700526 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800527 return 0; // success
Fred Shih37f05ef2014-07-16 18:38:08 -0700528 }
529 return -1; // failure
530}
531
Mathieu Chartierbf369182016-02-04 18:13:32 -0800532extern "C" int artSet32InstanceFromCode(uint32_t field_idx,
533 mirror::Object* obj,
534 uint32_t new_value,
535 ArtMethod* referrer,
536 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, InstancePrimitiveWrite, sizeof(int32_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700540 if (LIKELY(field != nullptr && obj != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100541 // Compiled code can't use transactional mode.
542 field->Set32<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700543 return 0; // success
544 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800545 field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx,
546 referrer,
547 self,
548 sizeof(int32_t),
549 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700550 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800551 // Compiled code can't use transactional mode.
552 field->Set32<false>(obj, new_value);
553 return 0; // success
Ian Rogers57b86d42012-03-27 16:05:41 -0700554 }
555 return -1; // failure
556}
557
Mathieu Chartierbf369182016-02-04 18:13:32 -0800558extern "C" int artSet64InstanceFromCode(uint32_t field_idx,
559 mirror::Object* obj,
560 uint64_t new_value,
561 ArtMethod* referrer,
562 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700563 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700564 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700565 ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700566 if (LIKELY(field != nullptr && obj != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100567 // Compiled code can't use transactional mode.
568 field->Set64<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700569 return 0; // success
570 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800571 field = FindInstanceField<InstancePrimitiveWrite, true>(field_idx,
572 referrer,
573 self,
574 sizeof(int64_t),
575 &obj);
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700576 if (LIKELY(field != nullptr)) {
Mathieu Chartierbf369182016-02-04 18:13:32 -0800577 // Compiled code can't use transactional mode.
578 field->Set64<false>(obj, new_value);
579 return 0;
Ian Rogers57b86d42012-03-27 16:05:41 -0700580 }
581 return -1; // failure
582}
583
Mathieu Chartierbf369182016-02-04 18:13:32 -0800584extern "C" int artSetObjInstanceFromCode(uint32_t field_idx,
585 mirror::Object* obj,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800586 mirror::Object* new_value,
Mathieu Chartierbf369182016-02-04 18:13:32 -0800587 ArtMethod* referrer,
588 Thread* self)
Mathieu Chartier90443472015-07-16 20:32:27 -0700589 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700590 ScopedQuickEntrypointChecks sqec(self);
Mathieu Chartierbf369182016-02-04 18:13:32 -0800591 ArtField* field = FindFieldFast(field_idx,
592 referrer,
593 InstanceObjectWrite,
Mathieu Chartierc7853442015-03-27 14:35:38 -0700594 sizeof(mirror::HeapReference<mirror::Object>));
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700595 if (LIKELY(field != nullptr && obj != nullptr)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100596 // Compiled code can't use transactional mode.
597 field->SetObj<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700598 return 0; // success
599 }
Mathieu Chartierbf369182016-02-04 18:13:32 -0800600 {
601 StackHandleScope<2> hs(self);
602 HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
603 HandleWrapper<mirror::Object> h_new_value(hs.NewHandleWrapper(&new_value));
604 field = FindFieldFromCode<InstanceObjectWrite, true>(
605 field_idx,
606 referrer,
607 self,
608 sizeof(mirror::HeapReference<mirror::Object>));
609 }
Ian Rogers1d8cdbc2014-09-22 22:51:09 -0700610 if (LIKELY(field != nullptr)) {
611 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000612 ThrowNullPointerExceptionForFieldAccess(field, false);
Ian Rogers57b86d42012-03-27 16:05:41 -0700613 } else {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100614 // Compiled code can't use transactional mode.
615 field->SetObj<false>(obj, new_value);
Ian Rogers57b86d42012-03-27 16:05:41 -0700616 return 0; // success
617 }
618 }
619 return -1; // failure
620}
621
Roland Levillain7c1559a2015-12-15 10:55:36 +0000622extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj) {
623 DCHECK(kEmitCompilerReadBarrier);
624 return ReadBarrier::Mark(obj);
625}
626
Man Cao1aee9002015-07-14 22:31:42 -0700627extern "C" mirror::Object* artReadBarrierSlow(mirror::Object* ref ATTRIBUTE_UNUSED,
Roland Levillain0d5a2812015-11-13 10:07:31 +0000628 mirror::Object* obj,
629 uint32_t offset) {
630 DCHECK(kEmitCompilerReadBarrier);
Man Cao1aee9002015-07-14 22:31:42 -0700631 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(obj) + offset;
632 mirror::HeapReference<mirror::Object>* ref_addr =
Roland Levillain0d5a2812015-11-13 10:07:31 +0000633 reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
634 constexpr ReadBarrierOption kReadBarrierOption =
635 kUseReadBarrier ? kWithReadBarrier : kWithoutReadBarrier;
636 mirror::Object* result =
Hiroshi Yamauchicc78f3f2015-12-11 15:51:04 -0800637 ReadBarrier::Barrier<mirror::Object, kReadBarrierOption>(obj,
638 MemberOffset(offset),
639 ref_addr);
Roland Levillain0d5a2812015-11-13 10:07:31 +0000640 return result;
641}
642
643extern "C" mirror::Object* artReadBarrierForRootSlow(GcRoot<mirror::Object>* root) {
644 DCHECK(kEmitCompilerReadBarrier);
Roland Levillain0d5a2812015-11-13 10:07:31 +0000645 return root->Read();
Man Cao1aee9002015-07-14 22:31:42 -0700646}
647
Ian Rogers57b86d42012-03-27 16:05:41 -0700648} // namespace art