Assorted fixes for running frameworks apps
- Adding Heap::target_utililization_
- Convert ClassNotFoundError to ClassNotFoundException in Class.forName
- Finish String::GetHashCode
- Changed Runtime.gc to unimplemented
- Disable preload simulation in oat_process
- Empty native placeholder for org.apache.harmony.dalvik.ddmc.DdmServer
- Bonus: Fix problem with reflective invocation of constructors and private methods
Change-Id: If11b273e2f82e8e0fa7161a756098514e1156a19
diff --git a/Android.mk b/Android.mk
index ba7cf62..6c2fd7e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -51,6 +51,7 @@
# "mm test-art" to build and run all tests on host and device
.PHONY: test-art
test-art: test-art-host test-art-target
+ @echo test-art PASSED
define run-host-tests-with
$(foreach file,$(sort $(ART_HOST_TEST_EXECUTABLES)),$(1) $(file) &&) true
@@ -68,16 +69,19 @@
.PHONY: test-art-host
test-art-host: $(ART_HOST_TEST_DEPENDENCIES)
$(call run-host-tests-with,)
+ @echo test-art-host PASSED
# "mm valgrind-art-host" to build and run all host tests under valgrind.
.PHONY: valgrind-art-host
valgrind-art-host: $(ART_HOST_TEST_DEPENDENCIES)
$(call run-host-tests-with,"valgrind")
+ @echo valgrind-art-host PASSED
# "mm tsan-art-host" to build and run all host tests under tsan.
.PHONY: tsan-art-host
tsan-art-host: $(ART_HOST_TEST_DEPENDENCIES)
$(call run-host-tests-with,"tsan")
+ @echo tsan-art-host PASSED
########################################################################
# target test targets
@@ -85,6 +89,7 @@
# "mm test-art-target" to build and run all target tests
.PHONY: test-art-target
test-art-target: test-art-target-gtest test-art-target-oat
+ @echo test-art-target PASSED
.PHONY: test-art-target-sync
test-art-target-sync: $(ART_TARGET_TEST_DEPENDENCIES)
@@ -101,6 +106,7 @@
.PHONY: test-art-target-oat
test-art-target-oat: $(ART_TEST_OAT_TARGETS)
+ @echo test-art-target-oat PASSED
########################################################################
# oat_process test targets
@@ -130,13 +136,18 @@
test-art-target-oat-process-Calculator: $(TARGET_OUT_APPS)/Calculator.oat $(TARGET_OUT_JAVA_LIBRARIES)/am.oat test-art-target-sync
mkdir -p $(TARGET_OUT_DATA)/art-cache
unzip $(TARGET_OUT_APPS)/Calculator.apk classes.dex -d $(TARGET_OUT_DATA)/art-cache
- mv $(TARGET_OUT_DATA)/art-cache/classes.dex $(TARGET_OUT_DATA)/art-cache/system@app@Calculator.apk@classes.dex.c96b4ebb # crc32 from "unzip -lv $(TARGET_OUT_APPS)/Calculator.apk"
+ mv $(TARGET_OUT_DATA)/art-cache/classes.dex $(TARGET_OUT_DATA)/art-cache/system@app@Calculator.apk@classes.dex.`unzip -lv $(TARGET_OUT_APPS)/Calculator.apk classes.dex | grep classes.dex | sed -E 's/.* ([0-9a-f]+) classes.dex/\1/'` # note this is extracting the crc32 that is needed as the file extension
adb remount
adb sync
- adb shell setprop wrap.com.android.calculator2 "oat_processd"
- adb shell stop
- adb shell start
- sleep 15 # sleep 30
+ if [ "`adb shell getprop wrap.com.android.calculator2 | tr -d '\r'`" = "oat_processd" ]; then \
+ echo wrap.com.android.calculator2 already set; \
+ else \
+ echo Setting wrap.com.android.calculator2 and restarting runtime; \
+ adb shell setprop wrap.com.android.calculator2 "oat_processd"; \
+ adb shell stop; \
+ adb shell start; \
+ sleep 30; \
+ fi
adb shell sh -c "export CLASSPATH=/system/framework/am.jar && oat_processd /system/bin/app_process -Xbootimage:/system/framework/boot.oat -Ximage:/system/framework/am.oat /system/bin com.android.commands.am.Am start -a android.intent.action.MAIN -n com.android.calculator2/.Calculator && touch /sdcard/test-art-target-process-Calculator"
$(hide) (adb pull /sdcard/test-art-target-process-Calculator /tmp/ && echo test-art-target-process-Calculator PASSED) || echo test-art-target-process-Calculator FAILED
$(hide) rm /tmp/test-art-target-process-Calculator
@@ -144,6 +155,9 @@
########################################################################
# oatdump targets
+.PHONY: dump-oat
+dump-oat: dump-core-oat dump-boot-oat
+
.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
diff --git a/build/Android.common.mk b/build/Android.common.mk
index f0e80b1..5903eae 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -132,6 +132,7 @@
src/object.cc \
src/object_bitmap.cc \
src/offsets.cc \
+ src/org_apache_harmony_dalvik_ddmc_DdmServer.cc \
src/os_linux.cc \
src/reference_table.cc \
src/reflection.cc \
diff --git a/oat_process/app_main.cpp b/oat_process/app_main.cpp
index 92ede6d..ca80fc2 100644
--- a/oat_process/app_main.cpp
+++ b/oat_process/app_main.cpp
@@ -128,7 +128,7 @@
strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0));
}
-int main(int argc, const char* const argv[])
+int main(int argc, const char* argv[])
{
// These are global variables in ProcessState.cpp
mArgC = argc;
@@ -187,6 +187,18 @@
LOGI("argv[%d]=%s", i, argv[i]);
}
+ // TODO: change the system default to not perform preloading
+ LOGI("Disabling preloading");
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "preload") == 0) {
+ argv[i] = "nopreload";
+ break;
+ }
+ }
+ for (int i = 0; i < argc; i++) {
+ LOGI("argv[%d]=%s", i, argv[i]);
+ }
+
// Everything up to '--' or first non '-' arg goes to the vm
int i = runtime.addVmArguments(argc, argv);
diff --git a/src/heap.cc b/src/heap.cc
index 8311944..5e96a79 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -38,6 +38,8 @@
MemberOffset Heap::reference_pendingNext_offset_ = MemberOffset(0);
MemberOffset Heap::finalizer_reference_zombie_offset_ = MemberOffset(0);
+float Heap::target_utilization_ = 0.5;
+
Mutex* Heap::lock_ = NULL;
bool Heap::verify_objects_ = false;
diff --git a/src/heap.h b/src/heap.h
index ea05a73..b669a86 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -87,12 +87,11 @@
}
// Implements dalvik.system.VMRuntime.getTargetHeapUtilization.
static float GetTargetHeapUtilization() {
- UNIMPLEMENTED(WARNING);
- return 0.0f;
+ return target_utilization_;
}
// Implements dalvik.system.VMRuntime.setTargetHeapUtilization.
static void SetTargetHeapUtilization(float target) {
- UNIMPLEMENTED(WARNING);
+ target_utilization_ = target;
}
// Blocks the caller until the garbage collector becomes idle.
@@ -240,6 +239,9 @@
// offset of java.lang.ref.FinalizerReference.zombie
static MemberOffset finalizer_reference_zombie_offset_;
+ // Target ideal heap utilization ratio
+ static float target_utilization_;
+
static bool verify_objects_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Heap);
diff --git a/src/indirect_reference_table.cc b/src/indirect_reference_table.cc
index ed27bf4..f1e903c 100644
--- a/src/indirect_reference_table.cc
+++ b/src/indirect_reference_table.cc
@@ -85,7 +85,7 @@
DCHECK(obj != NULL);
// TODO: stronger sanity check on the object (such as in heap)
- DCHECK(IsAligned(reinterpret_cast<intptr_t>(obj), 8));
+ DCHECK(IsAligned(reinterpret_cast<intptr_t>(obj), 8)) << reinterpret_cast<const void*>(obj);
DCHECK(table_ != NULL);
DCHECK_LE(alloc_entries_, max_entries_);
DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index d93d3e6..4fe3191 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -48,6 +48,15 @@
ClassLoader* class_loader = down_cast<ClassLoader*>(loader);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Class* c = class_linker->FindClass(descriptor.c_str(), class_loader);
+ if (c == NULL) {
+ // Convert NoClassDefFoundError to ClassNotFoundException
+ // TODO: chain exceptions?
+ DCHECK(env->ExceptionCheck());
+ env->ExceptionClear();
+ Thread::Current()->ThrowNewException("Ljava/lang/ClassNotFoundException;",
+ "%s", name.c_str());
+ return NULL;
+ }
if (initialize) {
class_linker->EnsureInitialized(c, true);
}
diff --git a/src/java_lang_Runtime.cc b/src/java_lang_Runtime.cc
index a2bd399..a3f4f49 100644
--- a/src/java_lang_Runtime.cc
+++ b/src/java_lang_Runtime.cc
@@ -30,6 +30,8 @@
namespace {
void Runtime_gc(JNIEnv*, jclass) {
+ UNIMPLEMENTED(WARNING);
+ return;
Heap::CollectGarbage();
}
diff --git a/src/object.cc b/src/object.cc
index e37b683..8bdc295 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -1273,11 +1273,14 @@
return Runtime::Current()->GetInternTable()->InternWeak(this);
}
-int32_t String::GetHashCode() const {
- int32_t result = GetField32(
- OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
- DCHECK(result != 0 ||
- ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0);
+int32_t String::GetHashCode() {
+ int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
+ if (result == 0) {
+ ComputeHashCode();
+ }
+ result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
+ DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
+ << ToModifiedUtf8() << " " << result;
return result;
}
diff --git a/src/object.h b/src/object.h
index 2ceafbd..1a137bd 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1711,6 +1711,9 @@
const StringPiece& descriptor);
Method* FindVirtualMethodForVirtualOrInterface(Method* method) {
+ if (method->IsDirect()) {
+ return method;
+ }
if (method->GetDeclaringClass()->IsInterface()) {
return FindVirtualMethodForInterface(method);
}
@@ -2393,7 +2396,7 @@
int32_t GetLength() const;
- int32_t GetHashCode() const;
+ int32_t GetHashCode();
void ComputeHashCode() {
SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
diff --git a/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc b/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc
new file mode 100644
index 0000000..3392689
--- /dev/null
+++ b/src/org_apache_harmony_dalvik_ddmc_DdmServer.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "logging.h"
+
+#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
+#include "ScopedPrimitiveArray.h" // Last to avoid problems with LOG redefinition.
+
+namespace art {
+
+namespace {
+
+static void DdmServer_nativeSendChunk(JNIEnv* env, jclass, jint type,
+ jbyteArray javaData, jint offset, jint length)
+{
+ ScopedByteArrayRO data(env, javaData);
+ DCHECK_LE(offset + length, static_cast<int32_t>(data.size()));
+ UNIMPLEMENTED(WARNING) << "dvmDbgDdmSendChunk(type, length, data->get() + offset);";
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(DdmServer, nativeSendChunk, "(I[BII)V"),
+};
+
+} // namespace
+
+void register_org_apache_harmony_dalvik_ddmc_DdmServer(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "org/apache/harmony/dalvik/ddmc/DdmServer", gMethods, NELEM(gMethods));
+}
+
+} // namespace art
diff --git a/src/runtime.cc b/src/runtime.cc
index acb42e9..ca1d4f8 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -471,7 +471,7 @@
REGISTER(register_java_lang_reflect_Method);
//REGISTER(register_java_lang_reflect_Proxy);
REGISTER(register_java_util_concurrent_atomic_AtomicLong);
- //REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer);
+ REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer);
//REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal);
REGISTER(register_sun_misc_Unsafe);
#undef REGISTER