xref: /aosp_15_r20/art/runtime/common_dex_operations.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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(&reg));
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