ART: Change ART for new native bridge sequence
Initialize or unload after a fork.
Change-Id: I5a20de1cb68dd1802937b369b14c50c9c1031c67
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index df6055d..c3c8c25 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -17,9 +17,11 @@
#include <stdlib.h>
#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 @@
return reinterpret_cast<jlong>(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<Thread*>(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 c962c14..32d2912 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -428,7 +428,7 @@
return false;
}
} else {
- DidForkFromZygote();
+ DidForkFromZygote(NativeBridgeAction::kInitialize);
}
StartDaemonThreads();
@@ -506,9 +506,19 @@
#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 @@
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 79d4554..e255272 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -387,9 +387,13 @@
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_;