ObjPtr<>-ify UnstartedRuntime, fix 2 stale reference uses.
Test: Rely on TreeHugger.
Bug: 31113334
Change-Id: I35f76c3e3b94dfca18dbe67aba065a1270f4e5ee
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 0a186f4..4ca12fe 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 f23304c..048c6e4 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 @@
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 @@
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 5a50ec5..708a788 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 @@
}
}
+// 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 @@
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 67a0349..37234e1 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -543,24 +543,6 @@
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 5c7838c..2762629 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 1b39a74..d62f511 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 @@
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 @@
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 @@
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 @@
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 0000000..7eaad59
--- /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 d5451ff..f76b86c 100644
--- a/runtime/interpreter/shadow_frame.h
+++ b/runtime/interpreter/shadow_frame.h
@@ -37,6 +37,7 @@
class ArtMethod;
class ShadowFrame;
+template<class MirrorType> class ObjPtr;
class Thread;
union JValue;
@@ -245,18 +246,8 @@
}
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 0e429a6..7abb007 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -131,7 +131,7 @@
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 @@
}
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 @@
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 @@
// 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 @@
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 @@
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::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 @@
// 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 @@
}
// 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::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::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 fd43562..860de2c 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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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, 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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
};
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, 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 00a8c00..c4ac982 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 1d45aae..27de725 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 fce3d06..b6e3134 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 @@
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 44c819a..c755299 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 077aa33..ad08fa0 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 229238e..93127be 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 eada24d..51b3752 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"