summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2020-05-04 15:37:29 +0100
committer Vladimir Marko <vmarko@google.com> 2020-05-05 08:05:24 +0000
commitb6f4c79b06bb97651a7be1ac828d18ed18356603 (patch)
treeef0bbb1281f6d4785e60f26cb420646c83eb6f6d
parent3971661c74a9b4635d9744f72f3b053c820067c9 (diff)
Clean up Constructor/Method/Field construction.
Simplify the code by ignoring active transactions. Writing to fields of a newly allocated object does not need to be recorded as aborting the transaction removes all references to the new object and it's unnecessary to roll back writes to unreachable object's fields. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: aosp_taimen-userdebug boots. Change-Id: Ib5cd60c003d2ad3e6a246ff86d6b9288428c60ee
-rw-r--r--runtime/dex/dex_file_annotations.cc42
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc2
-rw-r--r--runtime/interpreter/unstarted_runtime.cc76
-rw-r--r--runtime/interpreter/unstarted_runtime_test.cc18
-rw-r--r--runtime/jni/jni_internal.cc5
-rw-r--r--runtime/mirror/class.cc44
-rw-r--r--runtime/mirror/class.h4
-rw-r--r--runtime/mirror/executable.cc26
-rw-r--r--runtime/mirror/executable.h12
-rw-r--r--runtime/mirror/field-inl.h30
-rw-r--r--runtime/mirror/field.h51
-rw-r--r--runtime/mirror/method.cc24
-rw-r--r--runtime/mirror/method.h4
-rw-r--r--runtime/native/java_lang_Class.cc14
-rw-r--r--runtime/native/java_lang_invoke_MethodHandleImpl.cc13
-rw-r--r--runtime/proxy_test.cc8
-rw-r--r--runtime/proxy_test.h8
17 files changed, 150 insertions, 231 deletions
diff --git a/runtime/dex/dex_file_annotations.cc b/runtime/dex/dex_file_annotations.cc
index 24b3a3e5fe..99c56a1e3a 100644
--- a/runtime/dex/dex_file_annotations.cc
+++ b/runtime/dex/dex_file_annotations.cc
@@ -525,21 +525,13 @@ bool ProcessAnnotationValue(const ClassData& klass,
PointerSize pointer_size = class_linker->GetImagePointerSize();
set_object = true;
if (method->IsConstructor()) {
- if (pointer_size == PointerSize::k64) {
- element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k64,
- kTransactionActive>(self, method);
- } else {
- element_object = mirror::Constructor::CreateFromArtMethod<PointerSize::k32,
- kTransactionActive>(self, method);
- }
+ element_object = (pointer_size == PointerSize::k64)
+ ? mirror::Constructor::CreateFromArtMethod<PointerSize::k64>(self, method)
+ : mirror::Constructor::CreateFromArtMethod<PointerSize::k32>(self, method);
} else {
- if (pointer_size == PointerSize::k64) {
- element_object = mirror::Method::CreateFromArtMethod<PointerSize::k64,
- kTransactionActive>(self, method);
- } else {
- element_object = mirror::Method::CreateFromArtMethod<PointerSize::k32,
- kTransactionActive>(self, method);
- }
+ element_object = (pointer_size == PointerSize::k64)
+ ? mirror::Method::CreateFromArtMethod<PointerSize::k64>(self, method)
+ : mirror::Method::CreateFromArtMethod<PointerSize::k32>(self, method);
}
if (element_object == nullptr) {
return false;
@@ -562,13 +554,9 @@ bool ProcessAnnotationValue(const ClassData& klass,
}
set_object = true;
PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
- if (pointer_size == PointerSize::k64) {
- element_object = mirror::Field::CreateFromArtField<PointerSize::k64,
- kTransactionActive>(self, field, true);
- } else {
- element_object = mirror::Field::CreateFromArtField<PointerSize::k32,
- kTransactionActive>(self, field, true);
- }
+ element_object = (pointer_size == PointerSize::k64)
+ ? mirror::Field::CreateFromArtField<PointerSize::k64>(self, field, true)
+ : mirror::Field::CreateFromArtField<PointerSize::k32>(self, field, true);
if (element_object == nullptr) {
return false;
}
@@ -743,15 +731,9 @@ ObjPtr<mirror::Object> CreateAnnotationMember(const ClassData& klass,
ObjPtr<mirror::Class> annotation_member_class =
WellKnownClasses::ToClass(WellKnownClasses::libcore_reflect_AnnotationMember);
Handle<mirror::Object> new_member(hs.NewHandle(annotation_member_class->AllocObject(self)));
- ObjPtr<mirror::Method> method_obj_ptr;
- DCHECK(!Runtime::Current()->IsActiveTransaction());
- if (pointer_size == PointerSize::k64) {
- method_obj_ptr = mirror::Method::CreateFromArtMethod<PointerSize::k64, false>(
- self, annotation_method);
- } else {
- method_obj_ptr = mirror::Method::CreateFromArtMethod<PointerSize::k32, false>(
- self, annotation_method);
- }
+ ObjPtr<mirror::Method> method_obj_ptr = (pointer_size == PointerSize::k64)
+ ? mirror::Method::CreateFromArtMethod<PointerSize::k64>(self, annotation_method)
+ : mirror::Method::CreateFromArtMethod<PointerSize::k32>(self, annotation_method);
Handle<mirror::Method> method_object(hs.NewHandle(method_obj_ptr));
if (new_member == nullptr || string_name == nullptr ||
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index b04f26eb5f..55be920ace 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -845,7 +845,7 @@ extern "C" uint64_t artQuickProxyInvokeHandler(
DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
DCHECK(!Runtime::Current()->IsActiveTransaction());
ObjPtr<mirror::Method> interface_reflect_method =
- mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), interface_method);
+ mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), interface_method);
if (interface_reflect_method == nullptr) {
soa.Self()->AssertPendingOOMException();
return 0;
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 5986982d7e..1bdffa3812 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -360,26 +360,10 @@ void UnstartedRuntime::UnstartedClassGetDeclaredField(
klass->PrettyDescriptor().c_str());
return;
}
- Runtime* runtime = Runtime::Current();
- PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
- ObjPtr<mirror::Field> field;
- if (runtime->IsActiveTransaction()) {
- if (pointer_size == PointerSize::k64) {
- field = mirror::Field::CreateFromArtField<PointerSize::k64, true>(
- self, found, true);
- } else {
- field = mirror::Field::CreateFromArtField<PointerSize::k32, true>(
- self, found, true);
- }
- } else {
- if (pointer_size == PointerSize::k64) {
- field = mirror::Field::CreateFromArtField<PointerSize::k64, false>(
- self, found, true);
- } else {
- field = mirror::Field::CreateFromArtField<PointerSize::k32, false>(
- self, found, true);
- }
- }
+ PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
+ ObjPtr<mirror::Field> field = (pointer_size == PointerSize::k64)
+ ? mirror::Field::CreateFromArtField<PointerSize::k64>(self, found, true)
+ : mirror::Field::CreateFromArtField<PointerSize::k32>(self, found, true);
result->SetL(field);
}
@@ -395,28 +379,13 @@ void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
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();
- PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
+ PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
auto fn_hiddenapi_access_context = GetHiddenapiAccessContextFunction(shadow_frame);
- ObjPtr<mirror::Method> method;
- if (transaction) {
- if (pointer_size == PointerSize::k64) {
- method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
- self, klass, name, args, fn_hiddenapi_access_context);
- } else {
- method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
- self, klass, name, args, fn_hiddenapi_access_context);
- }
- } else {
- if (pointer_size == PointerSize::k64) {
- method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
- self, klass, name, args, fn_hiddenapi_access_context);
- } else {
- method = mirror::Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
- self, klass, name, args, fn_hiddenapi_access_context);
- }
- }
+ ObjPtr<mirror::Method> method = (pointer_size == PointerSize::k64)
+ ? mirror::Class::GetDeclaredMethodInternal<PointerSize::k64>(
+ self, klass, name, args, fn_hiddenapi_access_context)
+ : mirror::Class::GetDeclaredMethodInternal<PointerSize::k32>(
+ self, klass, name, args, fn_hiddenapi_access_context);
if (method != nullptr && ShouldDenyAccessToMember(method->GetArtMethod(), shadow_frame)) {
method = nullptr;
}
@@ -433,27 +402,10 @@ void UnstartedRuntime::UnstartedClassGetDeclaredConstructor(
}
ObjPtr<mirror::ObjectArray<mirror::Class>> args =
shadow_frame->GetVRegReference(arg_offset + 1)->AsObjectArray<mirror::Class>();
- Runtime* runtime = Runtime::Current();
- bool transaction = runtime->IsActiveTransaction();
- PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
- ObjPtr<mirror::Constructor> constructor;
- if (transaction) {
- if (pointer_size == PointerSize::k64) {
- constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
- true>(self, klass, args);
- } else {
- constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
- true>(self, klass, args);
- }
- } else {
- if (pointer_size == PointerSize::k64) {
- constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64,
- false>(self, klass, args);
- } else {
- constructor = mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32,
- false>(self, klass, args);
- }
- }
+ PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
+ ObjPtr<mirror::Constructor> constructor = (pointer_size == PointerSize::k64)
+ ? mirror::Class::GetDeclaredConstructorInternal<PointerSize::k64>(self, klass, args)
+ : mirror::Class::GetDeclaredConstructorInternal<PointerSize::k32>(self, klass, args);
if (constructor != nullptr &&
ShouldDenyAccessToMember(constructor->GetArtMethod(), shadow_frame)) {
constructor = nullptr;
diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc
index 4429f6371d..8020962c52 100644
--- a/runtime/interpreter/unstarted_runtime_test.cc
+++ b/runtime/interpreter/unstarted_runtime_test.cc
@@ -1322,19 +1322,13 @@ TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
// Find the constructor.
- ArtMethod* throw_cons = throw_class->FindConstructor(
- "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
+ PointerSize pointer_size = class_linker->GetImagePointerSize();
+ ArtMethod* throw_cons = throw_class->FindConstructor("(Ljava/lang/String;)V", pointer_size);
ASSERT_TRUE(throw_cons != nullptr);
- Handle<mirror::Constructor> cons;
- if (class_linker->GetImagePointerSize() == PointerSize::k64) {
- cons = hs.NewHandle(
- mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
- ASSERT_TRUE(cons != nullptr);
- } else {
- cons = hs.NewHandle(
- mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
- ASSERT_TRUE(cons != nullptr);
- }
+ Handle<mirror::Constructor> cons = hs.NewHandle((pointer_size == PointerSize::k64)
+ ? mirror::Constructor::CreateFromArtMethod<PointerSize::k64>(self, throw_cons)
+ : mirror::Constructor::CreateFromArtMethod<PointerSize::k32>(self, throw_cons));
+ ASSERT_TRUE(cons != nullptr);
Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
mirror::ObjectArray<mirror::Object>::Alloc(
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index b228d9910c..9bbde2334a 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -531,11 +531,10 @@ class JNI {
ArtMethod* m = jni::DecodeArtMethod(mid);
ObjPtr<mirror::Executable> method;
DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
- DCHECK(!Runtime::Current()->IsActiveTransaction());
if (m->IsConstructor()) {
- method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
+ method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), m);
} else {
- method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
+ method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), m);
}
return soa.AddLocalReference<jobject>(method);
}
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index a2d76cd7b4..b1c36abf8d 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -1453,7 +1453,7 @@ static bool IsMethodPreferredOver(ArtMethod* orig_method,
return false;
}
-template <PointerSize kPointerSize, bool kTransactionActive>
+template <PointerSize kPointerSize>
ObjPtr<Method> Class::GetDeclaredMethodInternal(
Thread* self,
ObjPtr<Class> klass,
@@ -1494,7 +1494,7 @@ ObjPtr<Method> Class::GetDeclaredMethodInternal(
bool m_hidden = hiddenapi::ShouldDenyAccessToMember(&m, fn_get_access_context, access_method);
if (!m_hidden && !m.IsSynthetic()) {
// Non-hidden, virtual, non-synthetic. Best possible result, exit early.
- return Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, &m);
+ return Method::CreateFromArtMethod<kPointerSize>(self, &m);
} else if (IsMethodPreferredOver(result, result_hidden, &m, m_hidden)) {
// Remember as potential result.
result = &m;
@@ -1533,7 +1533,7 @@ ObjPtr<Method> Class::GetDeclaredMethodInternal(
// Non-hidden, direct, non-synthetic. Any virtual result could only have been
// hidden, therefore this is the best possible match. Exit now.
DCHECK((result == nullptr) || result_hidden);
- return Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, &m);
+ return Method::CreateFromArtMethod<kPointerSize>(self, &m);
} else if (IsMethodPreferredOver(result, result_hidden, &m, m_hidden)) {
// Remember as potential result.
result = &m;
@@ -1543,40 +1543,26 @@ ObjPtr<Method> Class::GetDeclaredMethodInternal(
}
return result != nullptr
- ? Method::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, result)
+ ? Method::CreateFromArtMethod<kPointerSize>(self, result)
: nullptr;
}
template
-ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k32, false>(
+ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k32>(
Thread* self,
ObjPtr<Class> klass,
ObjPtr<String> name,
ObjPtr<ObjectArray<Class>> args,
const std::function<hiddenapi::AccessContext()>& fn_get_access_context);
template
-ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k32, true>(
- Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<String> name,
- ObjPtr<ObjectArray<Class>> args,
- const std::function<hiddenapi::AccessContext()>& fn_get_access_context);
-template
-ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k64, false>(
- Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<String> name,
- ObjPtr<ObjectArray<Class>> args,
- const std::function<hiddenapi::AccessContext()>& fn_get_access_context);
-template
-ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k64, true>(
+ObjPtr<Method> Class::GetDeclaredMethodInternal<PointerSize::k64>(
Thread* self,
ObjPtr<Class> klass,
ObjPtr<String> name,
ObjPtr<ObjectArray<Class>> args,
const std::function<hiddenapi::AccessContext()>& fn_get_access_context);
-template <PointerSize kPointerSize, bool kTransactionActive>
+template <PointerSize kPointerSize>
ObjPtr<Constructor> Class::GetDeclaredConstructorInternal(
Thread* self,
ObjPtr<Class> klass,
@@ -1584,29 +1570,19 @@ ObjPtr<Constructor> Class::GetDeclaredConstructorInternal(
StackHandleScope<1> hs(self);
ArtMethod* result = klass->GetDeclaredConstructor(self, hs.NewHandle(args), kPointerSize);
return result != nullptr
- ? Constructor::CreateFromArtMethod<kPointerSize, kTransactionActive>(self, result)
+ ? Constructor::CreateFromArtMethod<kPointerSize>(self, result)
: nullptr;
}
// Constructor::CreateFromArtMethod<kTransactionActive>(self, result)
template
-ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k32, false>(
- Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<ObjectArray<Class>> args);
-template
-ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k32, true>(
- Thread* self,
- ObjPtr<Class> klass,
- ObjPtr<ObjectArray<Class>> args);
-template
-ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k64, false>(
+ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k32>(
Thread* self,
ObjPtr<Class> klass,
ObjPtr<ObjectArray<Class>> args);
template
-ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k64, true>(
+ObjPtr<Constructor> Class::GetDeclaredConstructorInternal<PointerSize::k64>(
Thread* self,
ObjPtr<Class> klass,
ObjPtr<ObjectArray<Class>> args);
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 48e1c3c7be..9b6390e02d 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -740,7 +740,7 @@ class MANAGED Class final : public Object {
PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
- template <PointerSize kPointerSize, bool kTransactionActive>
+ template <PointerSize kPointerSize>
static ObjPtr<Method> GetDeclaredMethodInternal(
Thread* self,
ObjPtr<Class> klass,
@@ -749,7 +749,7 @@ class MANAGED Class final : public Object {
const std::function<hiddenapi::AccessContext()>& fn_get_access_context)
REQUIRES_SHARED(Locks::mutator_lock_);
- template <PointerSize kPointerSize, bool kTransactionActive>
+ template <PointerSize kPointerSize>
static ObjPtr<Constructor> GetDeclaredConstructorInternal(Thread* self,
ObjPtr<Class> klass,
ObjPtr<ObjectArray<Class>> args)
diff --git a/runtime/mirror/executable.cc b/runtime/mirror/executable.cc
index d2a2ec5a7e..3996f49e1a 100644
--- a/runtime/mirror/executable.cc
+++ b/runtime/mirror/executable.cc
@@ -22,22 +22,24 @@
namespace art {
namespace mirror {
-template <PointerSize kPointerSize, bool kTransactionActive>
-bool Executable::CreateFromArtMethod(ArtMethod* method) {
+template <PointerSize kPointerSize>
+void Executable::InitializeFromArtMethod(ArtMethod* method) {
+ // We're initializing a newly allocated object, so we do not need to record that under
+ // a transaction. If the transaction is aborted, the whole object shall be unreachable.
auto* interface_method = method->GetInterfaceMethodIfProxy(kPointerSize);
- SetArtMethod<kTransactionActive>(method);
- SetFieldObject<kTransactionActive>(DeclaringClassOffset(), method->GetDeclaringClass());
- SetFieldObject<kTransactionActive>(
+ SetArtMethod</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(method);
+ SetFieldObject</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ DeclaringClassOffset(), method->GetDeclaringClass());
+ SetFieldObject</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
DeclaringClassOfOverriddenMethodOffset(), interface_method->GetDeclaringClass());
- SetField32<kTransactionActive>(AccessFlagsOffset(), method->GetAccessFlags());
- SetField32<kTransactionActive>(DexMethodIndexOffset(), method->GetDexMethodIndex());
- return true;
+ SetField32</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ AccessFlagsOffset(), method->GetAccessFlags());
+ SetField32</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ DexMethodIndexOffset(), method->GetDexMethodIndex());
}
-template bool Executable::CreateFromArtMethod<PointerSize::k32, false>(ArtMethod* method);
-template bool Executable::CreateFromArtMethod<PointerSize::k32, true>(ArtMethod* method);
-template bool Executable::CreateFromArtMethod<PointerSize::k64, false>(ArtMethod* method);
-template bool Executable::CreateFromArtMethod<PointerSize::k64, true>(ArtMethod* method);
+template void Executable::InitializeFromArtMethod<PointerSize::k32>(ArtMethod* method);
+template void Executable::InitializeFromArtMethod<PointerSize::k64>(ArtMethod* method);
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/executable.h b/runtime/mirror/executable.h
index 750a16741d..6e072af1e5 100644
--- a/runtime/mirror/executable.h
+++ b/runtime/mirror/executable.h
@@ -32,11 +32,6 @@ namespace mirror {
// C++ mirror of java.lang.reflect.Executable.
class MANAGED Executable : public AccessibleObject {
public:
- // Called from Constructor::CreateFromArtMethod, Method::CreateFromArtMethod.
- template <PointerSize kPointerSize, bool kTransactionActive>
- bool CreateFromArtMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_)
- REQUIRES(!Roles::uninterruptible_);
-
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ArtMethod* GetArtMethod() REQUIRES_SHARED(Locks::mutator_lock_) {
return reinterpret_cast64<ArtMethod*>(GetField64<kVerifyFlags>(ArtMethodOffset()));
@@ -56,6 +51,13 @@ class MANAGED Executable : public AccessibleObject {
return MemberOffset(OFFSETOF_MEMBER(Executable, art_method_));
}
+ protected:
+ // Called from Constructor::CreateFromArtMethod, Method::CreateFromArtMethod.
+ template <PointerSize kPointerSize>
+ void InitializeFromArtMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Roles::uninterruptible_);
+
+
private:
uint16_t has_real_parameter_data_;
HeapReference<mirror::Class> declaring_class_;
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 8a9cec46ed..4f544c97d9 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -41,7 +41,7 @@ inline ObjPtr<mirror::Class> Field::GetType() {
return GetFieldObject<mirror::Class>(OFFSET_OF_OBJECT_MEMBER(Field, type_));
}
-template <PointerSize kPointerSize, bool kTransactionActive>
+template <PointerSize kPointerSize>
inline ObjPtr<mirror::Field> Field::CreateFromArtField(Thread* self,
ArtField* field,
bool force_resolve) {
@@ -86,27 +86,33 @@ inline ObjPtr<mirror::Field> Field::CreateFromArtField(Thread* self,
field->GetDexCache()->SetResolvedField(dex_field_index, field, kPointerSize);
}
}
- ret->SetType<kTransactionActive>(type.Get());
- ret->SetDeclaringClass<kTransactionActive>(field->GetDeclaringClass());
- ret->SetAccessFlags<kTransactionActive>(field->GetAccessFlags());
+ // We're initializing a newly allocated object, so we do not need to record that under
+ // a transaction. If the transaction is aborted, the whole object shall be unreachable.
+ ret->SetType</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(type.Get());
+ ret->SetDeclaringClass</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ field->GetDeclaringClass());
+ ret->SetAccessFlags</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ field->GetAccessFlags());
auto iter_range = field->IsStatic() ? field->GetDeclaringClass()->GetSFields()
: field->GetDeclaringClass()->GetIFields();
auto position = std::find_if(
iter_range.begin(), iter_range.end(), [&](const auto& f) { return &f == field; });
DCHECK(position != iter_range.end());
- ret->SetArtFieldIndex<kTransactionActive>(std::distance(iter_range.begin(), position));
- ret->SetOffset<kTransactionActive>(field->GetOffset().Int32Value());
+ ret->SetArtFieldIndex</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ std::distance(iter_range.begin(), position));
+ ret->SetOffset</*kTransactionActive=*/ false, /*kCheckTransaction=*/ false>(
+ field->GetOffset().Int32Value());
return ret.Get();
}
-template<bool kTransactionActive>
-inline void Field::SetDeclaringClass(ObjPtr<mirror::Class> c) {
- SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), c);
+template<bool kTransactionActive, bool kCheckTransaction>
+inline void Field::SetDeclaringClass(ObjPtr<Class> c) {
+ SetFieldObject<kTransactionActive, kCheckTransaction>(DeclaringClassOffset(), c);
}
-template<bool kTransactionActive>
-inline void Field::SetType(ObjPtr<mirror::Class> type) {
- SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, type_), type);
+template<bool kTransactionActive, bool kCheckTransaction>
+inline void Field::SetType(ObjPtr<Class> type) {
+ SetFieldObject<kTransactionActive, kCheckTransaction>(TypeOffset(), type);
}
} // namespace mirror
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index dd5ee7678e..f8419086ab 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -42,12 +42,6 @@ class MANAGED Field : public AccessibleObject {
ALWAYS_INLINE uint32_t GetArtFieldIndex() REQUIRES_SHARED(Locks::mutator_lock_) {
return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, art_field_index_));
}
- // Public for use by class redefinition code.
- template<bool kTransactionActive>
- void SetArtFieldIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_) {
- SetField32<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, art_field_index_), idx);
- }
-
ObjPtr<mirror::Class> GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -77,7 +71,7 @@ class MANAGED Field : public AccessibleObject {
ArtField* GetArtField() REQUIRES_SHARED(Locks::mutator_lock_);
- template <PointerSize kPointerSize, bool kTransactionActive = false>
+ template <PointerSize kPointerSize>
static ObjPtr<mirror::Field> CreateFromArtField(Thread* self,
ArtField* field,
bool force_resolve)
@@ -98,20 +92,45 @@ class MANAGED Field : public AccessibleObject {
int32_t art_field_index_;
int32_t offset_;
- template<bool kTransactionActive>
- void SetDeclaringClass(ObjPtr<mirror::Class> c) REQUIRES_SHARED(Locks::mutator_lock_);
+ static constexpr MemberOffset DeclaringClassOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_);
+ }
+
+ static constexpr MemberOffset TypeOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Field, type_);
+ }
+
+ static constexpr MemberOffset AccessFlagsOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Field, access_flags_);
+ }
+
+ static constexpr MemberOffset ArtFieldIndexOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Field, art_field_index_);
+ }
+
+ static constexpr MemberOffset OffsetOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Field, offset_);
+ }
+
+ template<bool kTransactionActive, bool kCheckTransaction = true>
+ void SetDeclaringClass(ObjPtr<Class> c) REQUIRES_SHARED(Locks::mutator_lock_);
+
+ template<bool kTransactionActive, bool kCheckTransaction = true>
+ void SetType(ObjPtr<Class> type) REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive>
- void SetType(ObjPtr<mirror::Class> type) REQUIRES_SHARED(Locks::mutator_lock_);
+ template<bool kTransactionActive, bool kCheckTransaction = true>
+ void SetAccessFlags(uint32_t access_flags) REQUIRES_SHARED(Locks::mutator_lock_) {
+ SetField32<kTransactionActive, kCheckTransaction>(AccessFlagsOffset(), access_flags);
+ }
- template<bool kTransactionActive>
- void SetAccessFlags(uint32_t flags) REQUIRES_SHARED(Locks::mutator_lock_) {
- SetField32<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, access_flags_), flags);
+ template<bool kTransactionActive, bool kCheckTransaction = true>
+ void SetArtFieldIndex(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_) {
+ SetField32<kTransactionActive, kCheckTransaction>(ArtFieldIndexOffset(), idx);
}
- template<bool kTransactionActive>
+ template<bool kTransactionActive, bool kCheckTransaction = true>
void SetOffset(uint32_t offset) REQUIRES_SHARED(Locks::mutator_lock_) {
- SetField32<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, offset_), offset);
+ SetField32<kTransactionActive, kCheckTransaction>(OffsetOffset(), offset);
}
friend struct art::FieldOffsets; // for verifying offset information
diff --git a/runtime/mirror/method.cc b/runtime/mirror/method.cc
index 20a697977b..c8290268c4 100644
--- a/runtime/mirror/method.cc
+++ b/runtime/mirror/method.cc
@@ -25,43 +25,35 @@
namespace art {
namespace mirror {
-template <PointerSize kPointerSize, bool kTransactionActive>
+template <PointerSize kPointerSize>
ObjPtr<Method> Method::CreateFromArtMethod(Thread* self, ArtMethod* method) {
DCHECK(!method->IsConstructor()) << method->PrettyMethod();
ObjPtr<Method> ret = ObjPtr<Method>::DownCast(GetClassRoot<Method>()->AllocObject(self));
if (LIKELY(ret != nullptr)) {
- ret->Executable::CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
+ ret->InitializeFromArtMethod<kPointerSize>(method);
}
return ret;
}
-template ObjPtr<Method> Method::CreateFromArtMethod<PointerSize::k32, false>(
+template ObjPtr<Method> Method::CreateFromArtMethod<PointerSize::k32>(
Thread* self, ArtMethod* method);
-template ObjPtr<Method> Method::CreateFromArtMethod<PointerSize::k32, true>(
- Thread* self, ArtMethod* method);
-template ObjPtr<Method> Method::CreateFromArtMethod<PointerSize::k64, false>(
- Thread* self, ArtMethod* method);
-template ObjPtr<Method> Method::CreateFromArtMethod<PointerSize::k64, true>(
+template ObjPtr<Method> Method::CreateFromArtMethod<PointerSize::k64>(
Thread* self, ArtMethod* method);
-template <PointerSize kPointerSize, bool kTransactionActive>
+template <PointerSize kPointerSize>
ObjPtr<Constructor> Constructor::CreateFromArtMethod(Thread* self, ArtMethod* method) {
DCHECK(method->IsConstructor()) << method->PrettyMethod();
ObjPtr<Constructor> ret =
ObjPtr<Constructor>::DownCast(GetClassRoot<Constructor>()->AllocObject(self));
if (LIKELY(ret != nullptr)) {
- ret->Executable::CreateFromArtMethod<kPointerSize, kTransactionActive>(method);
+ ret->InitializeFromArtMethod<kPointerSize>(method);
}
return ret;
}
-template ObjPtr<Constructor> Constructor::CreateFromArtMethod<PointerSize::k32, false>(
- Thread* self, ArtMethod* method);
-template ObjPtr<Constructor> Constructor::CreateFromArtMethod<PointerSize::k32, true>(
- Thread* self, ArtMethod* method);
-template ObjPtr<Constructor> Constructor::CreateFromArtMethod<PointerSize::k64, false>(
+template ObjPtr<Constructor> Constructor::CreateFromArtMethod<PointerSize::k32>(
Thread* self, ArtMethod* method);
-template ObjPtr<Constructor> Constructor::CreateFromArtMethod<PointerSize::k64, true>(
+template ObjPtr<Constructor> Constructor::CreateFromArtMethod<PointerSize::k64>(
Thread* self, ArtMethod* method);
} // namespace mirror
diff --git a/runtime/mirror/method.h b/runtime/mirror/method.h
index a73cd45ca4..93d61b6597 100644
--- a/runtime/mirror/method.h
+++ b/runtime/mirror/method.h
@@ -30,7 +30,7 @@ class Class;
// C++ mirror of java.lang.reflect.Method.
class MANAGED Method : public Executable {
public:
- template <PointerSize kPointerSize, bool kTransactionActive>
+ template <PointerSize kPointerSize>
static ObjPtr<Method> CreateFromArtMethod(Thread* self, ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
@@ -41,7 +41,7 @@ class MANAGED Method : public Executable {
// C++ mirror of java.lang.reflect.Constructor.
class MANAGED Constructor: public Executable {
public:
- template <PointerSize kPointerSize, bool kTransactionActive>
+ template <PointerSize kPointerSize>
static ObjPtr<Constructor> CreateFromArtMethod(Thread* self, ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 2c537c6626..5a73bf3383 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -540,10 +540,10 @@ static jobject Class_getDeclaredConstructorInternal(
return nullptr;
}
Handle<mirror::Constructor> result = hs.NewHandle(
- mirror::Class::GetDeclaredConstructorInternal<kRuntimePointerSize, false>(
- soa.Self(),
- klass,
- soa.Decode<mirror::ObjectArray<mirror::Class>>(args)));
+ mirror::Class::GetDeclaredConstructorInternal<kRuntimePointerSize>(
+ soa.Self(),
+ klass,
+ soa.Decode<mirror::ObjectArray<mirror::Class>>(args)));
if (result == nullptr || ShouldDenyAccessToMember(result->GetArtMethod(), soa.Self())) {
return nullptr;
}
@@ -588,7 +588,7 @@ static jobjectArray Class_getDeclaredConstructorsInternal(
DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
DCHECK(!Runtime::Current()->IsActiveTransaction());
ObjPtr<mirror::Constructor> constructor =
- mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), &m);
+ mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), &m);
if (UNLIKELY(constructor == nullptr)) {
soa.Self()->AssertPendingOOMException();
return nullptr;
@@ -611,7 +611,7 @@ static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis,
return nullptr;
}
Handle<mirror::Method> result = hs.NewHandle(
- mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize, false>(
+ mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize>(
soa.Self(),
klass,
soa.Decode<mirror::String>(name),
@@ -659,7 +659,7 @@ static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaT
DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
DCHECK(!Runtime::Current()->IsActiveTransaction());
ObjPtr<mirror::Method> method =
- mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), &m);
+ mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), &m);
if (method == nullptr) {
soa.Self()->AssertPendingException();
return nullptr;
diff --git a/runtime/native/java_lang_invoke_MethodHandleImpl.cc b/runtime/native/java_lang_invoke_MethodHandleImpl.cc
index 0b26bd7c4a..c1060fe73a 100644
--- a/runtime/native/java_lang_invoke_MethodHandleImpl.cc
+++ b/runtime/native/java_lang_invoke_MethodHandleImpl.cc
@@ -40,23 +40,18 @@ static jobject MethodHandleImpl_getMemberInternal(JNIEnv* env, jobject thiz) {
// a Method for method invokers and a Constructor for constructors.
const mirror::MethodHandle::Kind handle_kind = handle->GetHandleKind();
- // We check this here because we pass false to CreateFromArtField and
- // CreateFromArtMethod.
- DCHECK(!Runtime::Current()->IsActiveTransaction());
-
MutableHandle<mirror::Object> h_object(hs.NewHandle<mirror::Object>(nullptr));
if (handle_kind >= mirror::MethodHandle::kFirstAccessorKind) {
ArtField* const field = handle->GetTargetField();
- h_object.Assign(mirror::Field::CreateFromArtField<kRuntimePointerSize, false>(
+ h_object.Assign(mirror::Field::CreateFromArtField<kRuntimePointerSize>(
soa.Self(), field, /* force_resolve= */ false));
} else {
ArtMethod* const method = handle->GetTargetMethod();
if (method->IsConstructor()) {
- h_object.Assign(mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(
- soa.Self(), method));
+ h_object.Assign(
+ mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), method));
} else {
- h_object.Assign(mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(
- soa.Self(), method));
+ h_object.Assign(mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), method));
}
}
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index b78855fd3d..76e036ac45 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -173,16 +173,16 @@ TEST_F(ProxyTest, CheckArtMirrorFieldsOfProxyStaticFields) {
ASSERT_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
ASSERT_FALSE(Runtime::Current()->IsActiveTransaction());
Handle<mirror::Field> field00 =
- hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize, false>(
+ hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize>(
soa.Self(), &static_fields0->At(0), true));
Handle<mirror::Field> field01 =
- hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize, false>(
+ hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize>(
soa.Self(), &static_fields0->At(1), true));
Handle<mirror::Field> field10 =
- hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize, false>(
+ hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize>(
soa.Self(), &static_fields1->At(0), true));
Handle<mirror::Field> field11 =
- hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize, false>(
+ hs.NewHandle(mirror::Field::CreateFromArtField<kRuntimePointerSize>(
soa.Self(), &static_fields1->At(1), true));
EXPECT_EQ(field00->GetArtField(), &static_fields0->At(0));
EXPECT_EQ(field01->GetArtField(), &static_fields0->At(1));
diff --git a/runtime/proxy_test.h b/runtime/proxy_test.h
index 23e536d27e..bdd902f9f2 100644
--- a/runtime/proxy_test.h
+++ b/runtime/proxy_test.h
@@ -76,14 +76,14 @@ ObjPtr<mirror::Class> GenerateProxyClass(ScopedObjectAccess& soa,
DCHECK(!Runtime::Current()->IsActiveTransaction());
soa.Env()->SetObjectArrayElement(
proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
- mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), method)));
+ mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), method)));
method = javaLangObject->FindClassMethod("hashCode", "()I", kRuntimePointerSize);
CHECK(method != nullptr);
CHECK(!method->IsDirect());
CHECK(method->GetDeclaringClass() == javaLangObject.Get());
soa.Env()->SetObjectArrayElement(
proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
- mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), method)));
+ mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), method)));
method = javaLangObject->FindClassMethod(
"toString", "()Ljava/lang/String;", kRuntimePointerSize);
CHECK(method != nullptr);
@@ -91,13 +91,13 @@ ObjPtr<mirror::Class> GenerateProxyClass(ScopedObjectAccess& soa,
CHECK(method->GetDeclaringClass() == javaLangObject.Get());
soa.Env()->SetObjectArrayElement(
proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
- mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), method)));
+ mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), method)));
// Now adds all interfaces virtual methods.
for (Handle<mirror::Class> interface : interfaces) {
for (auto& m : interface->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
soa.Env()->SetObjectArrayElement(
proxyClassMethods, array_index++, soa.AddLocalReference<jobject>(
- mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), &m)));
+ mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), &m)));
}
}
CHECK_EQ(array_index, methods_count);