Add basic runtime-plugins support.

This allows one to pass shared-libraries on the command line that the
runtime will load as plugins. They have access to runtime code and can
install hooks to add functionality. Currently the only hook they can
touch is JavaVMExt::AddEnvironmentHook to register a callback for
GetEnv(). More hooks might be added in the future.

Test: ./test/run-test 900
Change-Id: I852b4daf5a3fa71e9888722bc07794632c0e5010
diff --git a/runtime/java_vm_ext.h b/runtime/java_vm_ext.h
index 3d055cd..ed9d3ab 100644
--- a/runtime/java_vm_ext.h
+++ b/runtime/java_vm_ext.h
@@ -36,6 +36,10 @@
 class Runtime;
 struct RuntimeArgumentMap;
 
+class JavaVMExt;
+// Hook definition for runtime plugins.
+using GetEnvHook = jint (*)(JavaVMExt* vm, /*out*/void** new_env, jint version);
+
 class JavaVMExt : public JavaVM {
  public:
   JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options);
@@ -171,6 +175,12 @@
   void TrimGlobals() SHARED_REQUIRES(Locks::mutator_lock_)
       REQUIRES(!globals_lock_);
 
+  jint HandleGetEnv(/*out*/void** env, jint version);
+
+  void AddEnvironmentHook(GetEnvHook hook);
+
+  static bool IsBadJniVersion(int version);
+
  private:
   // Return true if self can currently access weak globals.
   bool MayAccessWeakGlobalsUnlocked(Thread* self) const SHARED_REQUIRES(Locks::mutator_lock_);
@@ -215,6 +225,9 @@
   Atomic<bool> allow_accessing_weak_globals_;
   ConditionVariable weak_globals_add_condition_ GUARDED_BY(weak_globals_lock_);
 
+  // TODO Maybe move this to Runtime.
+  std::vector<GetEnvHook> env_hooks_;
+
   DISALLOW_COPY_AND_ASSIGN(JavaVMExt);
 };