diff options
author | 2018-05-22 15:33:48 +0100 | |
---|---|---|
committer | 2018-05-23 13:48:31 +0100 | |
commit | 6ec2a1bf1cbecf17546df780dd0ad769042e1874 (patch) | |
tree | 09f7430f020e04dc892ff2c2152bb773cd45c0dd | |
parent | 2d3065e6ca0bd707bc998b7d260bb8e8ec07cf87 (diff) |
ObjPtr<>-ify UnstartedRuntime, fix 2 stale reference uses.
Test: Rely on TreeHugger.
Bug: 31113334
Change-Id: I35f76c3e3b94dfca18dbe67aba065a1270f4e5ee
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 1 | ||||
-rw-r--r-- | runtime/interpreter/interpreter.cc | 5 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 21 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 18 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 17 | ||||
-rw-r--r-- | runtime/interpreter/mterp/mterp.cc | 9 | ||||
-rw-r--r-- | runtime/interpreter/shadow_frame-inl.h | 43 | ||||
-rw-r--r-- | runtime/interpreter/shadow_frame.h | 15 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 31 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime_test.cc | 83 | ||||
-rw-r--r-- | runtime/method_handles-inl.h | 74 | ||||
-rw-r--r-- | runtime/method_handles.cc | 1 | ||||
-rw-r--r-- | runtime/method_handles.h | 76 | ||||
-rw-r--r-- | runtime/mirror/var_handle.cc | 2 | ||||
-rw-r--r-- | runtime/quick_exception_handler.cc | 1 | ||||
-rw-r--r-- | runtime/stack.cc | 2 | ||||
-rw-r--r-- | runtime/thread.cc | 2 |
17 files changed, 229 insertions, 172 deletions
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 0a186f4dc5..4ca12fe472 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -33,6 +33,7 @@ #include "index_bss_mapping.h" #include "instrumentation.h" #include "interpreter/interpreter.h" +#include "interpreter/shadow_frame-inl.h" #include "jit/jit.h" #include "linear_alloc.h" #include "method_handles.h" diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index f23304c391..048c6e4d66 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -31,6 +31,7 @@ #include "mterp/mterp.h" #include "nativehelper/scoped_local_ref.h" #include "scoped_thread_state_change-inl.h" +#include "shadow_frame-inl.h" #include "stack.h" #include "thread-inl.h" #include "unstarted_runtime.h" @@ -419,7 +420,7 @@ void EnterInterpreterFromInvoke(Thread* self, size_t cur_reg = num_regs - num_ins; if (!method->IsStatic()) { CHECK(receiver != nullptr); - shadow_frame->SetVRegReference(cur_reg, receiver.Ptr()); + shadow_frame->SetVRegReference(cur_reg, receiver); ++cur_reg; } uint32_t shorty_len = 0; @@ -430,7 +431,7 @@ void EnterInterpreterFromInvoke(Thread* self, case 'L': { ObjPtr<mirror::Object> o = reinterpret_cast<StackReference<mirror::Object>*>(&args[arg_pos])->AsMirrorPtr(); - shadow_frame->SetVRegReference(cur_reg, o.Ptr()); + shadow_frame->SetVRegReference(cur_reg, o); break; } case 'J': case 'D': { diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 5a50ec5586..708a7884fa 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -34,6 +34,7 @@ #include "mirror/var_handle.h" #include "reflection-inl.h" #include "reflection.h" +#include "shadow_frame-inl.h" #include "stack.h" #include "thread-inl.h" #include "transaction.h" @@ -1428,6 +1429,24 @@ bool DoInvokeCustom(Thread* self, } } +// Assign register 'src_reg' from shadow_frame to register 'dest_reg' into new_shadow_frame. +static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFrame& shadow_frame, + size_t dest_reg, size_t src_reg) + 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); + 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.Ptr())) { + new_shadow_frame->SetVRegReference(dest_reg, o); + } else { + new_shadow_frame->SetVReg(dest_reg, src_value); + } +} + template <bool is_range> inline void CopyRegisters(ShadowFrame& caller_frame, ShadowFrame* callee_frame, @@ -1612,7 +1631,7 @@ static inline bool DoCallCommon(ArtMethod* called_method, return false; } } - new_shadow_frame->SetVRegReference(dest_reg, o.Ptr()); + new_shadow_frame->SetVRegReference(dest_reg, o); break; } // Handle doubles and longs. 2 consecutive virtual register slots. diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 67a0349d7a..37234e1462 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -543,24 +543,6 @@ static inline bool IsBackwardBranch(int32_t branch_offset) { return branch_offset <= 0; } -// Assign register 'src_reg' from shadow_frame to register 'dest_reg' into new_shadow_frame. -static inline void AssignRegister(ShadowFrame* new_shadow_frame, const ShadowFrame& shadow_frame, - size_t dest_reg, size_t src_reg) - 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); - 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.Ptr())) { - new_shadow_frame->SetVRegReference(dest_reg, o.Ptr()); - } else { - new_shadow_frame->SetVReg(dest_reg, src_value); - } -} - // The arg_offset is the offset to the first input register in the frame. void ArtInterpreterToCompiledCodeBridge(Thread* self, ArtMethod* caller, diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index 5c7838cd66..27626295c1 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -24,6 +24,7 @@ #include "jit/jit.h" #include "jvalue-inl.h" #include "safe_math.h" +#include "shadow_frame-inl.h" namespace art { namespace interpreter { @@ -299,7 +300,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { PREAMBLE(); 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.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception); self->ClearException(); inst = inst->Next_1xx(); break; @@ -514,7 +515,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { if (UNLIKELY(s == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s); inst = inst->Next_2xx(); } break; @@ -527,7 +528,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { if (UNLIKELY(s == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s); inst = inst->Next_3xx(); } break; @@ -542,7 +543,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { if (UNLIKELY(c == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c); inst = inst->Next_2xx(); } break; @@ -556,7 +557,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { if (UNLIKELY(mh == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh); inst = inst->Next_2xx(); } break; @@ -570,7 +571,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { if (UNLIKELY(mt == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt); inst = inst->Next_2xx(); } break; @@ -681,7 +682,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { HANDLE_PENDING_EXCEPTION(); break; } - shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj); inst = inst->Next_2xx(); } break; @@ -698,7 +699,7 @@ void ExecuteSwitchImplCpp(SwitchImplContext* ctx) { if (UNLIKELY(obj == nullptr)) { HANDLE_PENDING_EXCEPTION(); } else { - shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr()); + shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj); inst = inst->Next_2xx(); } break; diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index 1b39a7422d..d62f511ad5 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -24,6 +24,7 @@ #include "entrypoints/entrypoint_utils-inl.h" #include "interpreter/interpreter_common.h" #include "interpreter/interpreter_intrinsics.h" +#include "interpreter/shadow_frame-inl.h" namespace art { namespace interpreter { @@ -369,7 +370,7 @@ extern "C" size_t MterpConstString(uint32_t index, if (UNLIKELY(s == nullptr)) { return true; } - shadow_frame->SetVRegReference(tgt_vreg, s.Ptr()); + shadow_frame->SetVRegReference(tgt_vreg, s); return false; } @@ -386,7 +387,7 @@ extern "C" size_t MterpConstClass(uint32_t index, if (UNLIKELY(c == nullptr)) { return true; } - shadow_frame->SetVRegReference(tgt_vreg, c.Ptr()); + shadow_frame->SetVRegReference(tgt_vreg, c); return false; } @@ -399,7 +400,7 @@ extern "C" size_t MterpConstMethodHandle(uint32_t index, if (UNLIKELY(mh == nullptr)) { return true; } - shadow_frame->SetVRegReference(tgt_vreg, mh.Ptr()); + shadow_frame->SetVRegReference(tgt_vreg, mh); return false; } @@ -413,7 +414,7 @@ extern "C" size_t MterpConstMethodType(uint32_t index, if (UNLIKELY(mt == nullptr)) { return true; } - shadow_frame->SetVRegReference(tgt_vreg, mt.Ptr()); + shadow_frame->SetVRegReference(tgt_vreg, mt); return false; } diff --git a/runtime/interpreter/shadow_frame-inl.h b/runtime/interpreter/shadow_frame-inl.h new file mode 100644 index 0000000000..7eaad597d2 --- /dev/null +++ b/runtime/interpreter/shadow_frame-inl.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_INTERPRETER_SHADOW_FRAME_INL_H_ +#define ART_RUNTIME_INTERPRETER_SHADOW_FRAME_INL_H_ + +#include "shadow_frame.h" + +#include "obj_ptr-inl.h" + +namespace art { + +template<VerifyObjectFlags kVerifyFlags /*= kDefaultVerifyFlags*/> +inline void ShadowFrame::SetVRegReference(size_t i, ObjPtr<mirror::Object> val) + REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK_LT(i, NumberOfVRegs()); + if (kVerifyFlags & kVerifyWrites) { + VerifyObject(val); + } + ReadBarrier::MaybeAssertToSpaceInvariant(val.Ptr()); + uint32_t* vreg = &vregs_[i]; + reinterpret_cast<StackReference<mirror::Object>*>(vreg)->Assign(val); + if (HasReferenceArray()) { + References()[i].Assign(val); + } +} + +} // namespace art + +#endif // ART_RUNTIME_INTERPRETER_SHADOW_FRAME_INL_H_ diff --git a/runtime/interpreter/shadow_frame.h b/runtime/interpreter/shadow_frame.h index d5451ffded..f76b86c94f 100644 --- a/runtime/interpreter/shadow_frame.h +++ b/runtime/interpreter/shadow_frame.h @@ -37,6 +37,7 @@ class Object; class ArtMethod; class ShadowFrame; +template<class MirrorType> class ObjPtr; class Thread; union JValue; @@ -245,18 +246,8 @@ class ShadowFrame { } template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> - void SetVRegReference(size_t i, mirror::Object* val) REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK_LT(i, NumberOfVRegs()); - if (kVerifyFlags & kVerifyWrites) { - VerifyObject(val); - } - ReadBarrier::MaybeAssertToSpaceInvariant(val); - uint32_t* vreg = &vregs_[i]; - reinterpret_cast<StackReference<mirror::Object>*>(vreg)->Assign(val); - if (HasReferenceArray()) { - References()[i].Assign(val); - } - } + void SetVRegReference(size_t i, ObjPtr<mirror::Object> val) + REQUIRES_SHARED(Locks::mutator_lock_); void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_) { DCHECK(method != nullptr); diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 0e429a63f6..7abb007838 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -131,7 +131,7 @@ static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> class std::string descriptor(DotToDescriptor(className->ToModifiedUtf8().c_str())); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - mirror::Class* found = class_linker->FindClass(self, descriptor.c_str(), class_loader); + ObjPtr<mirror::Class> found = class_linker->FindClass(self, descriptor.c_str(), class_loader); if (found == nullptr && abort_if_not_found) { if (!self->IsExceptionPending()) { AbortTransactionOrFail(self, "%s failed in un-started runtime for class: %s", @@ -142,7 +142,7 @@ static void UnstartedRuntimeFindClass(Thread* self, Handle<mirror::String> class } if (found != nullptr && initialize_class) { StackHandleScope<1> hs(self); - Handle<mirror::Class> h_class(hs.NewHandle(found)); + HandleWrapperObjPtr<mirror::Class> h_class = hs.NewHandleWrapper(&found); if (!class_linker->EnsureInitialized(self, h_class, true, true)) { CHECK(self->IsExceptionPending()); return; @@ -269,8 +269,7 @@ void UnstartedRuntime::UnstartedClassNewInstance( AbortTransactionOrFail(self, "Null-pointer in Class.newInstance."); return; } - mirror::Class* klass = param->AsClass(); - Handle<mirror::Class> h_klass(hs.NewHandle(klass)); + Handle<mirror::Class> h_klass(hs.NewHandle(param->AsClass())); // Check that it's not null. if (h_klass == nullptr) { @@ -280,7 +279,7 @@ void UnstartedRuntime::UnstartedClassNewInstance( // If we're in a transaction, class must not be finalizable (it or a superclass has a finalizer). if (Runtime::Current()->IsActiveTransaction()) { - if (h_klass.Get()->IsFinalizable()) { + if (h_klass->IsFinalizable()) { AbortTransactionF(self, "Class for newInstance is finalizable: '%s'", h_klass->PrettyClass().c_str()); return; @@ -299,7 +298,7 @@ void UnstartedRuntime::UnstartedClassNewInstance( cons = nullptr; } if (cons != nullptr) { - Handle<mirror::Object> h_obj(hs.NewHandle(klass->AllocObject(self))); + Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(self))); CHECK(h_obj != nullptr); // We don't expect OOM at compile-time. EnterInterpreterFromInvoke(self, cons, h_obj.Get(), nullptr, nullptr); if (!self->IsExceptionPending()) { @@ -323,8 +322,8 @@ void UnstartedRuntime::UnstartedClassGetDeclaredField( Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail // going the reflective Dex way. - mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); - mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); + ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); + ObjPtr<mirror::String> name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); ArtField* found = nullptr; for (ArtField& field : klass->GetIFields()) { if (name2->Equals(field.GetName())) { @@ -376,13 +375,13 @@ void UnstartedRuntime::UnstartedClassGetDeclaredField( void UnstartedRuntime::UnstartedClassGetDeclaredMethod( Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { // Special managed code cut-out to allow method lookup in a un-started runtime. - mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); + ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); if (klass == nullptr) { ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual); return; } - mirror::String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); - mirror::ObjectArray<mirror::Class>* args = + ObjPtr<mirror::String> name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); + ObjPtr<mirror::ObjectArray<mirror::Class>> args = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<mirror::Class>(); Runtime* runtime = Runtime::Current(); bool transaction = runtime->IsActiveTransaction(); @@ -414,7 +413,7 @@ void UnstartedRuntime::UnstartedClassGetDeclaredMethod( // Special managed code cut-out to allow constructor lookup in a un-started runtime. void UnstartedRuntime::UnstartedClassGetDeclaredConstructor( Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) { - mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); + ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); if (klass == nullptr) { ThrowNullPointerExceptionForMethodAccess(shadow_frame->GetMethod(), InvokeType::kVirtual); return; @@ -830,12 +829,12 @@ void UnstartedRuntime::UnstartedSystemArraycopy( } // Type checking. - mirror::Class* src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()-> + ObjPtr<mirror::Class> src_type = shadow_frame->GetVRegReference(arg_offset)->GetClass()-> GetComponentType(); if (!src_type->IsPrimitive()) { // Check that the second type is not primitive. - mirror::Class* trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()-> + ObjPtr<mirror::Class> trg_type = shadow_frame->GetVRegReference(arg_offset + 2)->GetClass()-> GetComponentType(); if (trg_type->IsPrimitiveInt()) { AbortTransactionOrFail(self, "Type mismatch in arraycopy: %s vs %s", @@ -1894,7 +1893,7 @@ void UnstartedRuntime::UnstartedJNIUnsafePutObject( void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType( Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) { - mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass(); + ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass(); Primitive::Type primitive_type = component->GetPrimitiveType(); result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value()); } @@ -1902,7 +1901,7 @@ void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType( void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType( Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) { - mirror::Class* component = reinterpret_cast<mirror::Object*>(args[0])->AsClass(); + ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass(); Primitive::Type primitive_type = component->GetPrimitiveType(); result->SetI(Primitive::ComponentSize(primitive_type)); } diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc index fd435627bf..860de2c28b 100644 --- a/runtime/interpreter/unstarted_runtime_test.cc +++ b/runtime/interpreter/unstarted_runtime_test.cc @@ -35,6 +35,7 @@ #include "mirror/string-inl.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" +#include "shadow_frame-inl.h" #include "thread.h" #include "transaction.h" @@ -82,7 +83,7 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size // of three everywhere. That is enough to test all cases. - static mirror::ObjectArray<mirror::Object>* CreateObjectArray( + static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray( Thread* self, ObjPtr<mirror::Class> component_type, const StackHandleScope<3>& data) @@ -98,10 +99,10 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { result->Set(static_cast<int32_t>(i), data.GetReference(i)); CHECK(!self->IsExceptionPending()); } - return result.Ptr(); + return result; } - static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array, + static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array, const StackHandleScope<3>& data) REQUIRES_SHARED(Locks::mutator_lock_) { CHECK_EQ(array->GetLength(), 3); @@ -114,9 +115,9 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { void RunArrayCopy(Thread* self, ShadowFrame* tmp, bool expect_exception, - mirror::ObjectArray<mirror::Object>* src, + ObjPtr<mirror::ObjectArray<mirror::Object>> src, int32_t src_pos, - mirror::ObjectArray<mirror::Object>* dst, + ObjPtr<mirror::ObjectArray<mirror::Object>> dst, int32_t dst_pos, int32_t length) REQUIRES_SHARED(Locks::mutator_lock_) { @@ -137,8 +138,8 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { void RunArrayCopy(Thread* self, ShadowFrame* tmp, bool expect_exception, - mirror::Class* src_component_class, - mirror::Class* dst_component_class, + ObjPtr<mirror::Class> src_component_class, + ObjPtr<mirror::Class> dst_component_class, const StackHandleScope<3>& src_data, int32_t src_pos, const StackHandleScope<3>& dst_data, @@ -366,7 +367,7 @@ TEST_F(UnstartedRuntimeTest, StringCharAt) { // TODO: Actual UTF. constexpr const char* base_string = "abcdefghijklmnop"; int32_t base_len = static_cast<int32_t>(strlen(base_string)); - mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); + ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); JValue result; ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); @@ -386,7 +387,7 @@ TEST_F(UnstartedRuntimeTest, StringCharAt) { TEST_F(UnstartedRuntimeTest, StringInit) { Thread* self = Thread::Current(); ScopedObjectAccess soa(self); - mirror::Class* klass = mirror::String::GetJavaLangString(); + ObjPtr<mirror::Class> klass = mirror::String::GetJavaLangString(); ArtMethod* method = klass->FindConstructor("(Ljava/lang/String;)V", Runtime::Current()->GetClassLinker()->GetImagePointerSize()); @@ -398,10 +399,13 @@ TEST_F(UnstartedRuntimeTest, StringInit) { JValue result; ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); const char* base_string = "hello_world"; - mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); - mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); - shadow_frame->SetVRegReference(0, reference_empty_string); - shadow_frame->SetVRegReference(1, string_arg); + StackHandleScope<2> hs(self); + Handle<mirror::String> string_arg = + hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string)); + Handle<mirror::String> reference_empty_string = + hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "")); + shadow_frame->SetVRegReference(0, reference_empty_string.Get()); + shadow_frame->SetVRegReference(1, string_arg.Get()); interpreter::DoCall<false, false>(method, self, @@ -409,7 +413,7 @@ TEST_F(UnstartedRuntimeTest, StringInit) { Instruction::At(inst_data), inst_data[0], &result); - mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); + ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL()); EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); if (string_arg->IsCompressed() && string_result->IsCompressed()) { @@ -442,7 +446,7 @@ TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we // allocate. - StackHandleScope<2> hs_misc(self); + StackHandleScope<3> hs_misc(self); Handle<mirror::Class> object_class( hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); @@ -461,10 +465,10 @@ TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); - mirror::ObjectArray<mirror::Object>* class_as_array = - reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); - RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); - RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); + Handle<mirror::ObjectArray<mirror::Object>> class_as_array = + hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get())); + RunArrayCopy(self, tmp, true, class_as_array.Get(), 0, array.Get(), 0, 0); + RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array.Get(), 0, 0); ShadowFrame::DeleteDeoptimizedFrame(tmp); } @@ -897,7 +901,7 @@ TEST_F(UnstartedRuntimeTest, IsAnonymousClass) { JValue result; ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); - mirror::Class* class_klass = mirror::Class::GetJavaLangClass(); + ObjPtr<mirror::Class> class_klass = mirror::Class::GetJavaLangClass(); shadow_frame->SetVRegReference(0, class_klass); UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); EXPECT_EQ(result.GetZ(), 0); @@ -906,7 +910,7 @@ TEST_F(UnstartedRuntimeTest, IsAnonymousClass) { StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader( hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); - mirror::Class* c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader); + ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader); ASSERT_TRUE(c != nullptr); shadow_frame->SetVRegReference(0, c); UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); @@ -1042,7 +1046,7 @@ TEST_F(UnstartedRuntimeTest, FloatConversion) { Instruction::At(inst_data), inst_data[0], &result); - ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL()); + ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL()); ASSERT_TRUE(string_result != nullptr); std::string mod_utf = string_result->ToModifiedUtf8(); @@ -1138,7 +1142,7 @@ class UnstartedClassForNameTest : public UnstartedRuntimeTest { ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); for (const char* name : kTestCases) { - mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name); + ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name); CHECK(name_string != nullptr); if (in_transaction) { @@ -1213,8 +1217,10 @@ class UnstartedClassForNameTest : public UnstartedRuntimeTest { }; TEST_F(UnstartedClassForNameTest, ClassForName) { - auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) - REQUIRES_SHARED(Locks::mutator_lock_) { + auto runner = [](Thread* self, + ShadowFrame* shadow_frame, + ObjPtr<mirror::String> name, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { shadow_frame->SetVRegReference(0, name); UnstartedClassForName(self, shadow_frame, result, 0); }; @@ -1222,8 +1228,10 @@ TEST_F(UnstartedClassForNameTest, ClassForName) { } TEST_F(UnstartedClassForNameTest, ClassForNameLong) { - auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) - REQUIRES_SHARED(Locks::mutator_lock_) { + auto runner = [](Thread* self, + ShadowFrame* shadow_frame, + ObjPtr<mirror::String> name, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { shadow_frame->SetVRegReference(0, name); shadow_frame->SetVReg(1, 0); shadow_frame->SetVRegReference(2, nullptr); @@ -1239,8 +1247,10 @@ TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) { StackHandleScope<1> hs(self); Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); - auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) - REQUIRES_SHARED(Locks::mutator_lock_) { + auto runner = [&](Thread* th, + ShadowFrame* shadow_frame, + ObjPtr<mirror::String> name, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { shadow_frame->SetVRegReference(0, name); shadow_frame->SetVReg(1, 0); shadow_frame->SetVRegReference(2, boot_cp.Get()); @@ -1256,7 +1266,10 @@ TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) { StackHandleScope<1> hs(self); Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); - auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) + auto runner = [&](Thread* th, + ShadowFrame* shadow_frame, + ObjPtr<mirror::String> name, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { shadow_frame->SetVRegReference(0, name); shadow_frame->SetVReg(1, 0); @@ -1277,8 +1290,10 @@ TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) { Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>( self->DecodeJObject(path_jobj)->AsClassLoader()); - auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) - REQUIRES_SHARED(Locks::mutator_lock_) { + auto runner = [&](Thread* th, + ShadowFrame* shadow_frame, + ObjPtr<mirror::String> name, + JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { shadow_frame->SetVRegReference(0, name); shadow_frame->SetVReg(1, 0); shadow_frame->SetVRegReference(2, path_cp.Get()); @@ -1376,7 +1391,7 @@ TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) { // Should have the right string. ObjPtr<mirror::String> result_msg = reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage(); - EXPECT_EQ(input.Get(), result_msg.Ptr()); + EXPECT_OBJ_PTR_EQ(input.Get(), result_msg); ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); } @@ -1393,7 +1408,7 @@ TEST_F(UnstartedRuntimeTest, IdentityHashCode) { ASSERT_FALSE(self->IsExceptionPending()); ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd"); - tmp->SetVRegReference(0, str.Ptr()); + tmp->SetVRegReference(0, str); UnstartedSystemIdentityHashCode(self, tmp, &result, 0); EXPECT_NE(0, result.GetI()); EXPECT_EQ(str->IdentityHashCode(), result.GetI()); diff --git a/runtime/method_handles-inl.h b/runtime/method_handles-inl.h index 00a8c00880..c4ac982576 100644 --- a/runtime/method_handles-inl.h +++ b/runtime/method_handles-inl.h @@ -22,6 +22,7 @@ #include "common_throws.h" #include "dex/dex_instruction.h" #include "interpreter/interpreter_common.h" +#include "interpreter/shadow_frame-inl.h" #include "jvalue-inl.h" #include "mirror/class.h" #include "mirror/method_type.h" @@ -31,6 +32,79 @@ namespace art { +// A convenience class that allows for iteration through a list of +// input argument registers. This is used to iterate over input +// arguments while performing standard argument conversions. +class ShadowFrameGetter { + public: + ShadowFrameGetter(const ShadowFrame& shadow_frame, + const InstructionOperands* const operands, + size_t operand_index = 0u) + : shadow_frame_(shadow_frame), operands_(operands), operand_index_(operand_index) {} + + ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) { + return shadow_frame_.GetVReg(Next()); + } + + ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) { + return shadow_frame_.GetVRegLong(NextLong()); + } + + ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) { + return shadow_frame_.GetVRegReference(Next()); + } + + private: + uint32_t Next() { + const uint32_t next = operands_->GetOperand(operand_index_); + operand_index_ += 1; + return next; + } + + uint32_t NextLong() { + const uint32_t next = operands_->GetOperand(operand_index_); + operand_index_ += 2; + return next; + } + + const ShadowFrame& shadow_frame_; + const InstructionOperands* const operands_; // the set of register operands to read + size_t operand_index_; // the next register operand to read from frame +}; + +// A convenience class that allows values to be written to a given shadow frame, +// starting at location |first_dst_reg|. +class ShadowFrameSetter { + public: + ShadowFrameSetter(ShadowFrame* shadow_frame, size_t first_dst_reg) + : shadow_frame_(shadow_frame), arg_index_(first_dst_reg) {} + + ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs()); + shadow_frame_->SetVReg(arg_index_++, value); + } + + ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value) + REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs()); + shadow_frame_->SetVRegReference(arg_index_++, value); + } + + ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs()); + shadow_frame_->SetVRegLong(arg_index_, value); + arg_index_ += 2; + } + + ALWAYS_INLINE bool Done() const { + return arg_index_ == shadow_frame_->NumberOfVRegs(); + } + + private: + ShadowFrame* shadow_frame_; + size_t arg_index_; +}; + inline bool ConvertArgumentValue(Handle<mirror::MethodType> callsite_type, Handle<mirror::MethodType> callee_type, ObjPtr<mirror::Class> from_class, diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index 1d45aaeb2e..27de72533c 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -19,6 +19,7 @@ #include "android-base/stringprintf.h" #include "common_dex_operations.h" +#include "interpreter/shadow_frame-inl.h" #include "jvalue-inl.h" #include "mirror/emulated_stack_frame.h" #include "mirror/method_handle_impl-inl.h" diff --git a/runtime/method_handles.h b/runtime/method_handles.h index fce3d06639..b6e31345e1 100644 --- a/runtime/method_handles.h +++ b/runtime/method_handles.h @@ -21,12 +21,13 @@ #include "dex/dex_instruction.h" #include "handle.h" -#include "interpreter/shadow_frame.h" #include "jvalue.h" #include "mirror/class.h" namespace art { +class ShadowFrame; + namespace mirror { class MethodHandle; class MethodType; @@ -126,79 +127,6 @@ bool PerformConversions(Thread* self, int32_t start_index, int32_t end_index) REQUIRES_SHARED(Locks::mutator_lock_); -// A convenience class that allows for iteration through a list of -// input argument registers. This is used to iterate over input -// arguments while performing standard argument conversions. -class ShadowFrameGetter { - public: - ShadowFrameGetter(const ShadowFrame& shadow_frame, - const InstructionOperands* const operands, - size_t operand_index = 0u) - : shadow_frame_(shadow_frame), operands_(operands), operand_index_(operand_index) {} - - ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) { - return shadow_frame_.GetVReg(Next()); - } - - ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) { - return shadow_frame_.GetVRegLong(NextLong()); - } - - ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) { - return shadow_frame_.GetVRegReference(Next()); - } - - private: - uint32_t Next() { - const uint32_t next = operands_->GetOperand(operand_index_); - operand_index_ += 1; - return next; - } - - uint32_t NextLong() { - const uint32_t next = operands_->GetOperand(operand_index_); - operand_index_ += 2; - return next; - } - - const ShadowFrame& shadow_frame_; - const InstructionOperands* const operands_; // the set of register operands to read - size_t operand_index_; // the next register operand to read from frame -}; - -// A convenience class that allows values to be written to a given shadow frame, -// starting at location |first_dst_reg|. -class ShadowFrameSetter { - public: - ShadowFrameSetter(ShadowFrame* shadow_frame, size_t first_dst_reg) - : shadow_frame_(shadow_frame), arg_index_(first_dst_reg) {} - - ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs()); - shadow_frame_->SetVReg(arg_index_++, value); - } - - ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value) - REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs()); - shadow_frame_->SetVRegReference(arg_index_++, value.Ptr()); - } - - ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) { - DCHECK_LT(arg_index_, shadow_frame_->NumberOfVRegs()); - shadow_frame_->SetVRegLong(arg_index_, value); - arg_index_ += 2; - } - - ALWAYS_INLINE bool Done() const { - return arg_index_ == shadow_frame_->NumberOfVRegs(); - } - - private: - ShadowFrame* shadow_frame_; - size_t arg_index_; -}; - bool MethodHandleInvoke(Thread* self, ShadowFrame& shadow_frame, Handle<mirror::MethodHandle> method_handle, diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc index 44c819aaf7..c755299a79 100644 --- a/runtime/mirror/var_handle.cc +++ b/runtime/mirror/var_handle.cc @@ -24,7 +24,7 @@ #include "intrinsics_enum.h" #include "jni/jni_internal.h" #include "jvalue-inl.h" -#include "method_handles.h" +#include "method_handles-inl.h" #include "method_type.h" #include "well_known_classes.h" diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 077aa33925..ad08fa0fa9 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -26,6 +26,7 @@ #include "entrypoints/quick/quick_entrypoints_enum.h" #include "entrypoints/runtime_asm_entrypoints.h" #include "handle_scope-inl.h" +#include "interpreter/shadow_frame-inl.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "mirror/class-inl.h" diff --git a/runtime/stack.cc b/runtime/stack.cc index 229238e0f7..93127bea29 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -28,7 +28,7 @@ #include "entrypoints/runtime_asm_entrypoints.h" #include "gc/space/image_space.h" #include "gc/space/space-inl.h" -#include "interpreter/shadow_frame.h" +#include "interpreter/shadow_frame-inl.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "linear_alloc.h" diff --git a/runtime/thread.cc b/runtime/thread.cc index eada24d257..51b37527f7 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -63,7 +63,7 @@ #include "handle_scope-inl.h" #include "indirect_reference_table-inl.h" #include "interpreter/interpreter.h" -#include "interpreter/shadow_frame.h" +#include "interpreter/shadow_frame-inl.h" #include "java_frame_root_info.h" #include "jni/java_vm_ext.h" #include "jni/jni_internal.h" |