diff options
author | jgu21 <jinghui.gu@intel.com> | 2014-09-10 06:57:17 -0400 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-09-23 20:11:31 -0700 |
commit | a6da74e941d7cee498ac3880018a1d8dc953c6eb (patch) | |
tree | bb36d90e914f8a842abd7dd854ba168f9441e8db /runtime | |
parent | a20b7b3ecf90bb761d7085403782721f2fb474c5 (diff) | |
download | android_art-a6da74e941d7cee498ac3880018a1d8dc953c6eb.tar.gz android_art-a6da74e941d7cee498ac3880018a1d8dc953c6eb.tar.bz2 android_art-a6da74e941d7cee498ac3880018a1d8dc953c6eb.zip |
ART: Update for split native bridge initialization
Change-Id: I0b93da93251c6b4638de786bf98cf99df07c3fc2
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/native/dalvik_system_ZygoteHooks.cc | 6 | ||||
-rw-r--r-- | runtime/native_bridge_art_interface.cc | 39 | ||||
-rw-r--r-- | runtime/native_bridge_art_interface.h | 14 | ||||
-rw-r--r-- | runtime/runtime.cc | 25 | ||||
-rw-r--r-- | runtime/runtime.h | 14 |
5 files changed, 67 insertions, 31 deletions
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index c3c8c2576e..e469126206 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -111,15 +111,17 @@ static void ZygoteHooks_nativePostForkChild(JNIEnv* env, jclass, jlong token, ji thread->InitAfterFork(); EnableDebugFeatures(debug_flags); - Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload; if (instruction_set != nullptr) { ScopedUtfChars isa_string(env, instruction_set); InstructionSet isa = GetInstructionSetFromString(isa_string.c_str()); + Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload; if (isa != kNone && isa != kRuntimeISA) { action = Runtime::NativeBridgeAction::kInitialize; } + Runtime::Current()->DidForkFromZygote(env, action, isa_string.c_str()); + } else { + Runtime::Current()->DidForkFromZygote(env, Runtime::NativeBridgeAction::kUnload, nullptr); } - Runtime::Current()->DidForkFromZygote(action); } static JNINativeMethod gMethods[] = { diff --git a/runtime/native_bridge_art_interface.cc b/runtime/native_bridge_art_interface.cc index 453c92f495..fcd11ed442 100644 --- a/runtime/native_bridge_art_interface.cc +++ b/runtime/native_bridge_art_interface.cc @@ -16,6 +16,9 @@ #include "native_bridge_art_interface.h" +#include "nativebridge/native_bridge.h" + +#include "base/logging.h" #include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "scoped_thread_state_change.h" @@ -91,4 +94,40 @@ uint32_t GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* methods, return count; } +// Native bridge library runtime callbacks. They represent the runtime interface to native bridge. +// +// The interface is expected to expose the following methods: +// getMethodShorty(): in the case of native method calling JNI native function CallXXXXMethodY(), +// native bridge calls back to VM for the shorty of the method so that it can prepare based on +// host calling convention. +// getNativeMethodCount() and getNativeMethods(): in case of JNI function UnregisterNatives(), +// native bridge can call back to get all native methods of specified class so that all +// corresponding trampolines can be destroyed. +static android::NativeBridgeRuntimeCallbacks native_bridge_art_callbacks_ { + GetMethodShorty, GetNativeMethodCount, GetNativeMethods +}; + +void LoadNativeBridge(std::string& native_bridge_library_filename) { + android::LoadNativeBridge(native_bridge_library_filename.c_str(), &native_bridge_art_callbacks_); + VLOG(startup) << "Runtime::Setup native bridge library: " + << (native_bridge_library_filename.empty() ? "(empty)" : native_bridge_library_filename); +} + +void PreInitializeNativeBridge(std::string dir) { + VLOG(startup) << "Runtime::Pre-initialize native bridge"; + if (unshare(CLONE_NEWNS) == -1) { + LOG(WARNING) << "Could not create mount namespace."; + return; + } + android::PreInitializeNativeBridge(dir.c_str(), GetInstructionSetString(kRuntimeISA)); +} + +void InitializeNativeBridge(JNIEnv* env, const char* instruction_set) { + android::InitializeNativeBridge(env, instruction_set); +} + +void UnloadNativeBridge() { + android::UnloadNativeBridge(); +} + }; // namespace art diff --git a/runtime/native_bridge_art_interface.h b/runtime/native_bridge_art_interface.h index 08735c8955..42f0ed25e6 100644 --- a/runtime/native_bridge_art_interface.h +++ b/runtime/native_bridge_art_interface.h @@ -19,15 +19,21 @@ #include <jni.h> #include <stdint.h> +#include <string> namespace art { -const char* GetMethodShorty(JNIEnv* env, jmethodID mid); +// Mirror libnativebridge interface. Done to have the ART callbacks out of line, and not require +// the system/core header file in other files. -uint32_t GetNativeMethodCount(JNIEnv* env, jclass clazz); +void LoadNativeBridge(std::string& native_bridge_library_filename); -uint32_t GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* methods, - uint32_t method_count); +// This is mostly for testing purposes, as in a full system this is called by Zygote code. +void PreInitializeNativeBridge(std::string dir); + +void InitializeNativeBridge(JNIEnv* env, const char* instruction_set); + +void UnloadNativeBridge(); }; // namespace art diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 9b24bec574..0edf116c00 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -143,8 +143,7 @@ Runtime::Runtime() target_sdk_version_(0), implicit_null_checks_(false), implicit_so_checks_(false), - implicit_suspend_checks_(false), - native_bridge_art_callbacks_({GetMethodShorty, GetNativeMethodCount, GetNativeMethods}) { + implicit_suspend_checks_(false) { } Runtime::~Runtime() { @@ -418,18 +417,23 @@ bool Runtime::Start() { Thread::FinishStartup(); + system_class_loader_ = CreateSystemClassLoader(); + if (is_zygote_) { if (!InitZygote()) { return false; } } else { - DidForkFromZygote(NativeBridgeAction::kInitialize); + bool have_native_bridge = !native_bridge_library_filename_.empty(); + if (have_native_bridge) { + PreInitializeNativeBridge("."); + } + DidForkFromZygote(self->GetJniEnv(), have_native_bridge ? NativeBridgeAction::kInitialize : + NativeBridgeAction::kUnload, GetInstructionSetString(kRuntimeISA)); } StartDaemonThreads(); - system_class_loader_ = CreateSystemClassLoader(); - { ScopedObjectAccess soa(self); self->GetJniEnv()->locals.AssertEmpty(); @@ -501,16 +505,16 @@ bool Runtime::InitZygote() { #endif } -void Runtime::DidForkFromZygote(NativeBridgeAction action) { +void Runtime::DidForkFromZygote(JNIEnv* env, NativeBridgeAction action, const char* isa) { is_zygote_ = false; switch (action) { case NativeBridgeAction::kUnload: - android::UnloadNativeBridge(); + UnloadNativeBridge(); break; case NativeBridgeAction::kInitialize: - android::InitializeNativeBridge(); + InitializeNativeBridge(env, isa); break; } @@ -870,10 +874,7 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) // DidForkFromZygote(kInitialize) -> try to initialize any native bridge given. // No-op wrt native bridge. native_bridge_library_filename_ = options->native_bridge_library_filename_; - android::LoadNativeBridge(native_bridge_library_filename_.c_str(), &native_bridge_art_callbacks_); - VLOG(startup) << "Runtime::Setup native bridge library: " - << (native_bridge_library_filename_.empty() ? - "(empty)" : native_bridge_library_filename_); + LoadNativeBridge(native_bridge_library_filename_); VLOG(startup) << "Runtime::Init exiting"; return true; diff --git a/runtime/runtime.h b/runtime/runtime.h index cfb1abc477..9a8235dfc6 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -32,7 +32,6 @@ #include "instrumentation.h" #include "instruction_set.h" #include "jobject_comparator.h" -#include "nativebridge/native_bridge.h" #include "object_callbacks.h" #include "offsets.h" #include "profiler_options.h" @@ -398,7 +397,7 @@ class Runtime { }; void PreZygoteFork(); bool InitZygote(); - void DidForkFromZygote(NativeBridgeAction action); + void DidForkFromZygote(JNIEnv* env, NativeBridgeAction action, const char* isa); const instrumentation::Instrumentation* GetInstrumentation() const { return &instrumentation_; @@ -648,17 +647,6 @@ class Runtime { // the native bridge to load it and then gets the trampoline for the entry to native activity. std::string native_bridge_library_filename_; - // Native bridge library runtime callbacks. They represent the runtime interface to native bridge. - // - // The interface is expected to expose the following methods: - // getMethodShorty(): in the case of native method calling JNI native function CallXXXXMethodY(), - // native bridge calls back to VM for the shorty of the method so that it can prepare based on - // host calling convention. - // getNativeMethodCount() and getNativeMethods(): in case of JNI function UnregisterNatives(), - // native bridge can call back to get all native methods of specified class so that all - // corresponding trampolines can be destroyed. - android::NativeBridgeRuntimeCallbacks native_bridge_art_callbacks_; - DISALLOW_COPY_AND_ASSIGN(Runtime); }; |