diff options
author | 2016-10-25 15:08:01 -0700 | |
---|---|---|
committer | 2016-10-26 15:25:40 -0700 | |
commit | ef41db7a3f322a1feb305fdb457410c4cea94d00 (patch) | |
tree | c03152c091ef62ab70f5be0a2fe3a965b189132c | |
parent | 1458e0c09fe0a3b9fa5fd7beb9b6077d1fc46b1d (diff) |
Move interpreter to ObjPtr
Moved most of interpreter, interpreter_common,
interpreter_switch_impl, and some of mterp to ObjPtr.
Bug: 31113334
Test: test-art-host ART_TEST_INTERPRETER=true
Test: art/tools/run-libcore-tests.sh '--mode=host' '--variant=X32' --debug
Change-Id: I0935d18287e1332205c17c5a018aa167788ab897
-rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 17 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 6 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 27 | ||||
-rw-r--r-- | runtime/interpreter/interpreter.cc | 85 | ||||
-rw-r--r-- | runtime/interpreter/interpreter.h | 5 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 100 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 77 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_mterp_impl.h | 1 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 129 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.h | 1 | ||||
-rw-r--r-- | runtime/interpreter/mterp/mterp.cc | 35 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 13 | ||||
-rw-r--r-- | runtime/jit/jit.cc | 2 | ||||
-rw-r--r-- | runtime/jit/jit.h | 5 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 2 | ||||
-rw-r--r-- | runtime/mirror/object.h | 2 |
17 files changed, 280 insertions, 229 deletions
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 31811fb96a..ed60f598d1 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -483,15 +483,15 @@ EXPLICIT_FIND_FIELD_FROM_CODE_TYPED_TEMPLATE_DECL(StaticPrimitiveWrite); template<InvokeType type, bool access_check> inline ArtMethod* FindMethodFromCode(uint32_t method_idx, - mirror::Object** this_object, + ObjPtr<mirror::Object>* this_object, ArtMethod* referrer, Thread* self) { ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); ArtMethod* resolved_method = class_linker->GetResolvedMethod(method_idx, referrer); if (resolved_method == nullptr) { StackHandleScope<1> hs(self); - mirror::Object* null_this = nullptr; - HandleWrapper<mirror::Object> h_this( + ObjPtr<mirror::Object> null_this = nullptr; + HandleWrapperObjPtr<mirror::Object> h_this( hs.NewHandleWrapper(type == kStatic ? &null_this : this_object)); constexpr ClassLinker::ResolveMode resolve_mode = access_check ? ClassLinker::kForceICCECheck @@ -560,7 +560,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, // defaults. What we actually need is a GetContainingClass that says which classes virtuals // this method is coming from. StackHandleScope<2> hs2(self); - HandleWrapper<mirror::Object> h_this(hs2.NewHandleWrapper(this_object)); + HandleWrapperObjPtr<mirror::Object> h_this(hs2.NewHandleWrapper(this_object)); Handle<mirror::Class> h_referring_class(hs2.NewHandle(referrer->GetDeclaringClass())); const uint16_t method_type_idx = h_referring_class->GetDexFile().GetMethodId(method_idx).class_idx_; @@ -652,7 +652,7 @@ inline ArtMethod* FindMethodFromCode(uint32_t method_idx, #define EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \ template REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE \ ArtMethod* FindMethodFromCode<_type, _access_check>(uint32_t method_idx, \ - mirror::Object** this_object, \ + ObjPtr<mirror::Object>* this_object, \ ArtMethod* referrer, \ Thread* self) #define EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(_type) \ @@ -722,8 +722,11 @@ inline ArtField* FindFieldFast(uint32_t field_idx, ArtMethod* referrer, FindFiel } // Fast path method resolution that can't throw exceptions. -inline ArtMethod* FindMethodFast(uint32_t method_idx, mirror::Object* this_object, - ArtMethod* referrer, bool access_check, InvokeType type) { +inline ArtMethod* FindMethodFast(uint32_t method_idx, + ObjPtr<mirror::Object> this_object, + ArtMethod* referrer, + bool access_check, + InvokeType type) { ScopedAssertNoThreadSuspension ants(__FUNCTION__); if (UNLIKELY(this_object == nullptr && type != kStatic)) { return nullptr; diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index cbefbbac5d..1ccb4b004c 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -237,7 +237,7 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons } } -bool FillArrayData(mirror::Object* obj, const Instruction::ArrayDataPayload* payload) { +bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload) { DCHECK_EQ(payload->ident, static_cast<uint16_t>(Instruction::kArrayDataSignature)); if (UNLIKELY(obj == nullptr)) { ThrowNullPointerException("null array in FILL_ARRAY_DATA"); diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 20c8401111..bcddfb0508 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -156,7 +156,7 @@ inline ArtField* FindFieldFromCode(uint32_t field_idx, template<InvokeType type, bool access_check> inline ArtMethod* FindMethodFromCode(uint32_t method_idx, - mirror::Object** this_object, + ObjPtr<mirror::Object>* this_object, ArtMethod* referrer, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) @@ -171,7 +171,7 @@ inline ArtField* FindFieldFast(uint32_t field_idx, // Fast path method resolution that can't throw exceptions. inline ArtMethod* FindMethodFast(uint32_t method_idx, - mirror::Object* this_object, + ObjPtr<mirror::Object> this_object, ArtMethod* referrer, bool access_check, InvokeType type) @@ -203,7 +203,7 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); -bool FillArrayData(mirror::Object* obj, const Instruction::ArrayDataPayload* payload) +bool FillArrayData(ObjPtr<mirror::Object> obj, const Instruction::ArrayDataPayload* payload) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 0bb65815bf..fe82878699 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -2121,7 +2121,9 @@ extern "C" uint64_t artQuickGenericJniEndTrampoline(Thread* self, // to hold the mutator lock (see REQUIRES_SHARED(Locks::mutator_lock_) annotations). template<InvokeType type, bool access_check> -static TwoWordReturn artInvokeCommon(uint32_t method_idx, mirror::Object* this_object, Thread* self, +static TwoWordReturn artInvokeCommon(uint32_t method_idx, + ObjPtr<mirror::Object> this_object, + Thread* self, ArtMethod** sp) { ScopedQuickEntrypointChecks sqec(self); DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveRefsAndArgs)); @@ -2136,7 +2138,9 @@ static TwoWordReturn artInvokeCommon(uint32_t method_idx, mirror::Object* this_o ScopedObjectAccessUnchecked soa(self->GetJniEnv()); RememberForGcArgumentVisitor visitor(sp, type == kStatic, shorty, shorty_len, &soa); visitor.VisitArguments(); - method = FindMethodFromCode<type, access_check>(method_idx, &this_object, caller_method, + method = FindMethodFromCode<type, access_check>(method_idx, + &this_object, + caller_method, self); visitor.FixupReferences(); } @@ -2162,7 +2166,7 @@ static TwoWordReturn artInvokeCommon(uint32_t method_idx, mirror::Object* this_o #define EXPLICIT_INVOKE_COMMON_TEMPLATE_DECL(type, access_check) \ template REQUIRES_SHARED(Locks::mutator_lock_) \ TwoWordReturn artInvokeCommon<type, access_check>( \ - uint32_t method_idx, mirror::Object* this_object, Thread* self, ArtMethod** sp) + uint32_t method_idx, ObjPtr<mirror::Object> his_object, Thread* self, ArtMethod** sp) EXPLICIT_INVOKE_COMMON_TEMPLATE_DECL(kVirtual, false); EXPLICIT_INVOKE_COMMON_TEMPLATE_DECL(kVirtual, true); @@ -2190,9 +2194,13 @@ extern "C" TwoWordReturn artInvokeDirectTrampolineWithAccessCheck( } extern "C" TwoWordReturn artInvokeStaticTrampolineWithAccessCheck( - uint32_t method_idx, mirror::Object* this_object, Thread* self, ArtMethod** sp) - REQUIRES_SHARED(Locks::mutator_lock_) { - return artInvokeCommon<kStatic, true>(method_idx, this_object, self, sp); + uint32_t method_idx, + mirror::Object* this_object ATTRIBUTE_UNUSED, + Thread* self, + ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) { + // For static, this_object is not required and may be random garbage. Don't pass it down so that + // it doesn't cause ObjPtr alignment failure check. + return artInvokeCommon<kStatic, true>(method_idx, nullptr, self, sp); } extern "C" TwoWordReturn artInvokeSuperTrampolineWithAccessCheck( @@ -2211,10 +2219,11 @@ extern "C" TwoWordReturn artInvokeVirtualTrampolineWithAccessCheck( // is there for consistency but should not be used, as some architectures overwrite it // in the assembly trampoline. extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t deadbeef ATTRIBUTE_UNUSED, - mirror::Object* this_object, + mirror::Object* raw_this_object, Thread* self, ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Object> this_object(raw_this_object); ScopedQuickEntrypointChecks sqec(self); StackHandleScope<1> hs(self); Handle<mirror::Class> cls(hs.NewHandle(this_object->GetClass())); @@ -2285,7 +2294,9 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t deadbeef ATTRIBUT ScopedObjectAccessUnchecked soa(self->GetJniEnv()); RememberForGcArgumentVisitor visitor(sp, false, shorty, shorty_len, &soa); visitor.VisitArguments(); - method = FindMethodFromCode<kInterface, false>(dex_method_idx, &this_object, caller_method, + method = FindMethodFromCode<kInterface, false>(dex_method_idx, + &this_object, + caller_method, self); visitor.FixupReferences(); } diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index 2e0077056e..a32c800491 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -35,8 +35,17 @@ namespace art { namespace interpreter { -static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty, - Object* receiver, uint32_t* args, JValue* result) +ALWAYS_INLINE static ObjPtr<mirror::Object> ObjArg(uint32_t arg) + REQUIRES_SHARED(Locks::mutator_lock_) { + return ObjPtr<mirror::Object>(reinterpret_cast<mirror::Object*>(arg)); +} + +static void InterpreterJni(Thread* self, + ArtMethod* method, + const StringPiece& shorty, + ObjPtr<mirror::Object> receiver, + uint32_t* args, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, // it should be removed and JNI compiled stubs used instead. @@ -52,7 +61,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), klass.get()); } - result->SetL(soa.Decode<Object>(jresult)); + result->SetL(soa.Decode<mirror::Object>(jresult)); } else if (shorty == "V") { typedef void (fntype)(JNIEnv*, jclass); fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); @@ -87,14 +96,13 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jclass> klass(soa.Env(), soa.AddLocalReference<jclass>(method->GetDeclaringClass())); ScopedLocalRef<jobject> arg0(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[0]))); + soa.AddLocalReference<jobject>(ObjArg(args[0]))); jobject jresult; { ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), klass.get(), arg0.get()); } - result->SetL(soa.Decode<Object>(jresult)); + result->SetL(soa.Decode<mirror::Object>(jresult)); } else if (shorty == "IIZ") { typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); @@ -109,8 +117,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jclass> klass(soa.Env(), soa.AddLocalReference<jclass>(method->GetDeclaringClass())); ScopedLocalRef<jobject> arg0(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[0]))); + soa.AddLocalReference<jobject>(ObjArg(args[0]))); ScopedThreadStateChange tsc(self, kNative); result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); } else if (shorty == "SIZ") { @@ -134,11 +141,9 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jclass> klass(soa.Env(), soa.AddLocalReference<jclass>(method->GetDeclaringClass())); ScopedLocalRef<jobject> arg0(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[0]))); + soa.AddLocalReference<jobject>(ObjArg(args[0]))); ScopedLocalRef<jobject> arg1(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[1]))); + soa.AddLocalReference<jobject>(ObjArg(args[1]))); ScopedThreadStateChange tsc(self, kNative); result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); } else if (shorty == "ZILL") { @@ -147,11 +152,9 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jclass> klass(soa.Env(), soa.AddLocalReference<jclass>(method->GetDeclaringClass())); ScopedLocalRef<jobject> arg1(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[1]))); + soa.AddLocalReference<jobject>(ObjArg(args[1]))); ScopedLocalRef<jobject> arg2(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[2]))); + soa.AddLocalReference<jobject>(ObjArg(args[2]))); ScopedThreadStateChange tsc(self, kNative); result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); } else if (shorty == "VILII") { @@ -160,8 +163,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jclass> klass(soa.Env(), soa.AddLocalReference<jclass>(method->GetDeclaringClass())); ScopedLocalRef<jobject> arg1(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[1]))); + soa.AddLocalReference<jobject>(ObjArg(args[1]))); ScopedThreadStateChange tsc(self, kNative); fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); } else if (shorty == "VLILII") { @@ -170,11 +172,9 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jclass> klass(soa.Env(), soa.AddLocalReference<jclass>(method->GetDeclaringClass())); ScopedLocalRef<jobject> arg0(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[0]))); + soa.AddLocalReference<jobject>(ObjArg(args[0]))); ScopedLocalRef<jobject> arg2(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[2]))); + soa.AddLocalReference<jobject>(ObjArg(args[2]))); ScopedThreadStateChange tsc(self, kNative); fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); } else { @@ -192,7 +192,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), rcvr.get()); } - result->SetL(soa.Decode<Object>(jresult)); + result->SetL(soa.Decode<mirror::Object>(jresult)); } else if (shorty == "V") { typedef void (fntype)(JNIEnv*, jobject); fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); @@ -206,14 +206,13 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedLocalRef<jobject> rcvr(soa.Env(), soa.AddLocalReference<jobject>(receiver)); ScopedLocalRef<jobject> arg0(soa.Env(), - soa.AddLocalReference<jobject>( - reinterpret_cast<Object*>(args[0]))); + soa.AddLocalReference<jobject>(ObjArg(args[0]))); jobject jresult; { ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), rcvr.get(), arg0.get()); } - result->SetL(soa.Decode<Object>(jresult)); + result->SetL(soa.Decode<mirror::Object>(jresult)); ScopedThreadStateChange tsc(self, kNative); } else if (shorty == "III") { typedef jint (fntype)(JNIEnv*, jobject, jint, jint); @@ -312,7 +311,7 @@ static inline JValue Execute( } else { // Mterp didn't like that instruction. Single-step it with the reference interpreter. result_register = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, - result_register, true); + result_register, true); if (shadow_frame.GetDexPC() == DexFile::kDexNoIndex) { // Single-stepped a return or an exception not handled locally. Return to caller. return result_register; @@ -354,8 +353,11 @@ static inline JValue Execute( } } -void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver, - uint32_t* args, JValue* result, +void EnterInterpreterFromInvoke(Thread* self, + ArtMethod* method, + ObjPtr<mirror::Object> receiver, + uint32_t* args, + JValue* result, bool stay_in_interpreter) { DCHECK_EQ(self, Thread::Current()); bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); @@ -393,7 +395,7 @@ void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receive size_t cur_reg = num_regs - num_ins; if (!method->IsStatic()) { CHECK(receiver != nullptr); - shadow_frame->SetVRegReference(cur_reg, receiver); + shadow_frame->SetVRegReference(cur_reg, receiver.Ptr()); ++cur_reg; } uint32_t shorty_len = 0; @@ -402,8 +404,9 @@ void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receive DCHECK_LT(shorty_pos + 1, shorty_len); switch (shorty[shorty_pos + 1]) { case 'L': { - Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr(); - shadow_frame->SetVRegReference(cur_reg, o); + ObjPtr<mirror::Object> o = + reinterpret_cast<StackReference<mirror::Object>*>(&args[arg_pos])->AsMirrorPtr(); + shadow_frame->SetVRegReference(cur_reg, o.Ptr()); break; } case 'J': case 'D': { @@ -442,7 +445,7 @@ void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receive // references pointers due to moving GC. args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); if (!Runtime::Current()->IsStarted()) { - UnstartedRuntime::Jni(self, method, receiver, args, result); + UnstartedRuntime::Jni(self, method, receiver.Ptr(), args, result); } else { InterpreterJni(self, method, shorty, receiver, args, result); } @@ -539,7 +542,7 @@ void EnterInterpreterFromDeoptimize(Thread* self, if (kIsDebugBuild) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); // This is a suspend point. But it's ok since value has been set into shadow_frame. - mirror::Class* klass = class_linker->ResolveType( + ObjPtr<mirror::Class> klass = class_linker->ResolveType( instr->VRegB_21c(), shadow_frame->GetMethod()); DCHECK(klass->IsStringClass()); } @@ -582,8 +585,10 @@ JValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* cod return Execute(self, code_item, *shadow_frame, JValue()); } -void ArtInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item, - ShadowFrame* shadow_frame, JValue* result) { +void ArtInterpreterToInterpreterBridge(Thread* self, + const DexFile::CodeItem* code_item, + ShadowFrame* shadow_frame, + JValue* result) { bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { ThrowStackOverflowError(self); @@ -595,10 +600,10 @@ void ArtInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* co // Ensure static methods are initialized. const bool is_static = method->IsStatic(); if (is_static) { - mirror::Class* declaring_class = method->GetDeclaringClass(); + ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); if (UNLIKELY(!declaring_class->IsInitialized())) { StackHandleScope<1> hs(self); - HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); + HandleWrapperObjPtr<mirror::Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( self, h_declaring_class, true, true))) { DCHECK(self->IsExceptionPending()); @@ -615,9 +620,9 @@ void ArtInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* co // We don't expect to be asked to interpret native code (which is entered via a JNI compiler // generated stub) except during testing and image writing. CHECK(!Runtime::Current()->IsStarted()); - Object* receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); + ObjPtr<mirror::Object> receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); - UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver, args, result); + UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver.Ptr(), args, result); } self->PopShadowFrame(); diff --git a/runtime/interpreter/interpreter.h b/runtime/interpreter/interpreter.h index 38ce851e8e..65cfade09a 100644 --- a/runtime/interpreter/interpreter.h +++ b/runtime/interpreter/interpreter.h @@ -19,6 +19,7 @@ #include "base/mutex.h" #include "dex_file.h" +#include "obj_ptr.h" namespace art { namespace mirror { @@ -36,7 +37,9 @@ namespace interpreter { // The optional stay_in_interpreter parameter (false by default) can be used by clients to // explicitly force interpretation in the remaining path that implements method invocation. extern void EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, - mirror::Object* receiver, uint32_t* args, JValue* result, + ObjPtr<mirror::Object> receiver, + uint32_t* args, + JValue* result, bool stay_in_interpreter = false) REQUIRES_SHARED(Locks::mutator_lock_); diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index a0d712ecbb..6f476365e2 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -54,7 +54,7 @@ bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst CHECK(self->IsExceptionPending()); return false; } - ObjPtr<Object> obj; + ObjPtr<mirror::Object> obj; if (is_static) { obj = f->GetDeclaringClass(); } else { @@ -71,7 +71,7 @@ bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst StackHandleScope<1> hs(self); // Wrap in handle wrapper in case the listener does thread suspension. HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj)); - ObjPtr<Object> this_object; + ObjPtr<mirror::Object> this_object; if (!f->IsStatic()) { this_object = obj; } @@ -147,7 +147,7 @@ EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(StaticObjectRead, Primitive::kPrimNot) // Returns true on success, otherwise throws an exception and returns false. template<Primitive::Type field_type> bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { - Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); if (UNLIKELY(obj == nullptr)) { // We lost the reference to the field index so we cannot get a more // precised exception message. @@ -163,8 +163,11 @@ bool DoIGetQuick(ShadowFrame& shadow_frame, const Instruction* inst, uint16_t in field_offset.Uint32Value()); DCHECK(f != nullptr); DCHECK(!f->IsStatic()); - instrumentation->FieldReadEvent(Thread::Current(), obj, shadow_frame.GetMethod(), - shadow_frame.GetDexPC(), f); + instrumentation->FieldReadEvent(Thread::Current(), + obj.Ptr(), + shadow_frame.GetMethod(), + shadow_frame.GetDexPC(), + f); } // Note: iget-x-quick instructions are only for non-volatile fields. const uint32_t vregA = inst->VRegA_22c(inst_data); @@ -258,7 +261,7 @@ bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction CHECK(self->IsExceptionPending()); return false; } - ObjPtr<Object> obj; + ObjPtr<mirror::Object> obj; if (is_static) { obj = f->GetDeclaringClass(); } else { @@ -278,7 +281,7 @@ bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction // Wrap in handle wrapper in case the listener does thread suspension. HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj)); JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA); - ObjPtr<Object> this_object = f->IsStatic() ? nullptr : obj; + ObjPtr<mirror::Object> this_object = f->IsStatic() ? nullptr : obj; instrumentation->FieldWriteEvent(self, this_object.Ptr(), shadow_frame.GetMethod(), shadow_frame.GetDexPC(), @@ -305,14 +308,14 @@ bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction f->SetLong<transaction_active>(obj, shadow_frame.GetVRegLong(vregA)); break; case Primitive::kPrimNot: { - Object* reg = shadow_frame.GetVRegReference(vregA); + ObjPtr<mirror::Object> reg = shadow_frame.GetVRegReference(vregA); if (do_assignability_check && reg != nullptr) { // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the // object in the destructor. - ObjPtr<Class> field_class; + ObjPtr<mirror::Class> field_class; { StackHandleScope<2> hs(self); - HandleWrapper<mirror::Object> h_reg(hs.NewHandleWrapper(®)); + HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(®)); HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj)); field_class = f->GetType<true>(); } @@ -371,7 +374,7 @@ EXPLICIT_DO_FIELD_PUT_ALL_TEMPLATE_DECL(StaticObjectWrite, Primitive::kPrimNot) template<Primitive::Type field_type, bool transaction_active> bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data) { - Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); if (UNLIKELY(obj == nullptr)) { // We lost the reference to the field index so we cannot get a more // precised exception message. @@ -389,8 +392,12 @@ bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint1 DCHECK(f != nullptr); DCHECK(!f->IsStatic()); JValue field_value = GetFieldValue<field_type>(shadow_frame, vregA); - instrumentation->FieldWriteEvent(Thread::Current(), obj, shadow_frame.GetMethod(), - shadow_frame.GetDexPC(), f, field_value); + instrumentation->FieldWriteEvent(Thread::Current(), + obj.Ptr(), + shadow_frame.GetMethod(), + shadow_frame.GetDexPC(), + f, + field_value); } // Note: iput-x-quick instructions are only for non-volatile fields. switch (field_type) { @@ -554,7 +561,7 @@ void ArtInterpreterToCompiledCodeBridge(Thread* self, ArtMethod* method = shadow_frame->GetMethod(); // Ensure static methods are initialized. if (method->IsStatic()) { - mirror::Class* declaringClass = method->GetDeclaringClass(); + ObjPtr<mirror::Class> declaringClass = method->GetDeclaringClass(); if (UNLIKELY(!declaringClass->IsInitialized())) { self->PushShadowFrame(shadow_frame); StackHandleScope<1> hs(self); @@ -587,7 +594,7 @@ void SetStringInitValueToAllAliases(ShadowFrame* shadow_frame, uint16_t this_obj_vreg, JValue result) REQUIRES_SHARED(Locks::mutator_lock_) { - Object* existing = shadow_frame->GetVRegReference(this_obj_vreg); + ObjPtr<mirror::Object> existing = shadow_frame->GetVRegReference(this_obj_vreg); if (existing == nullptr) { // If it's null, we come from compiled code that was deoptimized. Nothing to do, // as the compiler verified there was no alias. @@ -608,10 +615,11 @@ void SetStringInitValueToAllAliases(ShadowFrame* shadow_frame, } template<bool is_range, bool do_access_check> - REQUIRES_SHARED(Locks::mutator_lock_) -inline bool DoInvokePolymorphic(Thread* self, ShadowFrame& shadow_frame, - const Instruction* inst, uint16_t inst_data, - JValue* result) { +inline bool DoInvokePolymorphic(Thread* self, + ShadowFrame& shadow_frame, + const Instruction* inst, + uint16_t inst_data, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { // Invoke-polymorphic instructions always take a receiver. i.e, they are never static. const uint32_t vRegC = (is_range) ? inst->VRegC_4rcc() : inst->VRegC_45cc(); @@ -625,7 +633,8 @@ inline bool DoInvokePolymorphic(Thread* self, ShadowFrame& shadow_frame, // that vRegC really is a reference type. StackHandleScope<6> hs(self); Handle<mirror::MethodHandleImpl> method_handle(hs.NewHandle( - reinterpret_cast<mirror::MethodHandleImpl*>(shadow_frame.GetVRegReference(vRegC)))); + ObjPtr<mirror::MethodHandleImpl>::DownCast( + MakeObjPtr(shadow_frame.GetVRegReference(vRegC))))); if (UNLIKELY(method_handle.Get() == nullptr)) { const int method_idx = (is_range) ? inst->VRegB_4rcc() : inst->VRegB_45cc(); // Note that the invoke type is kVirtual here because a call to a signature @@ -683,8 +692,8 @@ inline bool DoInvokePolymorphic(Thread* self, ShadowFrame& shadow_frame, if (IsInvoke(handle_kind)) { if (handle_kind == kInvokeVirtual || handle_kind == kInvokeInterface) { - mirror::Object* receiver = shadow_frame.GetVRegReference(receiver_vregC); - mirror::Class* declaring_class = called_method->GetDeclaringClass(); + ObjPtr<mirror::Object> receiver = shadow_frame.GetVRegReference(receiver_vregC); + ObjPtr<mirror::Class> declaring_class = called_method->GetDeclaringClass(); // Verify that _vRegC is an object reference and of the type expected by // the receiver. called_method = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface( @@ -704,15 +713,15 @@ inline bool DoInvokePolymorphic(Thread* self, ShadowFrame& shadow_frame, // constructor. It's a private method, and we've already access checked at // the point of creating the handle. } else if (handle_kind == kInvokeSuper) { - mirror::Class* declaring_class = called_method->GetDeclaringClass(); + ObjPtr<mirror::Class> declaring_class = called_method->GetDeclaringClass(); // Note that we're not dynamically dispatching on the type of the receiver // here. We use the static type of the "receiver" object that we've // recorded in the method handle's type, which will be the same as the // special caller that was specified at the point of lookup. - mirror::Class* referrer_class = handle_type->GetPTypes()->Get(0); + ObjPtr<mirror::Class> referrer_class = handle_type->GetPTypes()->Get(0); if (!declaring_class->IsInterface()) { - mirror::Class* super_class = referrer_class->GetSuperClass(); + ObjPtr<mirror::Class> super_class = referrer_class->GetSuperClass(); uint16_t vtable_index = called_method->GetMethodIndex(); DCHECK(super_class != nullptr); DCHECK(super_class->HasVTable()); @@ -1104,10 +1113,10 @@ static inline bool DoCallCommon(ArtMethod* called_method, switch (shorty[shorty_pos + 1]) { // Handle Object references. 1 virtual register slot. case 'L': { - Object* o = shadow_frame.GetVRegReference(src_reg); + ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference(src_reg); if (do_assignability_check && o != nullptr) { PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - Class* arg_type = + ObjPtr<mirror::Class> arg_type = method->GetClassFromTypeIndex( params->GetTypeItem(shorty_pos).type_idx_, true /* resolve */, pointer_size); if (arg_type == nullptr) { @@ -1125,7 +1134,7 @@ static inline bool DoCallCommon(ArtMethod* called_method, return false; } } - new_shadow_frame->SetVRegReference(dest_reg, o); + new_shadow_frame->SetVRegReference(dest_reg, o.Ptr()); break; } // Handle doubles and longs. 2 consecutive virtual register slots. @@ -1192,8 +1201,10 @@ bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame, } template <bool is_range, bool do_access_check, bool transaction_active> -bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, - Thread* self, JValue* result) { +bool DoFilledNewArray(const Instruction* inst, + const ShadowFrame& shadow_frame, + Thread* self, + JValue* result) { DCHECK(inst->Opcode() == Instruction::FILLED_NEW_ARRAY || inst->Opcode() == Instruction::FILLED_NEW_ARRAY_RANGE); const int32_t length = is_range ? inst->VRegA_3rc() : inst->VRegA_35c(); @@ -1206,14 +1217,17 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, return false; } uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); - Class* array_class = ResolveVerifyAndClinit(type_idx, shadow_frame.GetMethod(), - self, false, do_access_check); + ObjPtr<mirror::Class> array_class = ResolveVerifyAndClinit(type_idx, + shadow_frame.GetMethod(), + self, + false, + do_access_check); if (UNLIKELY(array_class == nullptr)) { DCHECK(self->IsExceptionPending()); return false; } CHECK(array_class->IsArrayClass()); - Class* component_class = array_class->GetComponentType(); + ObjPtr<mirror::Class> component_class = array_class->GetComponentType(); const bool is_primitive_int_component = component_class->IsPrimitiveInt(); if (UNLIKELY(component_class->IsPrimitive() && !is_primitive_int_component)) { if (component_class->IsPrimitiveLong() || component_class->IsPrimitiveDouble()) { @@ -1226,9 +1240,12 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, } return false; } - Object* new_array = Array::Alloc<true>(self, array_class, length, - array_class->GetComponentSizeShift(), - Runtime::Current()->GetHeap()->GetCurrentAllocator()); + ObjPtr<mirror::Object> new_array = mirror::Array::Alloc<true>( + self, + array_class, + length, + array_class->GetComponentSizeShift(), + Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(new_array == nullptr)) { self->AssertPendingOOMException(); return false; @@ -1246,7 +1263,7 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, new_array->AsIntArray()->SetWithoutChecks<transaction_active>( i, shadow_frame.GetVReg(src_reg)); } else { - new_array->AsObjectArray<Object>()->SetWithoutChecks<transaction_active>( + new_array->AsObjectArray<mirror::Object>()->SetWithoutChecks<transaction_active>( i, shadow_frame.GetVRegReference(src_reg)); } } @@ -1255,17 +1272,18 @@ bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, return true; } -// TODO fix thread analysis: should be REQUIRES_SHARED(Locks::mutator_lock_). +// TODO: Use ObjPtr here. template<typename T> -static void RecordArrayElementsInTransactionImpl(mirror::PrimitiveArray<T>* array, int32_t count) - NO_THREAD_SAFETY_ANALYSIS { +static void RecordArrayElementsInTransactionImpl(mirror::PrimitiveArray<T>* array, + int32_t count) + REQUIRES_SHARED(Locks::mutator_lock_) { Runtime* runtime = Runtime::Current(); for (int32_t i = 0; i < count; ++i) { runtime->RecordWriteArray(array, i, array->GetWithoutChecks(i)); } } -void RecordArrayElementsInTransaction(mirror::Array* array, int32_t count) +void RecordArrayElementsInTransaction(ObjPtr<mirror::Array> array, int32_t count) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(Runtime::Current()->IsActiveTransaction()); DCHECK(array != nullptr); diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 40d6f036a2..9c26d24ab1 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -43,25 +43,11 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "mirror/string-inl.h" +#include "obj_ptr.h" #include "stack.h" #include "thread.h" #include "well_known_classes.h" -using ::art::ArtMethod; -using ::art::mirror::Array; -using ::art::mirror::BooleanArray; -using ::art::mirror::ByteArray; -using ::art::mirror::CharArray; -using ::art::mirror::Class; -using ::art::mirror::ClassLoader; -using ::art::mirror::IntArray; -using ::art::mirror::LongArray; -using ::art::mirror::Object; -using ::art::mirror::ObjectArray; -using ::art::mirror::ShortArray; -using ::art::mirror::String; -using ::art::mirror::Throwable; - namespace art { namespace interpreter { @@ -69,13 +55,11 @@ void ThrowNullPointerExceptionFromInterpreter() REQUIRES_SHARED(Locks::mutator_lock_); template <bool kMonitorCounting> -static inline void DoMonitorEnter(Thread* self, - ShadowFrame* frame, - Object* ref) +static inline void DoMonitorEnter(Thread* self, ShadowFrame* frame, ObjPtr<mirror::Object> ref) NO_THREAD_SAFETY_ANALYSIS REQUIRES(!Roles::uninterruptible_) { StackHandleScope<1> hs(self); - Handle<Object> h_ref(hs.NewHandle(ref)); + Handle<mirror::Object> h_ref(hs.NewHandle(ref)); h_ref->MonitorEnter(self); if (kMonitorCounting && frame->GetMethod()->MustCountLocks()) { frame->GetLockCountData().AddMonitor(self, h_ref.Get()); @@ -83,13 +67,11 @@ static inline void DoMonitorEnter(Thread* self, } template <bool kMonitorCounting> -static inline void DoMonitorExit(Thread* self, - ShadowFrame* frame, - Object* ref) +static inline void DoMonitorExit(Thread* self, ShadowFrame* frame, ObjPtr<mirror::Object> ref) NO_THREAD_SAFETY_ANALYSIS REQUIRES(!Roles::uninterruptible_) { StackHandleScope<1> hs(self); - Handle<Object> h_ref(hs.NewHandle(ref)); + Handle<mirror::Object> h_ref(hs.NewHandle(ref)); h_ref->MonitorExit(self); if (kMonitorCounting && frame->GetMethod()->MustCountLocks()) { frame->GetLockCountData().RemoveMonitorOrThrow(self, h_ref.Get()); @@ -113,7 +95,7 @@ void AbortTransactionF(Thread* self, const char* fmt, ...) void AbortTransactionV(Thread* self, const char* fmt, va_list args) REQUIRES_SHARED(Locks::mutator_lock_); -void RecordArrayElementsInTransaction(mirror::Array* array, int32_t count) +void RecordArrayElementsInTransaction(ObjPtr<mirror::Array> array, int32_t count) REQUIRES_SHARED(Locks::mutator_lock_); // Invokes the given method. This is part of the invocation support and is used by DoInvoke and @@ -126,11 +108,14 @@ bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame, // Handles all invoke-XXX/range instructions except for invoke-polymorphic[/range]. // Returns true on success, otherwise throws an exception and returns false. template<InvokeType type, bool is_range, bool do_access_check> -static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, - uint16_t inst_data, JValue* result) { +static inline bool DoInvoke(Thread* self, + ShadowFrame& shadow_frame, + const Instruction* inst, + uint16_t inst_data, + JValue* result) { const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); - Object* receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC); + ObjPtr<mirror::Object> receiver = (type == kStatic) ? nullptr : shadow_frame.GetVRegReference(vregC); ArtMethod* sf_method = shadow_frame.GetMethod(); ArtMethod* const called_method = FindMethodFromCode<type, do_access_check>( method_idx, &receiver, sf_method, self); @@ -156,7 +141,7 @@ static inline bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instr instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasInvokeVirtualOrInterfaceListeners())) { instrumentation->InvokeVirtualOrInterface( - self, receiver, sf_method, shadow_frame.GetDexPC(), called_method); + self, receiver.Ptr(), sf_method, shadow_frame.GetDexPC(), called_method); } } return DoCall<is_range, do_access_check>(called_method, self, shadow_frame, inst, inst_data, @@ -177,7 +162,7 @@ static inline bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, uint16_t inst_data, JValue* result) { const uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); - Object* const receiver = shadow_frame.GetVRegReference(vregC); + ObjPtr<mirror::Object> const receiver = shadow_frame.GetVRegReference(vregC); if (UNLIKELY(receiver == nullptr)) { // We lost the reference to the method index so we cannot get a more // precised exception message. @@ -190,7 +175,7 @@ static inline bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, CHECK(receiver->GetClass() != nullptr) << "Null class found in object " << receiver << " in region type " << Runtime::Current()->GetHeap()->ConcurrentCopyingCollector()-> - RegionSpace()->GetRegionType(receiver); + RegionSpace()->GetRegionType(receiver.Ptr()); } CHECK(receiver->GetClass()->ShouldHaveEmbeddedVTable()); ArtMethod* const called_method = receiver->GetClass()->GetEmbeddedVTableEntry( @@ -214,7 +199,7 @@ static inline bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, // TODO: Remove the InvokeVirtualOrInterface instrumentation, as it was only used by the JIT. if (UNLIKELY(instrumentation->HasInvokeVirtualOrInterfaceListeners())) { instrumentation->InvokeVirtualOrInterface( - self, receiver, shadow_frame.GetMethod(), shadow_frame.GetDexPC(), called_method); + self, receiver.Ptr(), shadow_frame.GetMethod(), shadow_frame.GetDexPC(), called_method); } // No need to check since we've been quickened. return DoCall<is_range, false>(called_method, self, shadow_frame, inst, inst_data, result); @@ -249,9 +234,11 @@ bool DoIPutQuick(const ShadowFrame& shadow_frame, const Instruction* inst, uint1 // Handles string resolution for const-string and const-string-jumbo instructions. Also ensures the // java.lang.String class is initialized. -static inline String* ResolveString(Thread* self, ShadowFrame& shadow_frame, uint32_t string_idx) +static inline ObjPtr<mirror::String> ResolveString(Thread* self, + ShadowFrame& shadow_frame, + uint32_t string_idx) REQUIRES_SHARED(Locks::mutator_lock_) { - Class* java_lang_string_class = String::GetJavaLangString(); + ObjPtr<mirror::Class> java_lang_string_class = mirror::String::GetJavaLangString(); if (UNLIKELY(!java_lang_string_class->IsInitialized())) { ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); StackHandleScope<1> hs(self); @@ -262,11 +249,11 @@ static inline String* ResolveString(Thread* self, ShadowFrame& shadow_frame, uin } } ArtMethod* method = shadow_frame.GetMethod(); - mirror::Class* declaring_class = method->GetDeclaringClass(); + ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); // MethodVerifier refuses methods with string_idx out of bounds. DCHECK_LT(string_idx % mirror::DexCache::kDexCacheStringCacheSize, declaring_class->GetDexFile().NumStringIds()); - mirror::String* string_ptr = + ObjPtr<mirror::String> string_ptr = mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(), string_idx, mirror::DexCache::kDexCacheStringCacheSize).Read(); @@ -318,8 +305,10 @@ static inline bool DoIntRemainder(ShadowFrame& shadow_frame, size_t result_reg, // Handles div-long and div-long-2addr instructions. // Returns true on success, otherwise throws a java.lang.ArithmeticException and return false. -static inline bool DoLongDivide(ShadowFrame& shadow_frame, size_t result_reg, - int64_t dividend, int64_t divisor) +static inline bool DoLongDivide(ShadowFrame& shadow_frame, + size_t result_reg, + int64_t dividend, + int64_t divisor) REQUIRES_SHARED(Locks::mutator_lock_) { const int64_t kMinLong = std::numeric_limits<int64_t>::min(); if (UNLIKELY(divisor == 0)) { @@ -336,8 +325,10 @@ static inline bool DoLongDivide(ShadowFrame& shadow_frame, size_t result_reg, // Handles rem-long and rem-long-2addr instructions. // Returns true on success, otherwise throws a java.lang.ArithmeticException and return false. -static inline bool DoLongRemainder(ShadowFrame& shadow_frame, size_t result_reg, - int64_t dividend, int64_t divisor) +static inline bool DoLongRemainder(ShadowFrame& shadow_frame, + size_t result_reg, + int64_t dividend, + int64_t divisor) REQUIRES_SHARED(Locks::mutator_lock_) { const int64_t kMinLong = std::numeric_limits<int64_t>::min(); if (UNLIKELY(divisor == 0)) { @@ -443,7 +434,7 @@ static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruc << inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\n"; for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) { uint32_t raw_value = shadow_frame.GetVReg(i); - Object* ref_value = shadow_frame.GetVRegReference(i); + ObjPtr<mirror::Object> ref_value = shadow_frame.GetVRegReference(i); oss << StringPrintf(" vreg%u=0x%08X", i, raw_value); if (ref_value != nullptr) { if (ref_value->GetClass()->IsStringClass() && @@ -469,13 +460,13 @@ static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFra REQUIRES_SHARED(Locks::mutator_lock_) { // Uint required, so that sign extension does not make this wrong on 64b systems uint32_t src_value = shadow_frame.GetVReg(src_reg); - mirror::Object* o = shadow_frame.GetVRegReference<kVerifyNone>(src_reg); + ObjPtr<mirror::Object> o = shadow_frame.GetVRegReference<kVerifyNone>(src_reg); // If both register locations contains the same value, the register probably holds a reference. // Note: As an optimization, non-moving collectors leave a stale reference value // in the references array even after the original vreg was overwritten to a non-reference. - if (src_value == reinterpret_cast<uintptr_t>(o)) { - new_shadow_frame->SetVRegReference(dest_reg, o); + if (src_value == reinterpret_cast<uintptr_t>(o.Ptr())) { + new_shadow_frame->SetVRegReference(dest_reg, o.Ptr()); } else { new_shadow_frame->SetVReg(dest_reg, src_value); } diff --git a/runtime/interpreter/interpreter_mterp_impl.h b/runtime/interpreter/interpreter_mterp_impl.h index 90d9f89d67..1be20fab25 100644 --- a/runtime/interpreter/interpreter_mterp_impl.h +++ b/runtime/interpreter/interpreter_mterp_impl.h @@ -21,6 +21,7 @@ #include "base/mutex.h" #include "dex_file.h" #include "jvalue.h" +#include "obj_ptr.h" namespace art { diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index 78afe56104..43bc9bd162 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -192,9 +192,9 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, break; case Instruction::MOVE_EXCEPTION: { PREAMBLE(); - Throwable* exception = self->GetException(); + ObjPtr<mirror::Throwable> exception = self->GetException(); DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction"; - shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception); + shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr()); self->ClearException(); inst = inst->Next_1xx(); break; @@ -273,11 +273,11 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, self->AllowThreadSuspension(); HANDLE_MONITOR_CHECKS(); const size_t ref_idx = inst->VRegA_11x(inst_data); - Object* obj_result = shadow_frame.GetVRegReference(ref_idx); + ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx); if (do_assignability_check && obj_result != nullptr) { PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); - Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */, - pointer_size); + ObjPtr<mirror::Class> return_type = method->GetReturnType(true /* resolve */, + pointer_size); // Re-load since it might have moved. obj_result = shadow_frame.GetVRegReference(ref_idx); if (return_type == nullptr) { @@ -373,41 +373,44 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, break; case Instruction::CONST_STRING: { PREAMBLE(); - String* s = ResolveString(self, shadow_frame, inst->VRegB_21c()); + ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, inst->VRegB_21c()); if (UNLIKELY(s == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr()); inst = inst->Next_2xx(); } break; } case Instruction::CONST_STRING_JUMBO: { PREAMBLE(); - String* s = ResolveString(self, shadow_frame, inst->VRegB_31c()); + ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, inst->VRegB_31c()); if (UNLIKELY(s == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s); + shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr()); inst = inst->Next_3xx(); } break; } case Instruction::CONST_CLASS: { PREAMBLE(); - Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), - self, false, do_access_check); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + shadow_frame.GetMethod(), + self, + false, + do_access_check); if (UNLIKELY(c == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr()); inst = inst->Next_2xx(); } break; } case Instruction::MONITOR_ENTER: { PREAMBLE(); - Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); if (UNLIKELY(obj == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -419,7 +422,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::MONITOR_EXIT: { PREAMBLE(); - Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); if (UNLIKELY(obj == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -431,12 +434,15 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::CHECK_CAST: { PREAMBLE(); - Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), - self, false, do_access_check); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + shadow_frame.GetMethod(), + self, + false, + do_access_check); if (UNLIKELY(c == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data)); if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) { ThrowClassCastException(c, obj->GetClass()); HANDLE_PENDING_EXCEPTION(); @@ -448,12 +454,15 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::INSTANCE_OF: { PREAMBLE(); - Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(), - self, false, do_access_check); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegC_22c(), + shadow_frame.GetMethod(), + self, + false, + do_access_check); if (UNLIKELY(c == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0); inst = inst->Next_2xx(); @@ -462,7 +471,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::ARRAY_LENGTH: { PREAMBLE(); - Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)); + ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)); if (UNLIKELY(array == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -474,9 +483,12 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::NEW_INSTANCE: { PREAMBLE(); - Object* obj = nullptr; - Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), - self, false, do_access_check); + ObjPtr<mirror::Object> obj = nullptr; + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(inst->VRegB_21c(), + shadow_frame.GetMethod(), + self, + false, + do_access_check); if (LIKELY(c != nullptr)) { if (UNLIKELY(c->IsStringClass())) { gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); @@ -499,7 +511,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, HANDLE_PENDING_EXCEPTION(); break; } - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr()); inst = inst->Next_2xx(); } break; @@ -507,13 +519,13 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, case Instruction::NEW_ARRAY: { PREAMBLE(); int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data)); - Object* obj = AllocArrayFromCode<do_access_check, true>( + ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>( inst->VRegC_22c(), length, shadow_frame.GetMethod(), self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(obj == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj); + shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr()); inst = inst->Next_2xx(); } break; @@ -539,7 +551,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t(); const Instruction::ArrayDataPayload* payload = reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr); - Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data)); + ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data)); bool success = FillArrayData(obj, payload); if (!success) { HANDLE_PENDING_EXCEPTION(); @@ -553,7 +565,8 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::THROW: { PREAMBLE(); - Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); + ObjPtr<mirror::Object> exception = + shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); if (UNLIKELY(exception == nullptr)) { ThrowNullPointerException("throw with null exception"); } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) { @@ -911,14 +924,14 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET_BOOLEAN: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); break; } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - BooleanArray* array = a->AsBooleanArray(); + ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray(); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -929,14 +942,14 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET_BYTE: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); break; } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - ByteArray* array = a->AsByteArray(); + ObjPtr<mirror::ByteArray> array = a->AsByteArray(); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -947,14 +960,14 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET_CHAR: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); break; } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - CharArray* array = a->AsCharArray(); + ObjPtr<mirror::CharArray> array = a->AsCharArray(); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -965,14 +978,14 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET_SHORT: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); break; } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - ShortArray* array = a->AsShortArray(); + ObjPtr<mirror::ShortArray> array = a->AsShortArray(); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -983,7 +996,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -991,7 +1004,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf(); - auto* array = down_cast<IntArray*>(a); + ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -1002,7 +1015,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET_WIDE: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1010,7 +1023,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf(); - auto* array = down_cast<LongArray*>(a); + ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -1021,14 +1034,14 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::AGET_OBJECT: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); break; } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - ObjectArray<Object>* array = a->AsObjectArray<Object>(); + ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>(); if (array->CheckIsValidIndex(index)) { shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index)); inst = inst->Next_2xx(); @@ -1039,7 +1052,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT_BOOLEAN: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1047,7 +1060,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - BooleanArray* array = a->AsBooleanArray(); + ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray(); if (array->CheckIsValidIndex(index)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); @@ -1058,7 +1071,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT_BYTE: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1066,7 +1079,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - ByteArray* array = a->AsByteArray(); + ObjPtr<mirror::ByteArray> array = a->AsByteArray(); if (array->CheckIsValidIndex(index)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); @@ -1077,7 +1090,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT_CHAR: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1085,7 +1098,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - CharArray* array = a->AsCharArray(); + ObjPtr<mirror::CharArray> array = a->AsCharArray(); if (array->CheckIsValidIndex(index)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); @@ -1096,7 +1109,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT_SHORT: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1104,7 +1117,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - ShortArray* array = a->AsShortArray(); + ObjPtr<mirror::ShortArray> array = a->AsShortArray(); if (array->CheckIsValidIndex(index)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); @@ -1115,7 +1128,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1124,7 +1137,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data)); int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf(); - auto* array = down_cast<IntArray*>(a); + ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a); if (array->CheckIsValidIndex(index)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); @@ -1135,7 +1148,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT_WIDE: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); @@ -1144,7 +1157,7 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data)); int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf(); - LongArray* array = down_cast<LongArray*>(a); + ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a); if (array->CheckIsValidIndex(index)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); @@ -1155,15 +1168,15 @@ JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item, } case Instruction::APUT_OBJECT: { PREAMBLE(); - Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); + ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { ThrowNullPointerExceptionFromInterpreter(); HANDLE_PENDING_EXCEPTION(); break; } int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); - Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data)); - ObjectArray<Object>* array = a->AsObjectArray<Object>(); + ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data)); + ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>(); if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) { array->SetWithoutChecks<transaction_active>(index, val); inst = inst->Next_2xx(); diff --git a/runtime/interpreter/interpreter_switch_impl.h b/runtime/interpreter/interpreter_switch_impl.h index d0c9386bd9..267df2e219 100644 --- a/runtime/interpreter/interpreter_switch_impl.h +++ b/runtime/interpreter/interpreter_switch_impl.h @@ -21,6 +21,7 @@ #include "base/mutex.h" #include "dex_file.h" #include "jvalue.h" +#include "obj_ptr.h" namespace art { diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index cf8d4bd1b5..46d5af179f 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -291,11 +291,11 @@ extern "C" size_t MterpConstString(uint32_t index, ShadowFrame* shadow_frame, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - String* s = ResolveString(self, *shadow_frame, index); + ObjPtr<mirror::String> s = ResolveString(self, *shadow_frame, index); if (UNLIKELY(s == nullptr)) { return true; } - shadow_frame->SetVRegReference(tgt_vreg, s); + shadow_frame->SetVRegReference(tgt_vreg, s.Ptr()); return false; } @@ -304,7 +304,7 @@ extern "C" size_t MterpConstClass(uint32_t index, ShadowFrame* shadow_frame, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - Class* c = ResolveVerifyAndClinit(index, shadow_frame->GetMethod(), self, false, false); + mirror::Class* c = ResolveVerifyAndClinit(index, shadow_frame->GetMethod(), self, false, false); if (UNLIKELY(c == nullptr)) { return true; } @@ -317,12 +317,12 @@ extern "C" size_t MterpCheckCast(uint32_t index, art::ArtMethod* method, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - Class* c = ResolveVerifyAndClinit(index, method, self, false, false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(index, method, self, false, false); if (UNLIKELY(c == nullptr)) { return true; } // Must load obj from vreg following ResolveVerifyAndClinit due to moving gc. - Object* obj = vreg_addr->AsMirrorPtr(); + mirror::Object* obj = vreg_addr->AsMirrorPtr(); if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) { ThrowClassCastException(c, obj->GetClass()); return true; @@ -335,16 +335,16 @@ extern "C" size_t MterpInstanceOf(uint32_t index, art::ArtMethod* method, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - Class* c = ResolveVerifyAndClinit(index, method, self, false, false); + ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(index, method, self, false, false); if (UNLIKELY(c == nullptr)) { return false; // Caller will check for pending exception. Return value unimportant. } // Must load obj from vreg following ResolveVerifyAndClinit due to moving gc. - Object* obj = vreg_addr->AsMirrorPtr(); + mirror::Object* obj = vreg_addr->AsMirrorPtr(); return (obj != nullptr) && obj->InstanceOf(c); } -extern "C" size_t MterpFillArrayData(Object* obj, const Instruction::ArrayDataPayload* payload) +extern "C" size_t MterpFillArrayData(mirror::Object* obj, const Instruction::ArrayDataPayload* payload) REQUIRES_SHARED(Locks::mutator_lock_) { return FillArrayData(obj, payload); } @@ -352,9 +352,12 @@ extern "C" size_t MterpFillArrayData(Object* obj, const Instruction::ArrayDataPa extern "C" size_t MterpNewInstance(ShadowFrame* shadow_frame, Thread* self, uint32_t inst_data) REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(shadow_frame->GetDexPCPtr()); - Object* obj = nullptr; - Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame->GetMethod(), - self, false, false); + mirror::Object* obj = nullptr; + mirror::Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), + shadow_frame->GetMethod(), + self, + false, + false); if (LIKELY(c != nullptr)) { if (UNLIKELY(c->IsStringClass())) { gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); @@ -404,13 +407,13 @@ extern "C" size_t MterpAputObject(ShadowFrame* shadow_frame, uint32_t inst_data) REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(dex_pc_ptr); - Object* a = shadow_frame->GetVRegReference(inst->VRegB_23x()); + mirror::Object* a = shadow_frame->GetVRegReference(inst->VRegB_23x()); if (UNLIKELY(a == nullptr)) { return false; } int32_t index = shadow_frame->GetVReg(inst->VRegC_23x()); - Object* val = shadow_frame->GetVRegReference(inst->VRegA_23x(inst_data)); - ObjectArray<Object>* array = a->AsObjectArray<Object>(); + mirror::Object* val = shadow_frame->GetVRegReference(inst->VRegA_23x(inst_data)); + mirror::ObjectArray<mirror::Object>* array = a->AsObjectArray<mirror::Object>(); if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) { array->SetWithoutChecks<false>(index, val); return true; @@ -442,7 +445,7 @@ extern "C" size_t MterpNewArray(ShadowFrame* shadow_frame, REQUIRES_SHARED(Locks::mutator_lock_) { const Instruction* inst = Instruction::At(dex_pc_ptr); int32_t length = shadow_frame->GetVReg(inst->VRegB_22c(inst_data)); - Object* obj = AllocArrayFromCode<false, true>( + mirror::Object* obj = AllocArrayFromCode<false, true>( inst->VRegC_22c(), length, shadow_frame->GetMethod(), self, Runtime::Current()->GetHeap()->GetCurrentAllocator()); if (UNLIKELY(obj == nullptr)) { @@ -678,7 +681,7 @@ extern "C" mirror::Object* artAGetObjectFromMterp(mirror::Object* arr, int32_t i ThrowNullPointerExceptionFromInterpreter(); return nullptr; } - ObjectArray<Object>* array = arr->AsObjectArray<Object>(); + mirror::ObjectArray<mirror::Object>* array = arr->AsObjectArray<mirror::Object>(); if (LIKELY(array->CheckIsValidIndex(index))) { return array->GetWithoutChecks(index); } else { diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 5a62bd77d5..75b91b1885 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -564,7 +564,7 @@ void UnstartedRuntime::UnstartedClassLoaderGetResourceAsStream( this_classloader_class.Get()) { AbortTransactionOrFail(self, "Unsupported classloader type %s for getResourceAsStream", - Class::PrettyClass(this_classloader_class.Get()).c_str()); + mirror::Class::PrettyClass(this_classloader_class.Get()).c_str()); return; } } @@ -608,10 +608,11 @@ static void PrimitiveArrayCopy(Thread* self, int32_t length) REQUIRES_SHARED(Locks::mutator_lock_) { if (src_array->GetClass()->GetComponentType() != dst_array->GetClass()->GetComponentType()) { - AbortTransactionOrFail(self, "Types mismatched in arraycopy: %s vs %s.", - Class::PrettyDescriptor( + AbortTransactionOrFail(self, + "Types mismatched in arraycopy: %s vs %s.", + mirror::Class::PrettyDescriptor( src_array->GetClass()->GetComponentType()).c_str(), - Class::PrettyDescriptor( + mirror::Class::PrettyDescriptor( dst_array->GetClass()->GetComponentType()).c_str()); return; } @@ -677,9 +678,9 @@ void UnstartedRuntime::UnstartedSystemArraycopy( GetComponentType(); if (trg_type->IsPrimitiveInt()) { AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s", - Class::PrettyDescriptor( + mirror::Class::PrettyDescriptor( src_array->GetClass()->GetComponentType()).c_str(), - Class::PrettyDescriptor( + mirror::Class::PrettyDescriptor( dst_array->GetClass()->GetComponentType()).c_str()); return; } diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 953b1c0540..4c1006360b 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -683,7 +683,7 @@ void Jit::MethodEntered(Thread* thread, ArtMethod* method) { } } -void Jit::InvokeVirtualOrInterface(mirror::Object* this_object, +void Jit::InvokeVirtualOrInterface(ObjPtr<mirror::Object> this_object, ArtMethod* caller, uint32_t dex_pc, ArtMethod* callee ATTRIBUTE_UNUSED) { diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h index d3178b0b37..a7824378c2 100644 --- a/runtime/jit/jit.h +++ b/runtime/jit/jit.h @@ -22,9 +22,10 @@ #include "base/macros.h" #include "base/mutex.h" #include "base/timing_logger.h" +#include "jit/profile_saver_options.h" +#include "obj_ptr.h" #include "object_callbacks.h" #include "offline_profiling_info.h" -#include "jit/profile_saver_options.h" #include "thread_pool.h" namespace art { @@ -114,7 +115,7 @@ class Jit { void AddSamples(Thread* self, ArtMethod* method, uint16_t samples, bool with_backedges) REQUIRES_SHARED(Locks::mutator_lock_); - void InvokeVirtualOrInterface(mirror::Object* this_object, + void InvokeVirtualOrInterface(ObjPtr<mirror::Object> this_object, ArtMethod* caller, uint32_t dex_pc, ArtMethod* callee) diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 2e70c9b43f..3bf9d94410 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -275,7 +275,7 @@ inline void Object::AssertReadBarrierPointer() const { } template<VerifyObjectFlags kVerifyFlags> -inline bool Object::VerifierInstanceOf(Class* klass) { +inline bool Object::VerifierInstanceOf(ObjPtr<Class> klass) { DCHECK(klass != nullptr); DCHECK(GetClass<kVerifyFlags>() != nullptr); return klass->IsInterface() || InstanceOf(klass); diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index f1ab72a989..886637be5c 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -119,7 +119,7 @@ class MANAGED LOCKABLE Object { // The verifier treats all interfaces as java.lang.Object and relies on runtime checks in // invoke-interface to detect incompatible interface types. template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> - bool VerifierInstanceOf(Class* klass) REQUIRES_SHARED(Locks::mutator_lock_); + bool VerifierInstanceOf(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> ALWAYS_INLINE bool InstanceOf(ObjPtr<Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); |