From 855564b83db7b106d2995d0e784f1f4b62e52371 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Fri, 25 Jul 2014 02:32:19 -0700 Subject: [PATCH] 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 --- runtime/native_bridge.cc | 64 ++++++--- runtime/native_bridge.h | 21 ++- runtime/parsed_options.cc | 4 + runtime/parsed_options.h | 1 + runtime/runtime.cc | 4 + test/115-native-bridge/expected.txt | 13 ++ test/115-native-bridge/info.txt | 1 + test/115-native-bridge/nativebridge.cc | 114 ++++++++++++++++ test/115-native-bridge/run | 29 ++++ test/115-native-bridge/src/NativeBridgeMain.java | 160 +++++++++++++++++++++++ test/Android.libnativebridgetest.mk | 87 ++++++++++++ test/Android.run-test.mk | 42 ++++++ test/etc/host-run-test-jar | 9 +- test/run-test | 3 + 14 files changed, 527 insertions(+), 25 deletions(-) create mode 100644 test/115-native-bridge/expected.txt create mode 100644 test/115-native-bridge/info.txt create mode 100644 test/115-native-bridge/nativebridge.cc create mode 100644 test/115-native-bridge/run create mode 100644 test/115-native-bridge/src/NativeBridgeMain.java create mode 100644 test/Android.libnativebridgetest.mk diff --git a/runtime/native_bridge.cc b/runtime/native_bridge.cc index de04a99d6..ad26ee4e9 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(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 dd895d2ba..3d20fe43f 100644 --- a/runtime/native_bridge.h +++ b/runtime/native_bridge.h @@ -19,23 +19,38 @@ #include "base/mutex.h" +#include + 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 8d0aff802..49f658507 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 29d54945a..668ed9ed2 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 b7eae850b..1cbf841df 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 000000000..f852620b3 --- /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 000000000..ccac7ae8d --- /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 000000000..bd3ae13a3 --- /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 +#include +#include + +#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 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 000000000..e475cd6b8 --- /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 000000000..a531f9230 --- /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 000000000..dd7255a4c --- /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 78493dc0f..6fa5df122 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 d72e997fd..2241f8569 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 0e42efe3d..ae613d9a6 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" -- 2.11.0