summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-07-25 02:32:19 -0700
committerAndreas Gampe <agampe@google.com>2014-07-26 18:35:08 -0700
commit855564b83db7b106d2995d0e784f1f4b62e52371 (patch)
treede3caa3f36b24acb9279a8cb85d4879baeed1798
parent3bcac48f23094fa0f46315a080ec47fc368fd4c2 (diff)
downloadart-855564b83db7b106d2995d0e784f1f4b62e52371.zip
art-855564b83db7b106d2995d0e784f1f4b62e52371.tar.gz
art-855564b83db7b106d2995d0e784f1f4b62e52371.tar.bz2
ART: Native bridge command-line parameter
Add a command-line parameter for the native bridge library, slight refactor/cleanup. Add run-test 115 to test the native bridge interface. Currently the tests are black-listed for the target, as the setup for the test is too complicated in the current infrastructure. Change-Id: I6ccf19485e8c30b96e9f2fd5425278cb1ebd403f
-rw-r--r--runtime/native_bridge.cc64
-rw-r--r--runtime/native_bridge.h21
-rw-r--r--runtime/parsed_options.cc4
-rw-r--r--runtime/parsed_options.h1
-rw-r--r--runtime/runtime.cc4
-rw-r--r--test/115-native-bridge/expected.txt13
-rw-r--r--test/115-native-bridge/info.txt1
-rw-r--r--test/115-native-bridge/nativebridge.cc114
-rw-r--r--test/115-native-bridge/run29
-rw-r--r--test/115-native-bridge/src/NativeBridgeMain.java160
-rw-r--r--test/Android.libnativebridgetest.mk87
-rw-r--r--test/Android.run-test.mk42
-rwxr-xr-xtest/etc/host-run-test-jar9
-rwxr-xr-xtest/run-test3
14 files changed, 527 insertions, 25 deletions
diff --git a/runtime/native_bridge.cc b/runtime/native_bridge.cc
index de04a99..ad26ee4 100644
--- a/runtime/native_bridge.cc
+++ b/runtime/native_bridge.cc
@@ -35,7 +35,7 @@
namespace art {
// Is native-bridge support enabled?
-static constexpr bool kNativeBridgeEnabled = false;
+static constexpr bool kNativeBridgeEnabled = true;
// Default library name for native-bridge.
static constexpr const char* kDefaultNativeBridge = "libnativebridge.so";
@@ -55,9 +55,6 @@ static constexpr const char* kNativeBridgeInterfaceSymbol = "NativeBridgeItf";
// ART interfaces to native-bridge.
struct NativeBridgeArtCallbacks {
- // Log utility, reserve unused.
- int (*logger)(int prio, const char* tag, const char* fmt, ...);
-
// Get shorty of a Java method. The shorty is supposed to be persistent in memory.
//
// Parameters:
@@ -190,71 +187,96 @@ static int GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
}
NativeBridgeArtCallbacks NativeBridgeArtItf = {
- nullptr,
GetMethodShorty,
GetNativeMethodCount,
GetNativeMethods
};
-bool NativeBridge::Init() {
+void NativeBridge::SetNativeBridgeLibraryString(std::string& native_bridge_library_string) {
+ native_bridge_library_string_ = native_bridge_library_string;
+ // TODO: when given an empty string, set initialized_ to true and available_ to false. This
+ // change is dependent on the property removal in Initialize().
+}
+
+bool NativeBridge::Initialize() {
if (!kNativeBridgeEnabled) {
return false;
}
MutexLock mu(Thread::Current(), lock_);
- if (!initialized_) {
- const char* libnb_path = kDefaultNativeBridge;
+ if (initialized_) {
+ // Somebody did it before.
+ return available_;
+ }
+
+ available_ = false;
+
+ const char* libnb_path;
+
+ if (!native_bridge_library_string_.empty()) {
+ libnb_path = native_bridge_library_string_.c_str();
+ } else {
+ // TODO: Remove this once the frameworks side is completely implemented.
+
+ libnb_path = kDefaultNativeBridge;
#ifdef HAVE_ANDROID_OS
char prop_buf[PROP_VALUE_MAX];
property_get(kPropEnableNativeBridge, prop_buf, "false");
- if (strcmp(prop_buf, "true") != 0)
+ if (strcmp(prop_buf, "true") != 0) {
+ initialized_ = true;
return false;
+ }
// If prop persist.native.bridge set, overwrite the default name.
int name_len = property_get(kPropNativeBridge, prop_buf, kDefaultNativeBridge);
if (name_len > 0)
libnb_path = prop_buf;
#endif
- void* handle = dlopen(libnb_path, RTLD_LAZY);
- if (handle == nullptr)
- return false;
+ }
+ void* handle = dlopen(libnb_path, RTLD_LAZY);
+ if (handle != nullptr) {
callbacks_ = reinterpret_cast<NativeBridgeCallbacks*>(dlsym(handle,
kNativeBridgeInterfaceSymbol));
- if (callbacks_ == nullptr) {
- dlclose(handle);
- return false;
+
+ if (callbacks_ != nullptr) {
+ available_ = callbacks_->initialize(&NativeBridgeArtItf);
}
- callbacks_->initialize(&NativeBridgeArtItf);
- initialized_ = true;
+ if (!available_) {
+ dlclose(handle);
+ }
}
- return initialized_;
+ initialized_ = true;
+
+ return available_;
}
void* NativeBridge::LoadLibrary(const char* libpath, int flag) {
- if (Init())
+ if (Initialize())
return callbacks_->loadLibrary(libpath, flag);
return nullptr;
}
void* NativeBridge::GetTrampoline(void* handle, const char* name, const char* shorty,
uint32_t len) {
- if (Init())
+ if (Initialize())
return callbacks_->getTrampoline(handle, name, shorty, len);
return nullptr;
}
bool NativeBridge::IsSupported(const char* libpath) {
- if (Init())
+ if (Initialize())
return callbacks_->isSupported(libpath);
return false;
}
+bool NativeBridge::available_ = false;
bool NativeBridge::initialized_ = false;
Mutex NativeBridge::lock_("native bridge lock");
+std::string NativeBridge::native_bridge_library_string_ = "";
NativeBridgeCallbacks* NativeBridge::callbacks_ = nullptr;
}; // namespace art
diff --git a/runtime/native_bridge.h b/runtime/native_bridge.h
index dd895d2..3d20fe4 100644
--- a/runtime/native_bridge.h
+++ b/runtime/native_bridge.h
@@ -19,23 +19,38 @@
#include "base/mutex.h"
+#include <string>
+
namespace art {
struct NativeBridgeCallbacks;
class NativeBridge {
public:
+ // Initialize the native bridge, if any. Should be called by Runtime::Init(). An empty string
+ // signals that we do not want to load a native bridge.
+ static void SetNativeBridgeLibraryString(std::string& native_bridge_library_string);
+
// Load a shared library that is supported by the native-bridge.
static void* LoadLibrary(const char* libpath, int flag);
// Get a native-bridge trampoline for specified native method.
static void* GetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len);
// True if native library is valid and is for an ABI that is supported by native-bridge.
- static bool IsSupported(const char* libpath);
+ static bool IsSupported(const char* libpath);
private:
- static bool Init();
- static bool initialized_ GUARDED_BY(lock_);
+ static bool Initialize();
+
+ // The library name we are supposed to load.
+ static std::string native_bridge_library_string_;
+
+ // Whether we have already initialized (or tried to).
+ static bool initialized_ GUARDED_BY(lock_);
static Mutex lock_;
+
+ // Whether a native bridge is available (loaded and ready).
+ static bool available_;
+
static NativeBridgeCallbacks* callbacks_;
};
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 8d0aff8..49f6585 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -596,6 +596,10 @@ bool ParsedOptions::Parse(const RuntimeOptions& options, bool ignore_unrecognize
Usage("Unknown -Xverify option %s\n", verify_mode.c_str());
return false;
}
+ } else if (StartsWith(option, "-XX:NativeBridge=")) {
+ if (!ParseStringAfterChar(option, '=', &native_bridge_library_string_)) {
+ return false;
+ }
} else if (StartsWith(option, "-ea") ||
StartsWith(option, "-da") ||
StartsWith(option, "-enableassertions") ||
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index 29d5494..668ed9e 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -45,6 +45,7 @@ class ParsedOptions {
std::string image_;
bool check_jni_;
std::string jni_trace_;
+ std::string native_bridge_library_string_;
CompilerCallbacks* compiler_callbacks_;
bool is_zygote_;
// TODO Change this to true when we want it on by default.
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index b7eae85..1cbf841 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -63,6 +63,7 @@
#include "mirror/stack_trace_element.h"
#include "mirror/throwable.h"
#include "monitor.h"
+#include "native_bridge.h"
#include "parsed_options.h"
#include "oat_file.h"
#include "quick/quick_method_frame_info.h"
@@ -718,6 +719,9 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized)
pre_allocated_OutOfMemoryError_ = self->GetException(NULL);
self->ClearException();
+ // Look for a native bridge.
+ NativeBridge::SetNativeBridgeLibraryString(options->native_bridge_library_string_);
+
VLOG(startup) << "Runtime::Init exiting";
return true;
}
diff --git a/test/115-native-bridge/expected.txt b/test/115-native-bridge/expected.txt
new file mode 100644
index 0000000..f852620
--- /dev/null
+++ b/test/115-native-bridge/expected.txt
@@ -0,0 +1,13 @@
+Ready for native bridge tests.
+Native bridge initialized.
+Checking for support.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
+Getting trampoline.
diff --git a/test/115-native-bridge/info.txt b/test/115-native-bridge/info.txt
new file mode 100644
index 0000000..ccac7ae
--- /dev/null
+++ b/test/115-native-bridge/info.txt
@@ -0,0 +1 @@
+Test for the native bridge interface.
diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc
new file mode 100644
index 0000000..bd3ae13
--- /dev/null
+++ b/test/115-native-bridge/nativebridge.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+// A simple implementation of the native-bridge interface.
+
+#include <algorithm>
+#include <dlfcn.h>
+#include <vector>
+
+#include "jni.h"
+#include "stdio.h"
+#include "string.h"
+#include "unistd.h"
+
+#include "native_bridge.h"
+
+
+// Native bridge interfaces...
+
+struct NativeBridgeArtCallbacks {
+ const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid);
+ int (*getNativeMethodCount)(JNIEnv* env, jclass clazz);
+ int (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
+ uint32_t method_count);
+};
+
+struct NativeBridgeCallbacks {
+ bool (*initialize)(NativeBridgeArtCallbacks* art_cbs);
+ void* (*loadLibrary)(const char* libpath, int flag);
+ void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len);
+ bool (*isSupported)(const char* libpath);
+};
+
+
+
+static std::vector<void*> symbols;
+
+// NativeBridgeCallbacks implementations
+extern "C" bool native_bridge_initialize(NativeBridgeArtCallbacks* art_cbs) {
+ printf("Native bridge initialized.\n");
+ return true;
+}
+
+extern "C" void* native_bridge_loadLibrary(const char* libpath, int flag) {
+ size_t len = strlen(libpath);
+ char* tmp = new char[len + 10];
+ strncpy(tmp, libpath, len);
+ tmp[len - 3] = '2';
+ tmp[len - 2] = '.';
+ tmp[len - 1] = 's';
+ tmp[len] = 'o';
+ tmp[len + 1] = 0;
+ void* handle = dlopen(tmp, flag);
+ delete[] tmp;
+
+ if (handle == nullptr) {
+ printf("Handle = nullptr!\n");
+ printf("Was looking for %s.\n", libpath);
+ printf("Error = %s.\n", dlerror());
+ char cwd[1024];
+ if (getcwd(cwd, sizeof(cwd)) != nullptr) {
+ printf("Current working dir: %s\n", cwd);
+ }
+ }
+ return handle;
+}
+
+extern "C" void* native_bridge_getTrampoline(void* handle, const char* name, const char* shorty,
+ uint32_t len) {
+ printf("Getting trampoline.\n");
+
+ // The name here is actually the JNI name, so we can directly do the lookup.
+ void* sym = dlsym(handle, name);
+ if (sym != nullptr) {
+ symbols.push_back(sym);
+ }
+
+ // As libarttest is the same arch as the host, we can actually directly use the code and do not
+ // need to create a trampoline. :-)
+ return sym;
+}
+
+extern "C" bool native_bridge_isSupported(const char* libpath) {
+ printf("Checking for support.\n");
+
+ if (libpath == nullptr) {
+ return false;
+ }
+ // We don't want to hijack javacore. So we should get libarttest...
+ return strcmp(libpath, "libjavacore.so") != 0;
+}
+
+NativeBridgeCallbacks NativeBridgeItf {
+ .initialize = &native_bridge_initialize,
+ .loadLibrary = &native_bridge_loadLibrary,
+ .getTrampoline = &native_bridge_getTrampoline,
+ .isSupported = &native_bridge_isSupported
+};
+
+
+
diff --git a/test/115-native-bridge/run b/test/115-native-bridge/run
new file mode 100644
index 0000000..e475cd6
--- /dev/null
+++ b/test/115-native-bridge/run
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 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.
+
+ARGS=${@}
+
+# Use libnativebridgetest as a native bridge, start NativeBridgeMain (Main is JniTest main file).
+LIBPATH=$(echo ${ARGS} | sed -r 's/.*Djava.library.path=([^ ]*) .*/\1/')
+cp ${LIBPATH}/libnativebridgetest.so .
+touch libarttest.so
+cp ${LIBPATH}/libarttest.so libarttest2.so
+
+# pwd likely has /, so it's a pain to put that into a sed rule.
+LEFT=$(echo ${ARGS} | sed -r 's/-Djava.library.path.*//')
+RIGHT=$(echo ${ARGS} | sed -r 's/.*Djava.library.path[^ ]* //')
+MODARGS="${LEFT} -Djava.library.path=`pwd` ${RIGHT}"
+exec ${RUN} --runtime-option -XX:NativeBridge=libnativebridgetest.so ${MODARGS} NativeBridgeMain
diff --git a/test/115-native-bridge/src/NativeBridgeMain.java b/test/115-native-bridge/src/NativeBridgeMain.java
new file mode 100644
index 0000000..a531f92
--- /dev/null
+++ b/test/115-native-bridge/src/NativeBridgeMain.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+import java.lang.reflect.Method;
+
+// This is named Main as it is a copy of JniTest, so that we can re-use the native implementations
+// from libarttest.
+class Main {
+ public static void main(String[] args) {
+ testFindClassOnAttachedNativeThread();
+ testFindFieldOnAttachedNativeThread();
+ testCallStaticVoidMethodOnSubClass();
+ testGetMirandaMethod();
+ testZeroLengthByteBuffers();
+ testByteMethod();
+ testShortMethod();
+ testBooleanMethod();
+ testCharMethod();
+ }
+
+ public static native void testFindClassOnAttachedNativeThread();
+
+ public static boolean testFindFieldOnAttachedNativeThreadField;
+
+ public static void testFindFieldOnAttachedNativeThread() {
+ testFindFieldOnAttachedNativeThreadNative();
+ if (!testFindFieldOnAttachedNativeThreadField) {
+ throw new AssertionError();
+ }
+ }
+
+ private static native void testFindFieldOnAttachedNativeThreadNative();
+
+ private static void testCallStaticVoidMethodOnSubClass() {
+ testCallStaticVoidMethodOnSubClassNative();
+ if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
+ throw new AssertionError();
+ }
+ }
+
+ private static native void testCallStaticVoidMethodOnSubClassNative();
+
+ private static class testCallStaticVoidMethodOnSubClass_SuperClass {
+ private static boolean executed = false;
+ private static void execute() {
+ executed = true;
+ }
+ }
+
+ private static class testCallStaticVoidMethodOnSubClass_SubClass
+ extends testCallStaticVoidMethodOnSubClass_SuperClass {
+ }
+
+ private static native Method testGetMirandaMethodNative();
+
+ private static void testGetMirandaMethod() {
+ Method m = testGetMirandaMethodNative();
+ if (m.getDeclaringClass() != testGetMirandaMethod_MirandaInterface.class) {
+ throw new AssertionError();
+ }
+ }
+
+ private static native void testZeroLengthByteBuffers();
+
+ private static abstract class testGetMirandaMethod_MirandaAbstract implements testGetMirandaMethod_MirandaInterface {
+ public boolean inAbstract() {
+ return true;
+ }
+ }
+
+ private static interface testGetMirandaMethod_MirandaInterface {
+ public boolean inInterface();
+ }
+
+ // Test sign-extension for values < 32b
+
+ native static byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7,
+ byte b8, byte b9, byte b10);
+
+ public static void testByteMethod() {
+ byte returns[] = { 0, 1, 2, 127, -1, -2, -128 };
+ for (int i = 0; i < returns.length; i++) {
+ byte result = byteMethod((byte)i, (byte)2, (byte)(-3), (byte)4, (byte)(-5), (byte)6,
+ (byte)(-7), (byte)8, (byte)(-9), (byte)10);
+ if (returns[i] != result) {
+ System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
+ throw new AssertionError();
+ }
+ }
+ }
+
+ native static short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7,
+ short s8, short s9, short s10);
+
+ private static void testShortMethod() {
+ short returns[] = { 0, 1, 2, 127, 32767, -1, -2, -128, -32768 };
+ for (int i = 0; i < returns.length; i++) {
+ short result = shortMethod((short)i, (short)2, (short)(-3), (short)4, (short)(-5), (short)6,
+ (short)(-7), (short)8, (short)(-9), (short)10);
+ if (returns[i] != result) {
+ System.out.println("Run " + i + " with " + returns[i] + " vs " + result);
+ throw new AssertionError();
+ }
+ }
+ }
+
+ // Test zero-extension for values < 32b
+
+ native static boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7,
+ boolean b8, boolean b9, boolean b10);
+
+ public static void testBooleanMethod() {
+ if (booleanMethod(false, true, false, true, false, true, false, true, false, true)) {
+ throw new AssertionError();
+ }
+
+ if (!booleanMethod(true, true, false, true, false, true, false, true, false, true)) {
+ throw new AssertionError();
+ }
+ }
+
+ native static char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7,
+ char c8, char c9, char c10);
+
+ private static void testCharMethod() {
+ char returns[] = { (char)0, (char)1, (char)2, (char)127, (char)255, (char)256, (char)15000,
+ (char)34000 };
+ for (int i = 0; i < returns.length; i++) {
+ char result = charMethod((char)i, 'a', 'b', 'c', '0', '1', '2', (char)1234, (char)2345,
+ (char)3456);
+ if (returns[i] != result) {
+ System.out.println("Run " + i + " with " + (int)returns[i] + " vs " + (int)result);
+ throw new AssertionError();
+ }
+ }
+ }
+}
+
+public class NativeBridgeMain {
+ static public void main(String[] args) throws Exception {
+ System.out.println("Ready for native bridge tests.");
+
+ System.loadLibrary("arttest");
+
+ Main.main(null);
+ }
+}
diff --git a/test/Android.libnativebridgetest.mk b/test/Android.libnativebridgetest.mk
new file mode 100644
index 0000000..dd7255a
--- /dev/null
+++ b/test/Android.libnativebridgetest.mk
@@ -0,0 +1,87 @@
+#
+# Copyright (C) 2014 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include art/build/Android.common_build.mk
+
+LIBNATIVEBRIDGETEST_COMMON_SRC_FILES := \
+ 115-native-bridge/nativebridge.cc
+
+ART_TARGET_LIBNATIVEBRIDGETEST_$(ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libnativebridgetest.so
+ifdef TARGET_2ND_ARCH
+ ART_TARGET_LIBNATIVEBRIDGETEST_$(2ND_ART_PHONY_TEST_TARGET_SUFFIX) += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libnativebridgetest.so
+endif
+
+# $(1): target or host
+define build-libnativebridgetest
+ ifneq ($(1),target)
+ ifneq ($(1),host)
+ $$(error expected target or host for argument 1, received $(1))
+ endif
+ endif
+
+ art_target_or_host := $(1)
+
+ include $(CLEAR_VARS)
+ LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
+ LOCAL_MODULE := libnativebridgetest
+ ifeq ($$(art_target_or_host),target)
+ LOCAL_MODULE_TAGS := tests
+ endif
+ LOCAL_SRC_FILES := $(LIBNATIVEBRIDGETEST_COMMON_SRC_FILES)
+ LOCAL_SHARED_LIBRARIES += libartd
+ LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime
+ LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+ LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.libnativebridgetest.mk
+ include external/libcxx/libcxx.mk
+ ifeq ($$(art_target_or_host),target)
+ $(call set-target-local-clang-vars)
+ $(call set-target-local-cflags-vars,debug)
+ LOCAL_SHARED_LIBRARIES += libdl libcutils
+ LOCAL_STATIC_LIBRARIES := libgtest
+ LOCAL_MULTILIB := both
+ LOCAL_MODULE_PATH_32 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_32)
+ LOCAL_MODULE_PATH_64 := $(ART_TARGET_TEST_OUT)/$(ART_TARGET_ARCH_64)
+ LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
+ include $(BUILD_SHARED_LIBRARY)
+ else # host
+ LOCAL_CLANG := $(ART_HOST_CLANG)
+ LOCAL_CFLAGS := $(ART_HOST_CFLAGS) $(ART_HOST_DEBUG_CFLAGS)
+ LOCAL_STATIC_LIBRARIES := libcutils
+ LOCAL_LDLIBS += -ldl -lpthread
+ ifeq ($(HOST_OS),linux)
+ LOCAL_LDLIBS += -lrt
+ endif
+ LOCAL_IS_HOST_MODULE := true
+ LOCAL_MULTILIB := both
+ include $(BUILD_HOST_SHARED_LIBRARY)
+ endif
+
+ # Clear locally used variables.
+ art_target_or_host :=
+endef
+
+ifeq ($(ART_BUILD_TARGET),true)
+ $(eval $(call build-libnativebridgetest,target))
+endif
+ifeq ($(ART_BUILD_HOST),true)
+ $(eval $(call build-libnativebridgetest,host))
+endif
+
+# Clear locally used variables.
+LOCAL_PATH :=
+LIBNATIVEBRIDGETEST_COMMON_SRC_FILES :=
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 78493dc..6fa5df1 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -40,6 +40,16 @@ define all-run-test-names
test-art-target-run-test$(2)-interpreter$(3)-$(1)64
endef # all-run-test-names
+# Subset of the above for target only.
+define all-run-test-target-names
+ test-art-target-run-test$(2)-default$(3)-$(1)32 \
+ test-art-target-run-test$(2)-optimizing$(3)-$(1)32 \
+ test-art-target-run-test$(2)-interpreter$(3)-$(1)32 \
+ test-art-target-run-test$(2)-default$(3)-$(1)64 \
+ test-art-target-run-test$(2)-optimizing$(3)-$(1)64 \
+ test-art-target-run-test$(2)-interpreter$(3)-$(1)64
+endef # all-run-test-target-names
+
# Tests that are timing sensitive and flaky on heavily loaded systems.
TEST_ART_TIMING_SENSITIVE_RUN_TESTS := \
053-wait-some \
@@ -120,6 +130,27 @@ ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_BROKEN_GCSTRESS_RUN_TESTS),
ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_BROKEN_GCSTRESS_RUN_TESTS), $(call all-run-test-names,$(test),-gcstress,-norelocate))
ART_TEST_KNOWN_BROKEN += $(foreach test, $(TEST_ART_BROKEN_GCSTRESS_RUN_TESTS), $(call all-run-test-names,$(test),-gcstress,))
+# 115-native-bridge setup is complicated. Need to implement it correctly for the target.
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,,)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-trace,)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcverify,)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcstress,)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,,-relocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-trace,-relocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcverify,-relocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcstress,-relocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,,-norelocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-trace,-norelocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcverify,-norelocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcstress,-norelocate)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,,-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-trace,-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcverify,-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcstress,-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,,-no-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-trace,-no-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcverify,-no-prebuild)
+ART_TEST_KNOWN_BROKEN += $(call all-run-test-target-names,115-native-bridge,-gcstress,-no-prebuild)
# The path where build only targets will be output, e.g.
# out/target/product/generic_x86_64/obj/PACKAGING/art-run-tests_intermediates/DATA
@@ -290,16 +321,24 @@ ifdef TARGET_2ND_ARCH
TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libarttest.so
endif
+# Also need libnativebridgetest.
+TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_ARCH)/libnativebridgetest.so
+ifdef TARGET_2ND_ARCH
+TEST_ART_TARGET_SYNC_DEPS += $(ART_TARGET_TEST_OUT)/$(TARGET_2ND_ARCH)/libnativebridgetest.so
+endif
+
# All tests require the host executables and the core images.
ART_TEST_HOST_RUN_TEST_DEPENDENCIES := \
$(ART_HOST_EXECUTABLES) \
$(ART_HOST_OUT_SHARED_LIBRARIES)/libarttest$(ART_HOST_SHLIB_EXTENSION) \
+ $(ART_HOST_OUT_SHARED_LIBRARIES)/libnativebridgetest$(ART_HOST_SHLIB_EXTENSION) \
$(ART_HOST_OUT_SHARED_LIBRARIES)/libjavacore$(ART_HOST_SHLIB_EXTENSION) \
$(HOST_CORE_IMG_OUT)
ifneq ($(HOST_PREFER_32_BIT),true)
ART_TEST_HOST_RUN_TEST_DEPENDENCIES += \
$(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libarttest$(ART_HOST_SHLIB_EXTENSION) \
+ $(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libnativebridgetest$(ART_HOST_SHLIB_EXTENSION) \
$(2ND_ART_HOST_OUT_SHARED_LIBRARIES)/libjavacore$(ART_HOST_SHLIB_EXTENSION) \
$(2ND_HOST_CORE_IMG_OUT)
endif
@@ -831,6 +870,9 @@ endif
# include libarttest build rules.
include $(LOCAL_PATH)/Android.libarttest.mk
+# Include libnativebridgetest build rules.
+include art/test/Android.libnativebridgetest.mk
+
define-test-art-run-test :=
define-test-art-run-test-group-rule :=
define-test-art-run-test-group :=
diff --git a/test/etc/host-run-test-jar b/test/etc/host-run-test-jar
index d72e997..2241f85 100755
--- a/test/etc/host-run-test-jar
+++ b/test/etc/host-run-test-jar
@@ -24,6 +24,7 @@ FLAGS=""
COMPILER_FLAGS=""
BUILD_BOOT_OPT=""
exe="${ANDROID_HOST_OUT}/bin/dalvikvm32"
+main="Main"
while true; do
if [ "x$1" = "x--quiet" ]; then
@@ -112,6 +113,12 @@ while true; do
fi
done
+if [ "x$1" = "x" ] ; then
+ main="Main"
+else
+ main="$1"
+fi
+
msg "------------------------------"
export ANDROID_PRINTF_LOG=brief
@@ -171,7 +178,7 @@ else
fi
JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni"
-cmdline="$INVOKE_WITH $gdb $exe $gdbargs -XXlib:$LIB $JNI_OPTS $FLAGS $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar Main"
+cmdline="$INVOKE_WITH $gdb $exe $gdbargs -XXlib:$LIB $JNI_OPTS $FLAGS $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar $main"
if [ "$DEV_MODE" = "y" ]; then
if [ "$PREBUILD" = "y" ]; then
echo "$mkdir_cmd && $prebuild_cmd && $cmdline"
diff --git a/test/run-test b/test/run-test
index 0e42efe..ae613d9 100755
--- a/test/run-test
+++ b/test/run-test
@@ -377,6 +377,9 @@ if echo "$test_dir" | grep 089; then
file_size_limit=5120
elif echo "$test_dir" | grep 083; then
file_size_limit=5120
+elif echo "$test_dir" | grep 115; then
+# Native bridge test copies libarttest.so into its directory, which needs 2MB already.
+ file_size_limit=5120
fi
if ! ulimit -S "$file_size_limit"; then
echo "ulimit file size setting failed"