Merge "Add dex file writer to dexlayout tool."
diff --git a/benchmark/Android.bp b/benchmark/Android.bp
index 014a2b3..e784508 100644
--- a/benchmark/Android.bp
+++ b/benchmark/Android.bp
@@ -44,3 +44,31 @@
"-Wno-frame-larger-than=",
],
}
+
+art_cc_library {
+ name: "libartbenchmark-micronative-host",
+ host_supported: true,
+ device_supported: false,
+ defaults: ["art_defaults", "art_debug_defaults"],
+ srcs: [
+ "jni_loader.cc",
+ "micro-native/micro_native.cc",
+ ],
+ shared_libs: [
+ ],
+ static_libs: [
+ ],
+ include_dirs: [
+ "libnativehelper/include/nativehelper" // only for jni.h
+ ],
+ stl: "libc++_static",
+ clang: true,
+ target: {
+ host: {
+ host_ldlibs: ["-ldl", "-lpthread"],
+ },
+ },
+ cflags: [
+ "-Wno-frame-larger-than=",
+ ],
+}
diff --git a/benchmark/micro-native/micro_native.cc b/benchmark/micro-native/micro_native.cc
index 43c29e2..d366d9d 100644
--- a/benchmark/micro-native/micro_native.cc
+++ b/benchmark/micro-native/micro_native.cc
@@ -14,12 +14,26 @@
* limitations under the License.
*/
-#define LOG_TAG "NativeMethods"
+#include <stdio.h>
+#include <jni.h>
+
+#ifndef NATIVE_METHOD
+#define NATIVE_METHOD(className, functionName, signature) \
+ { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
+#endif
+#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
+
+#define GLUE4(a, b, c, d) a ## b ## c ## d
+#define GLUE4_(a, b, c, d) GLUE4(a, b, c, d)
#define CLASS_NAME "benchmarks/MicroNative/java/NativeMethods"
+#define CLASS_INFIX benchmarks_MicroNative_java_NativeMethods
-#include "JNIHelp.h"
-#include "JniConstants.h"
+#define NAME_NORMAL_JNI_METHOD(name) GLUE4_(Java_, CLASS_INFIX, _, name)
+#define NAME_CRITICAL_JNI_METHOD(name) GLUE4_(JavaCritical_, CLASS_INFIX, _, name)
+
+#define DEFINE_NORMAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(Java_, CLASS_INFIX, _, name)
+#define DEFINE_CRITICAL_JNI_METHOD(ret, name) extern "C" JNIEXPORT ret JNICALL GLUE4_(JavaCritical_, CLASS_INFIX, _, name)
static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { }
static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { }
@@ -67,17 +81,66 @@
NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6_Fast, "(IIIIII)V"),
};
-static void NativeMethods_emptyJniStaticMethod0_Critical() { }
-static void NativeMethods_emptyJniStaticMethod6_Critical(int, int, int, int, int, int) { }
+// Have both a Java_ and a JavaCritical_ version of the same empty method.
+// The runtime automatically selects the right one when doing a dlsym-based native lookup.
+DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)(JNIEnv*, jclass) { }
+DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { }
+DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { }
+DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { }
static JNINativeMethod gMethods_Critical[] = {
- NATIVE_METHOD(NativeMethods, emptyJniStaticMethod0_Critical, "()V"),
- NATIVE_METHOD(NativeMethods, emptyJniStaticMethod6_Critical, "(IIIIII)V"),
+ // Don't use NATIVE_METHOD because the name is mangled differently.
+ { "emptyJniStaticMethod0_Critical", "()V",
+ reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod0_1Critical)) },
+ { "emptyJniStaticMethod6_Critical", "(IIIIII)V",
+ reinterpret_cast<void*>(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod6_1Critical)) }
};
+void jniRegisterNativeMethods(JNIEnv* env,
+ const char* className,
+ const JNINativeMethod* methods,
+ int numMethods) {
+ jclass c = env->FindClass(className);
+ if (c == nullptr) {
+ char* tmp;
+ const char* msg;
+ if (asprintf(&tmp,
+ "Native registration unable to find class '%s'; aborting...",
+ className) == -1) {
+ // Allocation failed, print default warning.
+ msg = "Native registration unable to find class; aborting...";
+ } else {
+ msg = tmp;
+ }
+ env->FatalError(msg);
+ }
+
+ if (env->RegisterNatives(c, methods, numMethods) < 0) {
+ char* tmp;
+ const char* msg;
+ if (asprintf(&tmp, "RegisterNatives failed for '%s'; aborting...", className) == -1) {
+ // Allocation failed, print default warning.
+ msg = "RegisterNatives failed; aborting...";
+ } else {
+ msg = tmp;
+ }
+ env->FatalError(msg);
+ }
+}
+
void register_micro_native_methods(JNIEnv* env) {
jniRegisterNativeMethods(env, CLASS_NAME, gMethods_NormalOnly, NELEM(gMethods_NormalOnly));
jniRegisterNativeMethods(env, CLASS_NAME, gMethods, NELEM(gMethods));
jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Fast, NELEM(gMethods_Fast));
- jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Critical, NELEM(gMethods_Critical));
+
+ if (env->FindClass("dalvik/annotation/optimization/CriticalNative") != nullptr) {
+ // Only register them explicitly if the annotation is present.
+ jniRegisterNativeMethods(env, CLASS_NAME, gMethods_Critical, NELEM(gMethods_Critical));
+ } else {
+ if (env->ExceptionCheck()) {
+ // It will throw NoClassDefFoundError
+ env->ExceptionClear();
+ }
+ }
+ // else let them be registered implicitly.
}
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 5d44cc1..1ddf961 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -990,6 +990,8 @@
}
}
+ char_backing_storage_.reserve((dex_locations_.size() - 1) * 2);
+
// Now create the other names. Use a counted loop to skip the first one.
for (size_t i = 1; i < dex_locations_.size(); ++i) {
// TODO: Make everything properly std::string.
diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc
index 17873b5..d09e66f 100644
--- a/runtime/base/logging.cc
+++ b/runtime/base/logging.cc
@@ -27,7 +27,7 @@
// Headers for LogMessage::LogLine.
#ifdef ART_TARGET_ANDROID
-#include "cutils/log.h"
+#include <android/log.h>
#include <android/set_abort_message.h>
#else
#include <sys/types.h>
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index 3649111..a968343 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -191,86 +191,6 @@
}
}
-template<size_t kAlignment>
-void SpaceBitmap<kAlignment>::WalkInstanceFields(SpaceBitmap<kAlignment>* visited,
- ObjectCallback* callback, mirror::Object* obj,
- mirror::Class* klass, void* arg)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- // Visit fields of parent classes first.
- mirror::Class* super = klass->GetSuperClass();
- if (super != nullptr) {
- WalkInstanceFields(visited, callback, obj, super, arg);
- }
- // Walk instance fields
- for (ArtField& field : klass->GetIFields()) {
- if (!field.IsPrimitiveType()) {
- mirror::Object* value = field.GetObj(obj);
- if (value != nullptr) {
- WalkFieldsInOrder(visited, callback, value, arg);
- }
- }
- }
-}
-
-template<size_t kAlignment>
-void SpaceBitmap<kAlignment>::WalkFieldsInOrder(SpaceBitmap<kAlignment>* visited,
- ObjectCallback* callback, mirror::Object* obj,
- void* arg) {
- if (visited->Test(obj)) {
- return;
- }
- // visit the object itself
- (*callback)(obj, arg);
- visited->Set(obj);
- // Walk instance fields of all objects
- mirror::Class* klass = obj->GetClass();
- WalkInstanceFields(visited, callback, obj, klass, arg);
- // Walk static fields of a Class
- if (obj->IsClass()) {
- for (ArtField& field : klass->GetSFields()) {
- if (!field.IsPrimitiveType()) {
- mirror::Object* value = field.GetObj(nullptr);
- if (value != nullptr) {
- WalkFieldsInOrder(visited, callback, value, arg);
- }
- }
- }
- } else if (obj->IsObjectArray()) {
- // Walk elements of an object array
- mirror::ObjectArray<mirror::Object>* obj_array = obj->AsObjectArray<mirror::Object>();
- int32_t length = obj_array->GetLength();
- for (int32_t i = 0; i < length; i++) {
- mirror::Object* value = obj_array->Get(i);
- if (value != nullptr) {
- WalkFieldsInOrder(visited, callback, value, arg);
- }
- }
- }
-}
-
-template<size_t kAlignment>
-void SpaceBitmap<kAlignment>::InOrderWalk(ObjectCallback* callback, void* arg) {
- std::unique_ptr<SpaceBitmap<kAlignment>> visited(
- Create("bitmap for in-order walk", reinterpret_cast<uint8_t*>(heap_begin_),
- IndexToOffset(bitmap_size_ / sizeof(intptr_t))));
- CHECK(bitmap_begin_ != nullptr);
- CHECK(callback != nullptr);
- uintptr_t end = Size() / sizeof(intptr_t);
- for (uintptr_t i = 0; i < end; ++i) {
- // Need uint for unsigned shift.
- uintptr_t w = bitmap_begin_[i].LoadRelaxed();
- if (UNLIKELY(w != 0)) {
- uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
- while (w != 0) {
- const size_t shift = CTZ(w);
- mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
- WalkFieldsInOrder(visited.get(), callback, obj, arg);
- w ^= (static_cast<uintptr_t>(1)) << shift;
- }
- }
- }
-}
-
template class SpaceBitmap<kObjectAlignment>;
template class SpaceBitmap<kPageSize>;
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h
index 576f9c7..296663a 100644
--- a/runtime/gc/accounting/space_bitmap.h
+++ b/runtime/gc/accounting/space_bitmap.h
@@ -133,11 +133,6 @@
void Walk(ObjectCallback* callback, void* arg)
REQUIRES_SHARED(Locks::heap_bitmap_lock_);
- // Visits set bits with an in order traversal. The callback is not permitted to change the bitmap
- // bits or max during the traversal.
- void InOrderWalk(ObjectCallback* callback, void* arg)
- REQUIRES_SHARED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
-
// Walk through the bitmaps in increasing address order, and find the object pointers that
// correspond to garbage objects. Call <callback> zero or more times with lists of these object
// pointers. The callback is not permitted to increase the max of either bitmap.
@@ -202,15 +197,6 @@
template<bool kSetBit>
bool Modify(const mirror::Object* obj);
- // For an unvisited object, visit it then all its children found via fields.
- static void WalkFieldsInOrder(SpaceBitmap* visited, ObjectCallback* callback, mirror::Object* obj,
- void* arg) REQUIRES_SHARED(Locks::mutator_lock_);
- // Walk instance fields of the given Class. Separate function to allow recursion on the super
- // class.
- static void WalkInstanceFields(SpaceBitmap<kAlignment>* visited, ObjectCallback* callback,
- mirror::Object* obj, mirror::Class* klass, void* arg)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Backing storage for bitmap.
std::unique_ptr<MemMap> mem_map_;
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc
index 671cb60..0d1839b 100644
--- a/runtime/monitor_android.cc
+++ b/runtime/monitor_android.cc
@@ -21,7 +21,7 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include "cutils/log.h"
+#include <android/log.h>
#define EVENT_LOG_TAG_dvm_lock_sample 20003
diff --git a/tools/jfuzz/run_dex_fuzz_test.py b/tools/jfuzz/run_dex_fuzz_test.py
index 56cdf02..50c4f20 100755
--- a/tools/jfuzz/run_dex_fuzz_test.py
+++ b/tools/jfuzz/run_dex_fuzz_test.py
@@ -26,6 +26,7 @@
os.path.realpath(__file__))))
from common.common import FatalError
+from common.common import GetEnvVariableOrError
from common.common import GetJackClassPath
from common.common import RetCode
from common.common import RunCommand
@@ -54,6 +55,7 @@
self._results_dir = None
self._dexfuzz_dir = None
self._inputs_dir = None
+ self._dexfuzz_env = None
def __enter__(self):
"""On entry, enters new temp directory after saving current directory.
@@ -68,7 +70,14 @@
if self._results_dir is None or self._dexfuzz_dir is None or \
self._inputs_dir is None:
raise FatalError('Cannot obtain temp directory')
+ self._dexfuzz_env = os.environ.copy()
+ self._dexfuzz_env['ANDROID_DATA'] = self._dexfuzz_dir
+ top = GetEnvVariableOrError('ANDROID_BUILD_TOP')
+ self._dexfuzz_env['PATH'] = (top + '/art/tools/bisection_search:' +
+ self._dexfuzz_env['PATH'])
os.chdir(self._dexfuzz_dir)
+ os.mkdir('divergent_programs')
+ os.mkdir('bisection_outputs')
return self
def __exit__(self, etype, evalue, etraceback):
@@ -110,15 +119,15 @@
def RunDexFuzz(self):
"""Starts the DexFuzz testing."""
os.chdir(self._dexfuzz_dir)
- os.environ['ANDROID_DATA'] = self._dexfuzz_dir
dexfuzz_args = ['--inputs=' + self._inputs_dir, '--execute',
'--execute-class=Test', '--repeat=' + str(self._num_tests),
- '--dump-output', '--interpreter', '--optimizing']
+ '--dump-output', '--interpreter', '--optimizing',
+ '--bisection-search']
if self._device is not None:
dexfuzz_args += ['--device=' + self._device, '--allarm']
else:
dexfuzz_args += ['--host'] # Assume host otherwise.
- check_call(['dexfuzz'] + dexfuzz_args)
+ check_call(['dexfuzz'] + dexfuzz_args, env=self._dexfuzz_env)
# TODO: summarize findings.