Implement -Xjnigreflimit.

Change-Id: Iaa31cf4ea4f90fc76baa4472b67fe6c2cc0e0277
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 9480644..02c8513 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -24,6 +24,8 @@
 #include "stringpiece.h"
 #include "thread.h"
 
+namespace art {
+
 static const size_t kMonitorsInitial = 32; // Arbitrary.
 static const size_t kMonitorsMax = 4096; // Arbitrary sanity check.
 
@@ -33,13 +35,18 @@
 static const size_t kPinTableInitial = 16; // Arbitrary.
 static const size_t kPinTableMax = 1024; // Arbitrary sanity check.
 
-static const size_t kGlobalsInitial = 512; // Arbitrary.
-static const size_t kGlobalsMax = 51200; // Arbitrary sanity check.
+static size_t gGlobalsInitial = 512; // Arbitrary.
+static size_t gGlobalsMax = 51200; // Arbitrary sanity check.
 
 static const size_t kWeakGlobalsInitial = 16; // Arbitrary.
 static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check.
 
-namespace art {
+void SetJniGlobalsMax(size_t max) {
+  if (max != 0) {
+    gGlobalsMax = max;
+    gGlobalsInitial = std::min(gGlobalsInitial, gGlobalsMax);
+  }
+}
 
 /*
  * Add a local reference for an object to the current stack frame.  When
@@ -2662,7 +2669,7 @@
       pins_lock("JNI pin table lock"),
       pin_table("pin table", kPinTableInitial, kPinTableMax),
       globals_lock("JNI global reference table lock"),
-      globals(kGlobalsInitial, kGlobalsMax, kGlobal),
+      globals(gGlobalsInitial, gGlobalsMax, kGlobal),
       weak_globals_lock("JNI weak global reference table lock"),
       weak_globals(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
       libraries_lock("JNI shared libraries map lock"),
diff --git a/src/jni_internal.h b/src/jni_internal.h
index 329a5af..09efd68 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -23,6 +23,7 @@
 class Method;
 class Thread;
 
+void SetJniGlobalsMax(size_t max);
 void JniAbort(const char* jni_function_name);
 void* FindNativeMethod(Thread* thread);
 
diff --git a/src/reference_table.cc b/src/reference_table.cc
index 1b20b52..2281eac 100644
--- a/src/reference_table.cc
+++ b/src/reference_table.cc
@@ -22,9 +22,8 @@
 
 namespace art {
 
-ReferenceTable::ReferenceTable(const char* name,
-    size_t initial_size, size_t max_size)
-        : name_(name), max_size_(max_size) {
+ReferenceTable::ReferenceTable(const char* name, size_t initial_size, size_t max_size)
+    : name_(name), max_size_(max_size) {
   CHECK_LE(initial_size, max_size);
   entries_.reserve(initial_size);
 }
diff --git a/src/runtime.cc b/src/runtime.cc
index 31ba262..be9c8fa 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -177,6 +177,20 @@
   return 0;
 }
 
+size_t ParseIntegerOrDie(const StringPiece& s) {
+  StringPiece::size_type colon = s.find(':');
+  if (colon == StringPiece::npos) {
+    LOG(FATAL) << "Missing integer: " << s;
+  }
+  const char* begin = &s.data()[colon + 1];
+  char* end;
+  size_t result = strtoul(begin, &end, 10);
+  if (begin == end || *end != '\0') {
+    LOG(FATAL) << "Failed to parse integer in: " << s;
+  }
+  return result;
+}
+
 void LoadJniLibrary(JavaVMExt* vm, const char* name) {
   // TODO: OS_SHARED_LIB_FORMAT_STR
   std::string mapped_name(StringPrintf("lib%s.so", name));
@@ -212,6 +226,7 @@
 
   parsed->is_zygote_ = false;
 
+  parsed->jni_globals_max_ = 0;
   parsed->lock_profiling_threshold_ = 0;
   parsed->hook_is_sensitive_thread_ = NULL;
 
@@ -287,8 +302,10 @@
       for (size_t i = 0; i < verbose_options.size(); ++i) {
         parsed->verbose_.insert(verbose_options[i]);
       }
+    } else if (option.starts_with("-Xjnigreflimit:")) {
+      parsed->jni_globals_max_ = ParseIntegerOrDie(option);
     } else if (option.starts_with("-Xlockprofthreshold:")) {
-      parsed->lock_profiling_threshold_ = atoi(option.substr(strlen("-Xlockprofthreshold:")).data());
+      parsed->lock_profiling_threshold_ = ParseIntegerOrDie(option);
     } else if (option == "sensitiveThread") {
       parsed->hook_is_sensitive_thread_ = reinterpret_cast<bool (*)()>(options[i].second);
     } else if (option == "vfprintf") {
@@ -437,6 +454,7 @@
     LOG(INFO) << "Runtime::Init -verbose:startup enabled";
   }
 
+  SetJniGlobalsMax(options->jni_globals_max_);
   Monitor::Init(options->IsVerbose("monitor"), options->lock_profiling_threshold_, options->hook_is_sensitive_thread_);
 
   host_prefix_ = options->host_prefix_;
diff --git a/src/runtime.h b/src/runtime.h
index cbd47b8..b29523e 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -56,7 +56,8 @@
     size_t heap_initial_size_;
     size_t heap_maximum_size_;
     size_t stack_size_;
-    uint32_t lock_profiling_threshold_;
+    size_t jni_globals_max_;
+    size_t lock_profiling_threshold_;
     bool (*hook_is_sensitive_thread_)();
     jint (*hook_vfprintf_)(FILE* stream, const char* format, va_list ap);
     void (*hook_exit_)(jint status);
diff --git a/test/etc/host-run-test-jar b/test/etc/host-run-test-jar
index 682910e..ea20da5 100755
--- a/test/etc/host-run-test-jar
+++ b/test/etc/host-run-test-jar
@@ -23,7 +23,6 @@
 VALGRIND="n"
 DEV_MODE="n"
 QUIET="n"
-PRECISE="y"
 
 while true; do
     if [ "x$1" = "x--quiet" ]; then
@@ -47,9 +46,6 @@
     elif [ "x$1" = "x--no-optimize" ]; then
         OPTIMIZE="n"
         shift
-    elif [ "x$1" = "x--no-precise" ]; then
-        PRECISE="n"
-        shift
     elif [ "x$1" = "x--" ]; then
         shift
         break
@@ -89,12 +85,6 @@
     valgrind_cmd=""
 fi
 
-if [ "$PRECISE" = "y" ]; then
-    GC_OPTS="-Xgc:precise -Xgenregmap"
-else
-    GC_OPTS="-Xgc:noprecise"
-fi
-
 msg "------------------------------"
 
 HOSTBASE="${ANDROID_BUILD_TOP}/out/host"
@@ -134,5 +124,5 @@
 fi
 
 $valgrind_cmd $gdb $exe $gdbargs "-Xbootclasspath:${bpath}" \
-    $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG $GC_OPTS -ea \
+    $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG -ea \
     -cp test.jar Main "$@"
diff --git a/test/etc/push-and-run-test-jar b/test/etc/push-and-run-test-jar
index c1d9250..24bc8c6 100755
--- a/test/etc/push-and-run-test-jar
+++ b/test/etc/push-and-run-test-jar
@@ -23,7 +23,6 @@
 OPTIMIZE="y"
 ZYGOTE="n"
 QUIET="n"
-PRECISE="y"
 DEV_MODE="n"
 
 while true; do
@@ -46,9 +45,6 @@
     elif [ "x$1" = "x--no-optimize" ]; then
         OPTIMIZE="n"
         shift
-    elif [ "x$1" = "x--no-precise" ]; then
-        PRECISE="n"
-        shift
     elif [ "x$1" = "x--" ]; then
         shift
         break
@@ -104,21 +100,15 @@
     DEX_DEBUG="-agentlib:jdwp=transport=dt_android_adb,server=y,suspend=y"
 fi
 
-if [ "$PRECISE" = "y" ]; then
-    GC_OPTS="-Xgc:precise -Xgenregmap"
-else
-    GC_OPTS="-Xgc:noprecise"
-fi
-
 if [ "$ZYGOTE" = "y" ]; then
   adb shell cd /data \; dvz -classpath $TEST_NAME.jar Main "$@"
 else
-  cmdline="cd /data; oatexecd \
+  cmdline="cd /data; oatexecd -Xjnigreflimit:256 \
       -Ximage:/data/art-test/core.art \
       -cp /data/art-test/$TEST_NAME.jar \
       Main"
   #cmdline="cd /data; dalvikvm $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG \
-  #    $GC_OPTS -cp test.jar -Xint:${INTERP} -ea Main"
+  #     -cp test.jar -Xint:${INTERP} -ea Main"
   if [ "$DEV_MODE" = "y" ]; then
     echo $cmdline "$@"
   fi