summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorjgu21 <jinghui.gu@intel.com>2014-09-10 06:57:17 -0400
committerAndreas Gampe <agampe@google.com>2014-09-23 20:11:31 -0700
commita6da74e941d7cee498ac3880018a1d8dc953c6eb (patch)
treebb36d90e914f8a842abd7dd854ba168f9441e8db /runtime
parenta20b7b3ecf90bb761d7085403782721f2fb474c5 (diff)
downloadandroid_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.cc6
-rw-r--r--runtime/native_bridge_art_interface.cc39
-rw-r--r--runtime/native_bridge_art_interface.h14
-rw-r--r--runtime/runtime.cc25
-rw-r--r--runtime/runtime.h14
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);
};