ART: skip compilation of huge methods.

Besides not being worthwhile to compile, it huge methods could cause
overflow of some internal compiler structures.

internal b/17524219

(cherry picked from commit bf5d818f7e59ce33521ad81bbab68b1e7a09e0ba)

Change-Id: If99b47c3191c69feee319c9d73537e827ba0cc1d
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index b267841..07f3033 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -82,11 +82,22 @@
                                      jobject class_loader, const DexFile& dex_file,
                                      void* llvm_compilation_unit) {
   VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
-  if (code_item->insns_size_in_code_units_ >= 0x10000) {
-    LOG(INFO) << "Method size exceeds compiler limits: " << code_item->insns_size_in_code_units_
+  /*
+   * Skip compilation for pathologically large methods - either by instruction count or num vregs.
+   * Dalvik uses 16-bit uints for instruction and register counts.  We'll limit to a quarter
+   * of that, which also guarantees we cannot overflow our 16-bit internal SSA name space.
+   */
+  if (code_item->insns_size_in_code_units_ >= UINT16_MAX / 4) {
+    LOG(INFO) << "Method exceeds compiler instruction limit: "
+              << code_item->insns_size_in_code_units_
               << " in " << PrettyMethod(method_idx, dex_file);
     return NULL;
   }
+  if (code_item->registers_size_ >= UINT16_MAX / 4) {
+    LOG(INFO) << "Method exceeds compiler virtual register limit: "
+              << code_item->registers_size_ << " in " << PrettyMethod(method_idx, dex_file);
+    return NULL;
+  }
 
   if (!driver.GetCompilerOptions().IsCompilationEnabled()) {
     return nullptr;