summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-05-02 17:17:18 -0700
committerIan Rogers <irogers@google.com>2014-05-02 23:30:03 -0700
commit5d27fafdf03f259e92eaee9f6319b9349cc8d62e (patch)
tree53afb1174be2ae235e41c5ac9eeb1e8d67e3c4e1 /runtime
parenta54c22c0041306f6881694f4c305e655b10e37be (diff)
downloadandroid_art-5d27fafdf03f259e92eaee9f6319b9349cc8d62e.tar.gz
android_art-5d27fafdf03f259e92eaee9f6319b9349cc8d62e.tar.bz2
android_art-5d27fafdf03f259e92eaee9f6319b9349cc8d62e.zip
Allow ArtMethod::Invoke in unstarted runtimes.
Change-Id: I0141f4daef4751589d03d27484eb65c811b14f27
Diffstat (limited to 'runtime')
-rw-r--r--runtime/class_linker.cc8
-rw-r--r--runtime/interpreter/interpreter.cc29
-rw-r--r--runtime/jni_internal_test.cc6
-rw-r--r--runtime/mirror/art_method.cc8
4 files changed, 29 insertions, 22 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 703229c44b..db46224c96 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -3215,12 +3215,8 @@ bool ClassLinker::InitializeClass(const SirtRef<mirror::Class>& klass, bool can_
mirror::ArtMethod* clinit = klass->FindClassInitializer();
if (clinit != NULL) {
CHECK(can_init_statics);
- if (LIKELY(Runtime::Current()->IsStarted())) {
- JValue result;
- clinit->Invoke(self, NULL, 0, &result, "V");
- } else {
- art::interpreter::EnterInterpreterFromInvoke(self, clinit, NULL, NULL, NULL);
- }
+ JValue result;
+ clinit->Invoke(self, NULL, 0, &result, "V");
}
uint64_t t1 = NanoTime();
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 1e1a8c19a3..7232e54944 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -27,10 +27,6 @@ namespace interpreter {
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 @@ static void UnstartedRuntimeJni(Thread* self, ArtMethod* method,
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 @@ static void UnstartedRuntimeJni(Thread* self, ArtMethod* method,
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 @@ static void UnstartedRuntimeJni(Thread* self, ArtMethod* method,
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";
}
}
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index 071b658fb9..14fc25c302 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -322,11 +322,7 @@ TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
ASSERT_TRUE(mid2 != NULL);
// Make sure we can actually use it.
jstring s = env_->NewStringUTF("poop");
- // TODO: this should return 4, but the runtime skips the method
- // invoke because the runtime isn't started. In the future it would
- // be nice to use interpretter for things like this. This still does
- // validate that we have a sane jmethodID value.
- ASSERT_EQ(0, env_->CallIntMethod(s, mid2));
+ ASSERT_EQ(4, env_->CallIntMethod(s, mid2));
}
void BogusMethod() {
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 7453d4d3fe..4275f25b05 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -287,9 +287,11 @@ void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue*
Runtime* runtime = Runtime::Current();
// Call the invoke stub, passing everything as arguments.
if (UNLIKELY(!runtime->IsStarted())) {
- LOG(INFO) << "Not invoking " << PrettyMethod(this) << " for a runtime that isn't started";
- if (result != NULL) {
- result->SetJ(0);
+ if (IsStatic()) {
+ art::interpreter::EnterInterpreterFromInvoke(self, this, nullptr, args, result);
+ } else {
+ Object* receiver = reinterpret_cast<StackReference<Object>*>(&args[0])->AsMirrorPtr();
+ art::interpreter::EnterInterpreterFromInvoke(self, this, receiver, args + 1, result);
}
} else {
const bool kLogInvocationStartAndReturn = false;