Merge "Support new VMRuntime native methods" into lmp-preview-dev
diff --git a/Android.mk b/Android.mk
index 3324458..cc37599 100644
--- a/Android.mk
+++ b/Android.mk
@@ -431,21 +431,21 @@
use-art:
adb root && sleep 3
adb shell stop
- adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libart.so
adb shell start
.PHONY: use-artd
use-artd:
adb root && sleep 3
adb shell stop
- adb shell setprop persist.sys.dalvik.vm.lib.1 libartd.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libartd.so
adb shell start
.PHONY: use-dalvik
use-dalvik:
adb root && sleep 3
adb shell stop
- adb shell setprop persist.sys.dalvik.vm.lib.1 libdvm.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libdvm.so
adb shell start
.PHONY: use-art-full
@@ -455,7 +455,7 @@
adb shell rm -rf $(ART_DALVIK_CACHE_DIR)/*
adb shell setprop dalvik.vm.dex2oat-flags ""
adb shell setprop dalvik.vm.image-dex2oat-flags ""
- adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libart.so
adb shell start
.PHONY: use-artd-full
@@ -465,7 +465,7 @@
adb shell rm -rf $(ART_DALVIK_CACHE_DIR)/*
adb shell setprop dalvik.vm.dex2oat-flags ""
adb shell setprop dalvik.vm.image-dex2oat-flags ""
- adb shell setprop persist.sys.dalvik.vm.lib.1 libartd.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libartd.so
adb shell start
.PHONY: use-art-smart
@@ -475,7 +475,7 @@
adb shell rm -rf $(ART_DALVIK_CACHE_DIR)/*
adb shell setprop dalvik.vm.dex2oat-flags "--compiler-filter=interpret-only"
adb shell setprop dalvik.vm.image-dex2oat-flags ""
- adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libart.so
adb shell start
.PHONY: use-art-interpret-only
@@ -485,7 +485,7 @@
adb shell rm -rf $(ART_DALVIK_CACHE_DIR)/*
adb shell setprop dalvik.vm.dex2oat-flags "--compiler-filter=interpret-only"
adb shell setprop dalvik.vm.image-dex2oat-flags "--compiler-filter=interpret-only"
- adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libart.so
adb shell start
.PHONY: use-art-verify-none
@@ -495,7 +495,7 @@
adb shell rm -rf $(ART_DALVIK_CACHE_DIR)/*
adb shell setprop dalvik.vm.dex2oat-flags "--compiler-filter=verify-none"
adb shell setprop dalvik.vm.image-dex2oat-flags "--compiler-filter=verify-none"
- adb shell setprop persist.sys.dalvik.vm.lib.1 libart.so
+ adb shell setprop persist.sys.dalvik.vm.lib.2 libart.so
adb shell start
########################################################################
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 2dbcc80..194cb18 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -180,13 +180,6 @@
virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* m = GetMethod();
- if (GetCurrentQuickFrame() == NULL) {
- if (kVerboseInstrumentation) {
- LOG(INFO) << " Ignoring a shadow frame. Frame " << GetFrameId()
- << " Method=" << PrettyMethod(m);
- }
- return true; // Ignore shadow frames.
- }
if (m == NULL) {
if (kVerboseInstrumentation) {
LOG(INFO) << " Skipping upcall. Frame " << GetFrameId();
@@ -204,6 +197,14 @@
if (kVerboseInstrumentation) {
LOG(INFO) << " Installing exit stub in " << DescribeLocation();
}
+ if (GetCurrentQuickFrame() == NULL) {
+ InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, 0, GetFrameId(), false);
+ if (kVerboseInstrumentation) {
+ LOG(INFO) << "Pushing shadow frame " << instrumentation_frame.Dump();
+ }
+ shadow_stack_.push_back(instrumentation_frame);
+ return true; // Continue.
+ }
uintptr_t return_pc = GetReturnPc();
if (return_pc == instrumentation_exit_pc_) {
// We've reached a frame which has already been installed with instrumentation exit stub.
@@ -238,6 +239,7 @@
return true; // Continue.
}
std::deque<InstrumentationStackFrame>* const instrumentation_stack_;
+ std::vector<InstrumentationStackFrame> shadow_stack_;
const size_t existing_instrumentation_frames_count_;
std::vector<uint32_t> dex_pcs_;
const uintptr_t instrumentation_exit_pc_;
@@ -261,14 +263,16 @@
if (instrumentation->ShouldNotifyMethodEnterExitEvents()) {
// Create method enter events for all methods currently on the thread's stack. We only do this
// if no debugger is attached to prevent from posting events twice.
- typedef std::deque<InstrumentationStackFrame>::const_reverse_iterator It;
- for (It it = thread->GetInstrumentationStack()->rbegin(),
- end = thread->GetInstrumentationStack()->rend(); it != end; ++it) {
- mirror::Object* this_object = (*it).this_object_;
- mirror::ArtMethod* method = (*it).method_;
+ auto ssi = visitor.shadow_stack_.rbegin();
+ for (auto isi = thread->GetInstrumentationStack()->rbegin(),
+ end = thread->GetInstrumentationStack()->rend(); isi != end; ++isi) {
+ while (ssi != visitor.shadow_stack_.rend() && (*ssi).frame_id_ < (*isi).frame_id_) {
+ instrumentation->MethodEnterEvent(thread, (*ssi).this_object_, (*ssi).method_, 0);
+ ++ssi;
+ }
uint32_t dex_pc = visitor.dex_pcs_.back();
visitor.dex_pcs_.pop_back();
- instrumentation->MethodEnterEvent(thread, this_object, method, dex_pc);
+ instrumentation->MethodEnterEvent(thread, (*isi).this_object_, (*isi).method_, dex_pc);
}
}
thread->VerifyStack();
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 8f74dd7..a0a294a 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -206,8 +206,8 @@
if (result != nullptr) {
for (size_t i = 0; i < dex_file->NumClassDefs(); ++i) {
const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
- const char* descriptor = dex_file->GetClassDescriptor(class_def);
- ScopedLocalRef<jstring> jdescriptor(env, env->NewStringUTF(descriptor));
+ std::string descriptor(DescriptorToDot(dex_file->GetClassDescriptor(class_def)));
+ ScopedLocalRef<jstring> jdescriptor(env, env->NewStringUTF(descriptor.c_str()));
if (jdescriptor.get() == nullptr) {
return nullptr;
}
diff --git a/test/071-dexfile/expected.txt b/test/071-dexfile/expected.txt
index b7af75e..d14c986 100644
--- a/test/071-dexfile/expected.txt
+++ b/test/071-dexfile/expected.txt
@@ -1,3 +1,4 @@
Constructing another
Got expected ULE
+Another
done
diff --git a/test/071-dexfile/src/Main.java b/test/071-dexfile/src/Main.java
index 117a391..2f85790 100644
--- a/test/071-dexfile/src/Main.java
+++ b/test/071-dexfile/src/Main.java
@@ -17,6 +17,8 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
/**
* DexFile tests (Dalvik-specific).
@@ -24,47 +26,37 @@
public class Main {
private static final String CLASS_PATH = System.getenv("DEX_LOCATION") + "/071-dexfile-ex.jar";
private static final String ODEX_DIR = System.getenv("DEX_LOCATION");
- //private static final String ODEX_DIR = ".";
private static final String ODEX_ALT = "/tmp";
private static final String LIB_DIR = "/nowhere/nothing/";
+ private static final String getOdexDir() {
+ return new File(ODEX_DIR).isDirectory() ? ODEX_DIR : ODEX_ALT;
+ }
+
/**
* Prep the environment then run the test.
*/
- public static void main(String[] args) {
- Process p;
- try {
- /*
- * Create a sub-process to see if the ProcessManager wait
- * interferes with the dexopt invocation wait.
- *
- * /dev/random never hits EOF, so we're sure that we'll still
- * be waiting for the process to complete. On the device it
- * stops pretty quickly (which means the child won't be
- * spinning).
- */
- ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random");
- p = pb.start();
- } catch (IOException ioe) {
- System.err.println("cmd failed: " + ioe.getMessage());
- p = null;
- }
+ public static void main(String[] args) throws Exception {
+ /*
+ * Create a sub-process to see if the ProcessManager wait
+ * interferes with the dexopt invocation wait.
+ *
+ * /dev/random never hits EOF, so we're sure that we'll still
+ * be waiting for the process to complete. On the device it
+ * stops pretty quickly (which means the child won't be
+ * spinning).
+ */
+ ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random");
+ Process p = pb.start();
- try {
- testDexClassLoader();
- } finally {
- // shouldn't be necessary, but it's good to be tidy
- if (p != null) {
- p.destroy();
- }
+ testDexClassLoader();
+ testDexFile();
- // let the ProcessManager's daemon thread finish before we shut down
- // (avoids the occasional segmentation fault)
- try {
- Thread.sleep(500);
- } catch (Exception ex) {}
- }
-
+ // shouldn't be necessary, but it's good to be tidy
+ p.destroy();
+ // let the ProcessManager's daemon thread finish before we shut down
+ // (avoids the occasional segmentation fault)
+ Thread.sleep(500);
System.out.println("done");
}
@@ -72,25 +64,10 @@
* Create a class loader, explicitly specifying the source DEX and
* the location for the optimized DEX.
*/
- private static void testDexClassLoader() {
+ private static void testDexClassLoader() throws Exception {
ClassLoader dexClassLoader = getDexClassLoader();
-
- Class anotherClass;
- try {
- anotherClass = dexClassLoader.loadClass("Another");
- } catch (ClassNotFoundException cnfe) {
- throw new RuntimeException("Another?", cnfe);
- }
-
- Object another;
- try {
- another = anotherClass.newInstance();
- } catch (IllegalAccessException ie) {
- throw new RuntimeException("new another", ie);
- } catch (InstantiationException ie) {
- throw new RuntimeException("new another", ie);
- }
-
+ Class Another = dexClassLoader.loadClass("Another");
+ Object another = Another.newInstance();
// not expected to work; just exercises the call
dexClassLoader.getResource("nonexistent");
}
@@ -100,51 +77,30 @@
* have visibility into dalvik.system.*, so we do this through
* reflection.
*/
- private static ClassLoader getDexClassLoader() {
- String odexDir;
-
- if (false) {
- String androidData = System.getenv("ANDROID_DATA");
- if (androidData == null) {
- androidData = "";
- }
- odexDir = androidData + "/" + ODEX_DIR;
- }
-
- File test = new File(ODEX_DIR);
- if (test.isDirectory()) {
- odexDir = ODEX_DIR;
- } else {
- odexDir = ODEX_ALT;
- }
- if (false) {
- System.out.println("Output dir is " + odexDir);
- }
-
- ClassLoader myLoader = Main.class.getClassLoader();
- Class dclClass;
- try {
- dclClass = myLoader.loadClass("dalvik.system.DexClassLoader");
- } catch (ClassNotFoundException cnfe) {
- throw new RuntimeException("dalvik.system.DexClassLoader not found", cnfe);
- }
-
- Constructor ctor;
- try {
- ctor = dclClass.getConstructor(String.class, String.class,
- String.class, ClassLoader.class);
- } catch (NoSuchMethodException nsme) {
- throw new RuntimeException("DCL ctor", nsme);
- }
-
+ private static ClassLoader getDexClassLoader() throws Exception {
+ ClassLoader classLoader = Main.class.getClassLoader();
+ Class DexClassLoader = classLoader.loadClass("dalvik.system.DexClassLoader");
+ Constructor DexClassLoader_init = DexClassLoader.getConstructor(String.class,
+ String.class,
+ String.class,
+ ClassLoader.class);
// create an instance, using the path we found
- Object dclObj;
- try {
- dclObj = ctor.newInstance(CLASS_PATH, odexDir, LIB_DIR, myLoader);
- } catch (Exception ex) {
- throw new RuntimeException("DCL newInstance", ex);
- }
+ return (ClassLoader) DexClassLoader_init.newInstance(CLASS_PATH, getOdexDir(), LIB_DIR, classLoader);
+ }
- return (ClassLoader) dclObj;
+ private static void testDexFile() throws Exception {
+ ClassLoader classLoader = Main.class.getClassLoader();
+ Class DexFile = classLoader.loadClass("dalvik.system.DexFile");
+ Method DexFile_loadDex = DexFile.getMethod("loadDex",
+ String.class,
+ String.class,
+ Integer.TYPE);
+ Method DexFile_entries = DexFile.getMethod("entries");
+ Object dexFile = DexFile_loadDex.invoke(null, CLASS_PATH, null, 0);
+ Enumeration<String> e = (Enumeration<String>) DexFile_entries.invoke(dexFile);
+ while (e.hasMoreElements()) {
+ String className = e.nextElement();
+ System.out.println(className);
+ }
}
}
diff --git a/test/etc/host-run-test-jar b/test/etc/host-run-test-jar
index d95559f..5d6d16a 100755
--- a/test/etc/host-run-test-jar
+++ b/test/etc/host-run-test-jar
@@ -89,11 +89,6 @@
msg "------------------------------"
-mkdir $DEX_LOCATION/dalvik-cache
-if [ $? -ne 0 ]; then
- exit
-fi
-
export ANDROID_PRINTF_LOG=brief
if [ "$DEV_MODE" = "y" ]; then
export ANDROID_LOG_TAGS='*:d'