Merge "Add the "- waiting on"/"- waiting to lock" lines to the SIGQUIT output." into dalvik-dev
diff --git a/Android.mk b/Android.mk
index 6c2fd7e..a27d526 100644
--- a/Android.mk
+++ b/Android.mk
@@ -156,18 +156,24 @@
 # oatdump targets
 
 .PHONY: dump-oat
-dump-oat: dump-core-oat dump-boot-oat
+dump-oat: dump-oat-core dump-oat-boot
 
-.PHONY: dump-core-oat
-dump-core-oat: $(TARGET_CORE_OAT) $(OATDUMP)
-	$(OATDUMP) $(addprefix --dex-file=,$(TARGET_CORE_DEX)) --image=$(TARGET_CORE_OAT) --strip-prefix=$(PRODUCT_OUT) --output=/tmp/core.oatdump.txt
+.PHONY: dump-oat-core
+dump-oat-core: $(TARGET_CORE_OAT) $(OATDUMP)
+	$(OATDUMP) $(addprefix --dex-file=,$(TARGET_CORE_DEX)) --image=$< --strip-prefix=$(PRODUCT_OUT) --output=/tmp/core.oatdump.txt
 	@echo Output in /tmp/core.oatdump.txt
 
-.PHONY: dump-boot-oat
-dump-boot-oat: $(TARGET_BOOT_OAT) $(OATDUMP)
-	$(OATDUMP) $(addprefix --dex-file=,$(TARGET_BOOT_DEX)) --image=$(TARGET_BOOT_OAT) --strip-prefix=$(PRODUCT_OUT) --output=/tmp/boot.oatdump.txt
+.PHONY: dump-oat-boot
+dump-oat-boot: $(TARGET_BOOT_OAT) $(OATDUMP)
+	$(OATDUMP) $(addprefix --dex-file=,$(TARGET_BOOT_DEX)) --image=$< --strip-prefix=$(PRODUCT_OUT) --output=/tmp/boot.oatdump.txt
 	@echo Output in /tmp/boot.oatdump.txt
 
+.PHONY: dump-oat-Calculator
+dump-oat-Calculator: $(TARGET_OUT_APPS)/Calculator.oat $(TARGET_BOOT_OAT) $(OATDUMP)
+	$(OATDUMP) --dex-file=$(TARGET_OUT_APPS)/Calculator.apk --image=$< $(addprefix --boot-dex-file=,$(TARGET_BOOT_DEX)) --boot=$(TARGET_BOOT_OAT) --strip-prefix=$(PRODUCT_OUT) --output=/tmp/Calculator.oatdump.txt
+	@echo Output in /tmp/Calculator.oatdump.txt
+
+
 ########################################################################
 # cpplint target
 
diff --git a/oat_process/Android.mk b/oat_process/Android.mk
index 9fb9401..0ebb052 100644
--- a/oat_process/Android.mk
+++ b/oat_process/Android.mk
@@ -6,18 +6,25 @@
 local_shared_libraries := \
 	libcutils \
 	libutils \
-	libbinder
+	libbinder \
+	libstlport
 
 include $(CLEAR_VARS)
+include external/stlport/libstlport.mk
 LOCAL_MODULE:= oat_process
 LOCAL_MODULE_TAGS:= optional
 LOCAL_SRC_FILES:= $(local_src_files)
-LOCAL_SHARED_LIBRARIES := liboat_runtimed $(local_shared_libraries)
+LOCAL_SHARED_LIBRARIES := liboat_runtime libart $(local_shared_libraries)
+LOCAL_C_INCLUDES += $(ART_C_INCLUDES)
+LOCAL_CFLAGS := $(ART_TARGET_CFLAGS)
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
+include external/stlport/libstlport.mk
 LOCAL_MODULE_TAGS:= optional
 LOCAL_MODULE:= oat_processd
 LOCAL_SRC_FILES:= $(local_src_files)
-LOCAL_SHARED_LIBRARIES := liboat_runtimed $(local_shared_libraries)
+LOCAL_SHARED_LIBRARIES := liboat_runtimed libartd $(local_shared_libraries)
+LOCAL_C_INCLUDES += $(ART_C_INCLUDES)
+LOCAL_CFLAGS := $(ART_TARGET_CFLAGS)
 include $(BUILD_EXECUTABLE)
diff --git a/oat_process/app_main.cpp b/oat_process/app_main.cpp
index ca80fc2..9ccdf16 100644
--- a/oat_process/app_main.cpp
+++ b/oat_process/app_main.cpp
@@ -7,6 +7,11 @@
 
 #define LOG_TAG "appproc"
 
+#include "class_loader.h"
+#include "jni_internal.h"
+#include "stringprintf.h"
+#include "thread.h"
+
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <utils/Log.h>
@@ -72,11 +77,57 @@
         char* slashClassName = toSlashClassName(mClassName);
         mClass = env->FindClass(slashClassName);
         if (mClass == NULL) {
-            LOGE("ERROR: could not find class '%s'\n", mClassName);
+            LOG(ERROR) << StringPrintf("ERROR: could not find class '%s'\n", mClassName);
         }
         free(slashClassName);
 
         mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
+
+        // TODO: remove this ClassLoader code
+        jclass ApplicationLoaders = env->FindClass("android/app/ApplicationLoaders");
+        jmethodID getDefault = env->GetStaticMethodID(ApplicationLoaders,
+                                                      "getDefault",
+                                                      "()Landroid/app/ApplicationLoaders;");
+        jfieldID mLoaders = env->GetFieldID(ApplicationLoaders, "mLoaders", "Ljava/util/Map;");
+        jclass BootClassLoader = env->FindClass("java/lang/BootClassLoader");
+        jmethodID getInstance = env->GetStaticMethodID(BootClassLoader,
+                                                       "getInstance",
+                                                       "()Ljava/lang/BootClassLoader;");
+        jclass ClassLoader = env->FindClass("java/lang/ClassLoader");
+        jfieldID parent = env->GetFieldID(ClassLoader, "parent", "Ljava/lang/ClassLoader;");
+        jclass Map = env->FindClass("java/util/Map");
+        jmethodID put = env->GetMethodID(Map,
+                                         "put",
+                                         "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+        jclass BaseDexClassLoader = env->FindClass("dalvik/system/BaseDexClassLoader");
+        jfieldID originalPath = env->GetFieldID(BaseDexClassLoader, "originalPath", "Ljava/lang/String;");
+        jfieldID pathList = env->GetFieldID(BaseDexClassLoader, "pathList", "Ldalvik/system/DexPathList;");
+        jclass DexPathList = env->FindClass("dalvik/system/DexPathList");
+        jmethodID init = env->GetMethodID(DexPathList,
+                                          "<init>",
+                                          "(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V");
+
+        // Set the parent of our pre-existing ClassLoader to the non-null BootClassLoader.getInstance()
+        const art::ClassLoader* class_loader_object = art::Thread::Current()->GetClassLoaderOverride();
+        jobject class_loader = art::AddLocalReference<jobject>(env, class_loader_object);
+        jobject boot_class_loader = env->CallStaticObjectMethod(BootClassLoader, getInstance);
+        env->SetObjectField(class_loader, parent, boot_class_loader);
+
+        // Create a DexPathList
+        jstring dex_path = env->NewStringUTF("/system/app/Calculator.apk");
+        jstring library_path = env->NewStringUTF("/data/data/com.android.calculator2/lib");
+        jobject dex_path_list = env->NewObject(DexPathList, init,
+                                               boot_class_loader, dex_path, library_path, NULL);
+
+        // Set DexPathList into our pre-existing ClassLoader
+        env->SetObjectField(class_loader, pathList, dex_path_list);
+        env->SetObjectField(class_loader, originalPath, dex_path);
+
+        // Stash our pre-existing ClassLoader into ApplicationLoaders.getDefault().mLoaders
+        // under the expected name.
+        jobject application_loaders = env->CallStaticObjectMethod(ApplicationLoaders, getDefault);
+        jobject loaders = env->GetObjectField(application_loaders, mLoaders);
+        env->CallObjectMethod(loaders, put, dex_path, class_loader);
     }
 
     virtual void onStarted()
@@ -150,11 +201,11 @@
 
     // ignore /system/bin/app_process when invoked via WrapperInit
     if (strcmp(argv[0], "/system/bin/app_process") == 0) {
-        LOGI("Removing /system/bin/app_process argument");
+        LOG(INFO) << "Removing /system/bin/app_process argument";
         argc--;
         argv++;
         for (int i = 0; i < argc; i++) {
-            LOGI("argv[%d]=%s", i, argv[i]);
+            LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
         }
     }
 
@@ -162,7 +213,7 @@
     int oatArgc = argc + 2;
     const char* oatArgv[oatArgc];
     if (strcmp(argv[0], "-Xbootimage:/system/framework/boot.oat") != 0) {
-        LOGI("Adding oat arguments");
+        LOG(INFO) << "Adding oat arguments";
         oatArgv[0] = "-Xbootimage:/system/framework/boot.oat";
         oatArgv[1] = "-Ximage:/system/app/Calculator.oat";
         setenv("CLASSPATH", "/system/app/Calculator.apk", 1);
@@ -170,12 +221,12 @@
         argv = oatArgv;
         argc = oatArgc;
         for (int i = 0; i < argc; i++) {
-            LOGI("argv[%d]=%s", i, argv[i]);
+            LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
         }
     }
 
     // TODO: remove the heap arguments when implicit garbage collection enabled
-    LOGI("Adding heap arguments");
+    LOG(INFO) << "Adding heap arguments";
     int heapArgc = argc + 2;
     const char* heapArgv[heapArgc];
     heapArgv[0] = "-Xms64m";
@@ -184,11 +235,11 @@
     argv = heapArgv;
     argc = heapArgc;
     for (int i = 0; i < argc; i++) {
-        LOGI("argv[%d]=%s", i, argv[i]);
+        LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
     }
 
     // TODO: change the system default to not perform preloading
-    LOGI("Disabling preloading");
+    LOG(INFO) << "Disabling preloading";
     for (int i = 0; i < argc; i++) {
         if (strcmp(argv[i], "preload") == 0) {
             argv[i] = "nopreload";
@@ -196,7 +247,7 @@
         }
     }
     for (int i = 0; i < argc; i++) {
-        LOGI("argv[%d]=%s", i, argv[i]);
+        LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
     }
 
     // Everything up to '--' or first non '-' arg goes to the vm
@@ -249,7 +300,7 @@
     } else {
         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
         app_usage();
-        LOG_ALWAYS_FATAL("oat_process: no class name or --zygote supplied.");
+        LOG(FATAL) << "oat_process: no class name or --zygote supplied.";
         return 10;
     }
 }
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 9c00d72..becd6d5 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1444,7 +1444,9 @@
 bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
                                                  const Class* klass1,
                                                  const Class* klass2) {
-  if (method->IsMiranda()) { return true; }
+  if (method->IsMiranda()) {
+      return true;
+  }
   const DexFile& dex_file = FindDexFile(method->GetDeclaringClass()->GetDexCache());
   const DexFile::ProtoId& proto_id = dex_file.GetProtoId(method->GetProtoIdx());
   DexFile::ParameterIterator *it;
@@ -1463,7 +1465,7 @@
   // Check the return type
   const char* descriptor = dex_file.GetReturnTypeDescriptor(proto_id);
   if (descriptor[0] == 'L' || descriptor[0] == '[') {
-    if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
+    if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
       return false;
     }
   }
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 4cb9cf0..e5911c0 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -126,6 +126,9 @@
     if (obj->IsClass()) {
       Class* klass = obj->AsClass();
       StringAppendF(&summary, "CLASS %s", klass->GetDescriptor()->ToModifiedUtf8().c_str());
+      std::stringstream ss;
+      ss << " (" << klass->GetStatus() << ")";
+      summary += ss.str();
     } else if (obj->IsMethod()) {
       Method* method = obj->AsMethod();
       StringAppendF(&summary, "METHOD %s", PrettyMethod(method).c_str());
@@ -151,21 +154,32 @@
     //               object_bytes, RoundUp(object_bytes, kObjectAlignment) - object_bytes);
     if (obj->IsMethod()) {
       Method* method = obj->AsMethod();
-      const ByteArray* code = method->GetCodeArray();
       if (!method->IsPhony()) {
-        size_t code_bytes = code->GetLength();
-        if (method->IsNative()) {
-          state->stats_.managed_to_native_code_bytes += code_bytes;
-        } else {
-          state->stats_.managed_code_bytes += code_bytes;
+        const ByteArray* code = method->GetCodeArray();
+        const int8_t* code_base = NULL;
+        const int8_t* code_limit = NULL;
+        if (code != NULL) {
+          size_t code_bytes = code->GetLength();
+          code_base = code->GetData();
+          code_limit = code_base + code_bytes;
+          if (method->IsNative()) {
+            state->stats_.managed_to_native_code_bytes += code_bytes;
+          } else {
+            state->stats_.managed_code_bytes += code_bytes;
+          }
         }
-        StringAppendF(&summary, "\tCODE     %p-%p\n", code->GetData(), code->GetData() + code_bytes);
+        StringAppendF(&summary, "\tCODE     %p-%p\n", code_base, code_limit);
 
         const ByteArray* invoke = method->GetInvokeStubArray();
-        size_t native_to_managed_code_bytes = invoke->GetLength();
-        state->stats_.native_to_managed_code_bytes += native_to_managed_code_bytes;
-        StringAppendF(&summary, "\tJNI STUB %p-%p\n",
-                      invoke->GetData(), invoke->GetData() + native_to_managed_code_bytes);
+        const int8_t* invoke_base = NULL;
+        const int8_t* invoke_limit = NULL;
+        if (invoke != NULL) {
+          size_t native_to_managed_code_bytes = invoke->GetLength();
+          invoke_base = invoke->GetData();
+          invoke_limit = invoke_base + native_to_managed_code_bytes;
+          state->stats_.native_to_managed_code_bytes += native_to_managed_code_bytes;
+          StringAppendF(&summary, "\tJNI STUB %p-%p\n", invoke_base, invoke_limit);
+        }
       }
       if (method->IsNative()) {
         if (method->IsRegistered()) {
@@ -191,8 +205,10 @@
                                      method->GetRegisterMapData()->GetLength());
         state->stats_.register_map_bytes += register_map_bytes;
 
-        size_t pc_mapping_table_bytes = method->GetMappingTable()->GetLength();
-        state->stats_.pc_mapping_table_bytes += pc_mapping_table_bytes;
+        if (method->GetMappingTable() != NULL) {
+          size_t pc_mapping_table_bytes = method->GetMappingTable()->GetLength();
+          state->stats_.pc_mapping_table_bytes += pc_mapping_table_bytes;
+        }
 
         ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
         class DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();