OSDN Git Service

Fix stack overflow and duplicate methods while tracing.
authorJeff Hao <jeffhao@google.com>
Wed, 3 Sep 2014 20:48:16 +0000 (13:48 -0700)
committerJeff Hao <jeffhao@google.com>
Wed, 3 Sep 2014 23:09:04 +0000 (16:09 -0700)
Bug: 16386215
Change-Id: I0d0ae0113a3a00013ce84a1f5a110e2c52f19b86

runtime/class_linker.cc
runtime/entrypoints/entrypoint_utils.cc
test/Android.run-test.mk

index 27483e7..73295f1 100644 (file)
@@ -2212,7 +2212,9 @@ bool ClassLinker::FindOatMethodFor(mirror::ArtMethod* method, OatFile::OatMethod
     size_t end = declaring_class->NumVirtualMethods();
     bool found = false;
     for (size_t i = 0; i < end; i++) {
-      if (declaring_class->GetVirtualMethod(i) == method) {
+      // Check method index instead of identity in case of duplicate method definitions.
+      if (method->GetDexMethodIndex() ==
+          declaring_class->GetVirtualMethod(i)->GetDexMethodIndex()) {
         found = true;
         break;
       }
@@ -2590,6 +2592,8 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file,
     klass->SetVirtualMethods(virtuals);
   }
   size_t class_def_method_index = 0;
+  uint32_t last_dex_method_index = DexFile::kDexNoIndex;
+  size_t last_class_def_method_index = 0;
   for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
     StackHandleScope<1> hs(self);
     Handle<mirror::ArtMethod> method(hs.NewHandle(LoadMethod(self, dex_file, it, klass)));
@@ -2599,7 +2603,15 @@ void ClassLinker::LoadClassMembers(const DexFile& dex_file,
     }
     klass->SetDirectMethod(i, method.Get());
     LinkCode(method, oat_class, dex_file, it.GetMemberIndex(), class_def_method_index);
-    method->SetMethodIndex(class_def_method_index);
+    uint32_t it_method_index = it.GetMemberIndex();
+    if (last_dex_method_index == it_method_index) {
+      // duplicate case
+      method->SetMethodIndex(last_class_def_method_index);
+    } else {
+      method->SetMethodIndex(class_def_method_index);
+      last_dex_method_index = it_method_index;
+      last_class_def_method_index = class_def_method_index;
+    }
     class_def_method_index++;
   }
   for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) {
index 34f92b5..8aaa471 100644 (file)
@@ -114,11 +114,6 @@ void ThrowStackOverflowError(Thread* self) {
     // We don't fail here because SetStackEndForStackOverflow will print better diagnostics.
   }
 
-  if (Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled()) {
-    // Remove extra entry pushed onto second stack during method tracing.
-    Runtime::Current()->GetInstrumentation()->PopMethodForUnwind(self, false);
-  }
-
   self->SetStackEndForStackOverflow();  // Allow space on the stack for constructor to execute.
   JNIEnvExt* env = self->GetJniEnv();
   std::string msg("stack size ");
index da94458..4ff6c65 100644 (file)
@@ -80,11 +80,7 @@ ifdef dist_goal
 endif
 
 # Tests that are broken in --trace mode.
-TEST_ART_BROKEN_TRACE_RUN_TESTS := \
-  004-SignalTest \
-  018-stack-overflow \
-  097-duplicate-method \
-  107-int-math2
+TEST_ART_BROKEN_TRACE_RUN_TESTS :=
 
 ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(call all-run-test-names,$(test),-trace,-relocate))
 ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_BROKEN_TRACE_RUN_TESTS), $(call all-run-test-names,$(test),-trace,-no-prebuild))