Allow ArtMethod::Invoke in unstarted runtimes.
Change-Id: I0141f4daef4751589d03d27484eb65c811b14f27
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 1e1a8c1..7232e54 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -27,10 +27,6 @@
static void UnstartedRuntimeJni(Thread* self, ArtMethod* method,
Object* receiver, uint32_t* args, JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(Runtime::Current()->IsActiveTransaction()) << "Calling native method "
- << PrettyMethod(method)
- << " in unstarted runtime should only happen"
- << " in a transaction";
std::string name(PrettyMethod(method));
if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") {
result->SetL(NULL);
@@ -71,7 +67,11 @@
result->SetL(Array::CreateMultiArray(self, sirt_class, sirt_dimensions));
} else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") {
ScopedObjectAccessUnchecked soa(self);
- result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<true>(soa)));
+ if (Runtime::Current()->IsActiveTransaction()) {
+ result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<true>(soa)));
+ } else {
+ result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<false>(soa)));
+ }
} else if (name == "int java.lang.System.identityHashCode(java.lang.Object)") {
mirror::Object* obj = reinterpret_cast<Object*>(args[0]);
result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0);
@@ -82,13 +82,22 @@
jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
jint expectedValue = args[3];
jint newValue = args[4];
- bool success = obj->CasField32<true>(MemberOffset(offset), expectedValue, newValue);
+ bool success;
+ if (Runtime::Current()->IsActiveTransaction()) {
+ success = obj->CasField32<true>(MemberOffset(offset), expectedValue, newValue);
+ } else {
+ success = obj->CasField32<false>(MemberOffset(offset), expectedValue, newValue);
+ }
result->SetZ(success ? JNI_TRUE : JNI_FALSE);
} else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") {
Object* obj = reinterpret_cast<Object*>(args[0]);
jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
Object* newValue = reinterpret_cast<Object*>(args[3]);
- obj->SetFieldObject<true>(MemberOffset(offset), newValue);
+ if (Runtime::Current()->IsActiveTransaction()) {
+ obj->SetFieldObject<true>(MemberOffset(offset), newValue);
+ } else {
+ obj->SetFieldObject<false>(MemberOffset(offset), newValue);
+ }
} else if (name == "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)") {
mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass();
Primitive::Type primitive_type = component->GetPrimitiveType();
@@ -97,9 +106,13 @@
mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass();
Primitive::Type primitive_type = component->GetPrimitiveType();
result->SetI(Primitive::ComponentSize(primitive_type));
- } else {
+ } else if (Runtime::Current()->IsActiveTransaction()) {
AbortTransaction(self, "Attempt to invoke native method in non-started runtime: %s",
name.c_str());
+
+ } else {
+ LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted "
+ "non-transactional runtime";
}
}