From 6be67eeedbe60afce42300ae3e7f0e7180a96efa Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Tue, 2 Sep 2014 21:22:18 -0700 Subject: [PATCH] ART: Change ART for new native bridge sequence Initialize or unload after a fork. Change-Id: I5a20de1cb68dd1802937b369b14c50c9c1031c67 --- runtime/native/dalvik_system_ZygoteHooks.cc | 18 ++++++++++--- runtime/runtime.cc | 42 ++++++++++++++++++++++++++--- runtime/runtime.h | 6 ++++- test/115-native-bridge/expected.txt | 2 +- 4 files changed, 60 insertions(+), 8 deletions(-) diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index df6055dac..c3c8c2576 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -17,9 +17,11 @@ #include #include "debugger.h" +#include "instruction_set.h" #include "java_vm_ext.h" #include "jni_internal.h" #include "JNIHelp.h" +#include "ScopedUtfChars.h" #include "thread-inl.h" #if defined(HAVE_PRCTL) @@ -102,17 +104,27 @@ static jlong ZygoteHooks_nativePreFork(JNIEnv* env, jclass) { return reinterpret_cast(self); } -static void ZygoteHooks_nativePostForkChild(JNIEnv* env, jclass, jlong token, jint debug_flags) { +static void ZygoteHooks_nativePostForkChild(JNIEnv* env, jclass, jlong token, jint debug_flags, + jstring instruction_set) { Thread* thread = reinterpret_cast(token); // Our system thread ID, etc, has changed so reset Thread state. thread->InitAfterFork(); EnableDebugFeatures(debug_flags); - Runtime::Current()->DidForkFromZygote(); + + Runtime::NativeBridgeAction action = Runtime::NativeBridgeAction::kUnload; + if (instruction_set != nullptr) { + ScopedUtfChars isa_string(env, instruction_set); + InstructionSet isa = GetInstructionSetFromString(isa_string.c_str()); + if (isa != kNone && isa != kRuntimeISA) { + action = Runtime::NativeBridgeAction::kInitialize; + } + } + Runtime::Current()->DidForkFromZygote(action); } static JNINativeMethod gMethods[] = { NATIVE_METHOD(ZygoteHooks, nativePreFork, "()J"), - NATIVE_METHOD(ZygoteHooks, nativePostForkChild, "(JI)V"), + NATIVE_METHOD(ZygoteHooks, nativePostForkChild, "(JILjava/lang/String;)V"), }; void register_dalvik_system_ZygoteHooks(JNIEnv* env) { diff --git a/runtime/runtime.cc b/runtime/runtime.cc index c962c146f..32d29127c 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -428,7 +428,7 @@ bool Runtime::Start() { return false; } } else { - DidForkFromZygote(); + DidForkFromZygote(NativeBridgeAction::kInitialize); } StartDaemonThreads(); @@ -506,9 +506,19 @@ bool Runtime::InitZygote() { #endif } -void Runtime::DidForkFromZygote() { +void Runtime::DidForkFromZygote(NativeBridgeAction action) { is_zygote_ = false; + switch (action) { + case NativeBridgeAction::kUnload: + android::UnloadNativeBridge(); + break; + + case NativeBridgeAction::kInitialize: + android::InitializeNativeBridge(); + break; + } + // Create the thread pool. heap_->CreateThreadPool(); @@ -829,8 +839,34 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) self->ClearException(); // Look for a native bridge. + // + // The intended flow here is, in the case of a running system: + // + // Runtime::Init() (zygote): + // LoadNativeBridge -> dlopen from cmd line parameter. + // | + // V + // Runtime::Start() (zygote): + // No-op wrt native bridge. + // | + // | start app + // V + // DidForkFromZygote(action) + // action = kUnload -> dlclose native bridge. + // action = kInitialize -> initialize library + // + // + // The intended flow here is, in the case of a simple dalvikvm call: + // + // Runtime::Init(): + // LoadNativeBridge -> dlopen from cmd line parameter. + // | + // V + // Runtime::Start(): + // DidForkFromZygote(kInitialize) -> try to initialize any native bridge given. + // No-op wrt native bridge. native_bridge_library_filename_ = options->native_bridge_library_filename_; - android::SetupNativeBridge(native_bridge_library_filename_.c_str(), &native_bridge_art_callbacks_); + 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_); diff --git a/runtime/runtime.h b/runtime/runtime.h index 79d455490..e255272b9 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -387,9 +387,13 @@ class Runtime { void SetStatsEnabled(bool new_state); + enum class NativeBridgeAction { // private + kUnload, + kInitialize + }; void PreZygoteFork(); bool InitZygote(); - void DidForkFromZygote(); + void DidForkFromZygote(NativeBridgeAction action); const instrumentation::Instrumentation* GetInstrumentation() const { return &instrumentation_; diff --git a/test/115-native-bridge/expected.txt b/test/115-native-bridge/expected.txt index 5b41606b5..808d968f6 100644 --- a/test/115-native-bridge/expected.txt +++ b/test/115-native-bridge/expected.txt @@ -1,5 +1,5 @@ -Ready for native bridge tests. Native bridge initialized. +Ready for native bridge tests. Checking for support. Getting trampoline for JNI_OnLoad with shorty (null). Test ART callbacks: all JNI function number is 9. -- 2.11.0