1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
21*795d594fSAndroid Build Coastguard Worker #include "art_field.h"
22*795d594fSAndroid Build Coastguard Worker #include "art_method.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
25*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
26*795d594fSAndroid Build Coastguard Worker #include "dex/code_item_accessors.h"
27*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_structs.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex/primitive.h"
29*795d594fSAndroid Build Coastguard Worker #include "entrypoints/entrypoint_utils.h"
30*795d594fSAndroid Build Coastguard Worker #include "handle_scope-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "instrumentation.h"
32*795d594fSAndroid Build Coastguard Worker #include "interpreter/interpreter.h"
33*795d594fSAndroid Build Coastguard Worker #include "interpreter/shadow_frame.h"
34*795d594fSAndroid Build Coastguard Worker #include "interpreter/unstarted_runtime.h"
35*795d594fSAndroid Build Coastguard Worker #include "jvalue-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "mirror/class.h"
37*795d594fSAndroid Build Coastguard Worker #include "mirror/object.h"
38*795d594fSAndroid Build Coastguard Worker #include "obj_ptr-inl.h"
39*795d594fSAndroid Build Coastguard Worker #include "reflective_handle.h"
40*795d594fSAndroid Build Coastguard Worker #include "reflective_handle_scope.h"
41*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
42*795d594fSAndroid Build Coastguard Worker #include "stack.h"
43*795d594fSAndroid Build Coastguard Worker #include "thread.h"
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker namespace interpreter {
48*795d594fSAndroid Build Coastguard Worker void ArtInterpreterToInterpreterBridge(Thread* self,
49*795d594fSAndroid Build Coastguard Worker const dex::CodeItem* code_item,
50*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
51*795d594fSAndroid Build Coastguard Worker JValue* result)
52*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker void ArtInterpreterToCompiledCodeBridge(Thread* self,
55*795d594fSAndroid Build Coastguard Worker ArtMethod* caller,
56*795d594fSAndroid Build Coastguard Worker ShadowFrame* shadow_frame,
57*795d594fSAndroid Build Coastguard Worker uint16_t arg_offset,
58*795d594fSAndroid Build Coastguard Worker JValue* result);
59*795d594fSAndroid Build Coastguard Worker
60*795d594fSAndroid Build Coastguard Worker } // namespace interpreter
61*795d594fSAndroid Build Coastguard Worker
EnsureInitialized(Thread * self,ShadowFrame * shadow_frame)62*795d594fSAndroid Build Coastguard Worker inline bool EnsureInitialized(Thread* self, ShadowFrame* shadow_frame)
63*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
64*795d594fSAndroid Build Coastguard Worker if (LIKELY(!shadow_frame->GetMethod()->StillNeedsClinitCheck())) {
65*795d594fSAndroid Build Coastguard Worker return true;
66*795d594fSAndroid Build Coastguard Worker }
67*795d594fSAndroid Build Coastguard Worker
68*795d594fSAndroid Build Coastguard Worker // Save the shadow frame.
69*795d594fSAndroid Build Coastguard Worker ScopedStackedShadowFramePusher pusher(self, shadow_frame);
70*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
71*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> h_class = hs.NewHandle(shadow_frame->GetMethod()->GetDeclaringClass());
72*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
73*795d594fSAndroid Build Coastguard Worker self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
74*795d594fSAndroid Build Coastguard Worker DCHECK(self->IsExceptionPending());
75*795d594fSAndroid Build Coastguard Worker return false;
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker DCHECK(h_class->IsInitializing());
78*795d594fSAndroid Build Coastguard Worker return true;
79*795d594fSAndroid Build Coastguard Worker }
80*795d594fSAndroid Build Coastguard Worker
PerformCall(Thread * self,const CodeItemDataAccessor & accessor,ArtMethod * caller_method,const size_t first_dest_reg,ShadowFrame * callee_frame,JValue * result,bool use_interpreter_entrypoint)81*795d594fSAndroid Build Coastguard Worker inline void PerformCall(Thread* self,
82*795d594fSAndroid Build Coastguard Worker const CodeItemDataAccessor& accessor,
83*795d594fSAndroid Build Coastguard Worker ArtMethod* caller_method,
84*795d594fSAndroid Build Coastguard Worker const size_t first_dest_reg,
85*795d594fSAndroid Build Coastguard Worker ShadowFrame* callee_frame,
86*795d594fSAndroid Build Coastguard Worker JValue* result,
87*795d594fSAndroid Build Coastguard Worker bool use_interpreter_entrypoint)
88*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
89*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!Runtime::Current()->IsStarted())) {
90*795d594fSAndroid Build Coastguard Worker interpreter::UnstartedRuntime::Invoke(self, accessor, callee_frame, result, first_dest_reg);
91*795d594fSAndroid Build Coastguard Worker return;
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker
94*795d594fSAndroid Build Coastguard Worker if (!EnsureInitialized(self, callee_frame)) {
95*795d594fSAndroid Build Coastguard Worker return;
96*795d594fSAndroid Build Coastguard Worker }
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker if (use_interpreter_entrypoint) {
99*795d594fSAndroid Build Coastguard Worker interpreter::ArtInterpreterToInterpreterBridge(self, accessor, callee_frame, result);
100*795d594fSAndroid Build Coastguard Worker } else {
101*795d594fSAndroid Build Coastguard Worker interpreter::ArtInterpreterToCompiledCodeBridge(
102*795d594fSAndroid Build Coastguard Worker self, caller_method, callee_frame, first_dest_reg, result);
103*795d594fSAndroid Build Coastguard Worker }
104*795d594fSAndroid Build Coastguard Worker }
105*795d594fSAndroid Build Coastguard Worker
106*795d594fSAndroid Build Coastguard Worker template <typename T>
DCheckStaticState(Thread * self,T * entity)107*795d594fSAndroid Build Coastguard Worker inline void DCheckStaticState(Thread* self, T* entity) REQUIRES_SHARED(Locks::mutator_lock_) {
108*795d594fSAndroid Build Coastguard Worker if (kIsDebugBuild) {
109*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> klass = entity->GetDeclaringClass();
110*795d594fSAndroid Build Coastguard Worker if (entity->IsStatic()) {
111*795d594fSAndroid Build Coastguard Worker klass->AssertInitializedOrInitializingInThread(self);
112*795d594fSAndroid Build Coastguard Worker } else {
113*795d594fSAndroid Build Coastguard Worker CHECK(klass->IsInitializing() || klass->IsErroneousResolved());
114*795d594fSAndroid Build Coastguard Worker }
115*795d594fSAndroid Build Coastguard Worker }
116*795d594fSAndroid Build Coastguard Worker }
117*795d594fSAndroid Build Coastguard Worker
118*795d594fSAndroid Build Coastguard Worker template<Primitive::Type field_type>
DoFieldGetCommon(Thread * self,const ShadowFrame & shadow_frame,ObjPtr<mirror::Object> obj,ArtField * field,JValue * result)119*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self,
120*795d594fSAndroid Build Coastguard Worker const ShadowFrame& shadow_frame,
121*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj,
122*795d594fSAndroid Build Coastguard Worker ArtField* field,
123*795d594fSAndroid Build Coastguard Worker JValue* result)
124*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
125*795d594fSAndroid Build Coastguard Worker DCheckStaticState(self, field);
126*795d594fSAndroid Build Coastguard Worker
127*795d594fSAndroid Build Coastguard Worker // Report this field access to instrumentation if needed.
128*795d594fSAndroid Build Coastguard Worker instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
129*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
130*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(self);
131*795d594fSAndroid Build Coastguard Worker StackArtFieldHandleScope<1> rhs(self);
132*795d594fSAndroid Build Coastguard Worker // Wrap in handle wrapper in case the listener does thread suspension.
133*795d594fSAndroid Build Coastguard Worker HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
134*795d594fSAndroid Build Coastguard Worker ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
135*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object;
136*795d594fSAndroid Build Coastguard Worker if (!field->IsStatic()) {
137*795d594fSAndroid Build Coastguard Worker this_object = obj;
138*795d594fSAndroid Build Coastguard Worker }
139*795d594fSAndroid Build Coastguard Worker instrumentation->FieldReadEvent(self,
140*795d594fSAndroid Build Coastguard Worker this_object,
141*795d594fSAndroid Build Coastguard Worker shadow_frame.GetMethod(),
142*795d594fSAndroid Build Coastguard Worker shadow_frame.GetDexPC(),
143*795d594fSAndroid Build Coastguard Worker field);
144*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(self->IsExceptionPending())) {
145*795d594fSAndroid Build Coastguard Worker return false;
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker
149*795d594fSAndroid Build Coastguard Worker switch (field_type) {
150*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimBoolean:
151*795d594fSAndroid Build Coastguard Worker result->SetZ(field->GetBoolean(obj));
152*795d594fSAndroid Build Coastguard Worker break;
153*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimByte:
154*795d594fSAndroid Build Coastguard Worker result->SetB(field->GetByte(obj));
155*795d594fSAndroid Build Coastguard Worker break;
156*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimChar:
157*795d594fSAndroid Build Coastguard Worker result->SetC(field->GetChar(obj));
158*795d594fSAndroid Build Coastguard Worker break;
159*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimShort:
160*795d594fSAndroid Build Coastguard Worker result->SetS(field->GetShort(obj));
161*795d594fSAndroid Build Coastguard Worker break;
162*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimInt:
163*795d594fSAndroid Build Coastguard Worker result->SetI(field->GetInt(obj));
164*795d594fSAndroid Build Coastguard Worker break;
165*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimLong:
166*795d594fSAndroid Build Coastguard Worker result->SetJ(field->GetLong(obj));
167*795d594fSAndroid Build Coastguard Worker break;
168*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimNot:
169*795d594fSAndroid Build Coastguard Worker result->SetL(field->GetObject(obj));
170*795d594fSAndroid Build Coastguard Worker break;
171*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimVoid:
172*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable " << field_type;
173*795d594fSAndroid Build Coastguard Worker break;
174*795d594fSAndroid Build Coastguard Worker }
175*795d594fSAndroid Build Coastguard Worker return true;
176*795d594fSAndroid Build Coastguard Worker }
177*795d594fSAndroid Build Coastguard Worker
178*795d594fSAndroid Build Coastguard Worker template<Primitive::Type field_type, bool transaction_active>
DoFieldPutCommon(Thread * self,const ShadowFrame & shadow_frame,ObjPtr<mirror::Object> obj,ArtField * field,JValue & value)179*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool DoFieldPutCommon(Thread* self,
180*795d594fSAndroid Build Coastguard Worker const ShadowFrame& shadow_frame,
181*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj,
182*795d594fSAndroid Build Coastguard Worker ArtField* field,
183*795d594fSAndroid Build Coastguard Worker JValue& value)
184*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
185*795d594fSAndroid Build Coastguard Worker DCheckStaticState(self, field);
186*795d594fSAndroid Build Coastguard Worker
187*795d594fSAndroid Build Coastguard Worker // Report this field access to instrumentation if needed. Since we only have the offset of
188*795d594fSAndroid Build Coastguard Worker // the field from the base of the object, we need to look for it first.
189*795d594fSAndroid Build Coastguard Worker instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
190*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
191*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
192*795d594fSAndroid Build Coastguard Worker StackArtFieldHandleScope<1> rhs(self);
193*795d594fSAndroid Build Coastguard Worker // Save this and return value (if needed) in case the instrumentation causes a suspend.
194*795d594fSAndroid Build Coastguard Worker HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
195*795d594fSAndroid Build Coastguard Worker ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
196*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj;
197*795d594fSAndroid Build Coastguard Worker mirror::Object* fake_root = nullptr;
198*795d594fSAndroid Build Coastguard Worker HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
199*795d594fSAndroid Build Coastguard Worker field_type == Primitive::kPrimNot ? value.GetGCRoot() : &fake_root));
200*795d594fSAndroid Build Coastguard Worker instrumentation->FieldWriteEvent(self,
201*795d594fSAndroid Build Coastguard Worker this_object,
202*795d594fSAndroid Build Coastguard Worker shadow_frame.GetMethod(),
203*795d594fSAndroid Build Coastguard Worker shadow_frame.GetDexPC(),
204*795d594fSAndroid Build Coastguard Worker field,
205*795d594fSAndroid Build Coastguard Worker value);
206*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(self->IsExceptionPending())) {
207*795d594fSAndroid Build Coastguard Worker return false;
208*795d594fSAndroid Build Coastguard Worker }
209*795d594fSAndroid Build Coastguard Worker if (shadow_frame.GetForcePopFrame()) {
210*795d594fSAndroid Build Coastguard Worker // We need to check this here since we expect that the FieldWriteEvent happens before the
211*795d594fSAndroid Build Coastguard Worker // actual field write. If one pops the stack we should not modify the field. The next
212*795d594fSAndroid Build Coastguard Worker // instruction will force a pop. Return true.
213*795d594fSAndroid Build Coastguard Worker DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
214*795d594fSAndroid Build Coastguard Worker return true;
215*795d594fSAndroid Build Coastguard Worker }
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker
218*795d594fSAndroid Build Coastguard Worker switch (field_type) {
219*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimBoolean:
220*795d594fSAndroid Build Coastguard Worker field->SetBoolean<transaction_active>(obj, value.GetZ());
221*795d594fSAndroid Build Coastguard Worker break;
222*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimByte:
223*795d594fSAndroid Build Coastguard Worker field->SetByte<transaction_active>(obj, value.GetB());
224*795d594fSAndroid Build Coastguard Worker break;
225*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimChar:
226*795d594fSAndroid Build Coastguard Worker field->SetChar<transaction_active>(obj, value.GetC());
227*795d594fSAndroid Build Coastguard Worker break;
228*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimShort:
229*795d594fSAndroid Build Coastguard Worker field->SetShort<transaction_active>(obj, value.GetS());
230*795d594fSAndroid Build Coastguard Worker break;
231*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimInt:
232*795d594fSAndroid Build Coastguard Worker field->SetInt<transaction_active>(obj, value.GetI());
233*795d594fSAndroid Build Coastguard Worker break;
234*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimLong:
235*795d594fSAndroid Build Coastguard Worker field->SetLong<transaction_active>(obj, value.GetJ());
236*795d594fSAndroid Build Coastguard Worker break;
237*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimNot: {
238*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> reg = value.GetL();
239*795d594fSAndroid Build Coastguard Worker if (reg != nullptr && !shadow_frame.GetMethod()->SkipAccessChecks()) {
240*795d594fSAndroid Build Coastguard Worker // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the
241*795d594fSAndroid Build Coastguard Worker // object in the destructor.
242*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> field_class;
243*795d594fSAndroid Build Coastguard Worker {
244*795d594fSAndroid Build Coastguard Worker StackHandleScope<2> hs(self);
245*795d594fSAndroid Build Coastguard Worker StackArtFieldHandleScope<1> rhs(self);
246*795d594fSAndroid Build Coastguard Worker HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(®));
247*795d594fSAndroid Build Coastguard Worker HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
248*795d594fSAndroid Build Coastguard Worker ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
249*795d594fSAndroid Build Coastguard Worker field_class = field->ResolveType();
250*795d594fSAndroid Build Coastguard Worker }
251*795d594fSAndroid Build Coastguard Worker // ArtField::ResolveType() may fail as evidenced with a dexing bug (b/78788577).
252*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(field_class.IsNull())) {
253*795d594fSAndroid Build Coastguard Worker Thread::Current()->AssertPendingException();
254*795d594fSAndroid Build Coastguard Worker return false;
255*795d594fSAndroid Build Coastguard Worker }
256*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!reg->VerifierInstanceOf(field_class))) {
257*795d594fSAndroid Build Coastguard Worker // This should never happen.
258*795d594fSAndroid Build Coastguard Worker std::string temp1, temp2;
259*795d594fSAndroid Build Coastguard Worker self->ThrowNewExceptionF("Ljava/lang/InternalError;",
260*795d594fSAndroid Build Coastguard Worker "Put '%s' that is not instance of field '%s' in '%s'",
261*795d594fSAndroid Build Coastguard Worker reg->GetClass()->GetDescriptor(&temp1),
262*795d594fSAndroid Build Coastguard Worker field_class->GetDescriptor(&temp2),
263*795d594fSAndroid Build Coastguard Worker field->GetDeclaringClassDescriptor());
264*795d594fSAndroid Build Coastguard Worker return false;
265*795d594fSAndroid Build Coastguard Worker }
266*795d594fSAndroid Build Coastguard Worker }
267*795d594fSAndroid Build Coastguard Worker field->SetObj<transaction_active>(obj, reg);
268*795d594fSAndroid Build Coastguard Worker break;
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimVoid: {
271*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable " << field_type;
272*795d594fSAndroid Build Coastguard Worker break;
273*795d594fSAndroid Build Coastguard Worker }
274*795d594fSAndroid Build Coastguard Worker }
275*795d594fSAndroid Build Coastguard Worker if (transaction_active) {
276*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(self->IsExceptionPending())) {
277*795d594fSAndroid Build Coastguard Worker return false;
278*795d594fSAndroid Build Coastguard Worker }
279*795d594fSAndroid Build Coastguard Worker }
280*795d594fSAndroid Build Coastguard Worker return true;
281*795d594fSAndroid Build Coastguard Worker }
282*795d594fSAndroid Build Coastguard Worker
283*795d594fSAndroid Build Coastguard Worker } // namespace art
284*795d594fSAndroid Build Coastguard Worker
285*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
286