Add the two ReferenceTables.

Change-Id: Ie9200e6246dc07d867de0a70de52c1b2dc034f5b
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index eda3e9b..75992ea 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -1953,16 +1953,17 @@
   MonitorExit(env, obj);  // Ignore the result.
 }
 
-JNIEnv* CreateJNIEnv() {
-  Thread* self = Thread::Current();
-  CHECK(self != NULL);
-  JNIEnvExt* result = new JNIEnvExt;
-  result->fns = &gNativeInterface;
-  result->self = self;
-  result->critical = false;
-  result->MonitorEnterHelper = &MonitorEnterHelper;
-  result->MonitorExitHelper = &MonitorExitHelper;
-  return reinterpret_cast<JNIEnv*>(result);
+static const size_t kMonitorTableInitialSize = 32; // Arbitrary.
+static const size_t kMonitorTableMaxSize = 4096; // Arbitrary sanity check.
+
+JNIEnvExt::JNIEnvExt(Thread* self)
+    : fns(&gNativeInterface),
+      self(self),
+      critical(false),
+      monitor_table("monitor table", kMonitorTableInitialSize, kMonitorTableMaxSize) {
+  // TODO: kill these.
+  MonitorEnterHelper = &::art::MonitorEnterHelper;
+  MonitorExitHelper = &::art::MonitorExitHelper;
 }
 
 // JNI Invocation interface.
@@ -2094,11 +2095,13 @@
   AttachCurrentThreadAsDaemon
 };
 
-JavaVM* CreateJavaVM(Runtime* runtime) {
-  JavaVMExt* result = new JavaVMExt;
-  result->fns = &gInvokeInterface;
-  result->runtime = runtime;
-  return reinterpret_cast<JavaVM*>(result);
+static const size_t kPinTableInitialSize = 16;
+static const size_t kPinTableMaxSize = 1024;
+
+JavaVMExt::JavaVMExt(Runtime* runtime)
+    : fns(&gInvokeInterface),
+      runtime(runtime),
+      pin_table("pin table", kPinTableInitialSize, kPinTableMaxSize) {
 }
 
 }  // namespace art
diff --git a/src/jni_internal.h b/src/jni_internal.h
index 3ff12d8..03dbfa0 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -7,23 +7,28 @@
 
 #include "assembler.h"
 #include "macros.h"
+#include "reference_table.h"
 
 namespace art {
 
 class Runtime;
 class Thread;
 
-JavaVM* CreateJavaVM(Runtime* runtime);
-JNIEnv* CreateJNIEnv();
-
 struct JavaVMExt {
+  JavaVMExt(Runtime* runtime);
+
   // Must be first to correspond with JNIEnv.
   const struct JNIInvokeInterface* fns;
 
   Runtime* runtime;
+
+  // Used to hold references to pinned primitive arrays.
+  ReferenceTable pin_table;
 };
 
 struct JNIEnvExt {
+  JNIEnvExt(Thread* self);
+
   // Must be first to correspond with JavaVM.
   const struct JNINativeInterface* fns;
 
@@ -32,6 +37,9 @@
   // Are we in a "critical" JNI call?
   bool critical;
 
+  // Entered JNI monitors, for bulk exit on thread detach.
+  ReferenceTable  monitor_table;
+
   // Used to help call synchronized native methods.
   // TODO: make jni_compiler.cc do the indirection itself.
   void (*MonitorEnterHelper)(JNIEnv*, jobject);
diff --git a/src/runtime.cc b/src/runtime.cc
index 2ad3589..b167280c 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -268,7 +268,8 @@
 
   class_linker_ = ClassLinker::Create(parsed_options->boot_class_path_);
 
-  java_vm_.reset(CreateJavaVM(this));
+  java_vm_.reset(reinterpret_cast<JavaVM*>(new JavaVMExt(this)));
+
   return true;
 }
 
diff --git a/src/thread.cc b/src/thread.cc
index 609ae41..e3c92d4 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -103,7 +103,7 @@
       PLOG(FATAL) << "pthread_setspecific failed";
   }
 
-  thread->jni_env_ = CreateJNIEnv();
+  thread->jni_env_ = reinterpret_cast<JNIEnv*>(new JNIEnvExt(thread));
 
   return thread;
 }