Merge "Fix crash in VirtualMachine.AllThreads JDWP command" into lmp-dev
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 04be4a2..62ae099 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1843,17 +1843,17 @@
     ret
 
 .Ldo_memcmp16:
-    mov xIP0, x0                  // Save x0 and LR. __memcmp16 does not use these temps.
-    mov xIP1, xLR                 //                 TODO: Codify and check that?
+    mov x14, x0                  // Save x0 and LR. __memcmp16 does not use these temps.
+    mov x15, xLR                 //                 TODO: Codify and check that?
 
     mov x0, x2
     uxtw x2, w3
     bl __memcmp16
 
-    mov xLR, xIP1                 // Restore LR.
+    mov xLR, x15                 // Restore LR.
 
     cmp x0, #0                   // Check the memcmp difference.
-    csel x0, x0, xIP0, ne         // x0 := x0 != 0 ? xIP0(prev x0=length diff) : x1.
+    csel x0, x0, x14, ne         // x0 := x0 != 0 ? x14(prev x0=length diff) : x1.
     ret
 END art_quick_string_compareto
 
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 02cd25c..e7f26d9 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -806,10 +806,15 @@
     os << "Mean GC object throughput: "
        << (GetObjectsFreedEver() / total_seconds) << " objects/s\n";
   }
-  size_t total_objects_allocated = GetObjectsAllocatedEver();
-  os << "Total number of allocations: " << total_objects_allocated << "\n";
-  size_t total_bytes_allocated = GetBytesAllocatedEver();
+  uint64_t total_objects_allocated = GetObjectsAllocatedEver();
+  os << "Total number of allocations " << total_objects_allocated << "\n";
+  uint64_t total_bytes_allocated = GetBytesAllocatedEver();
   os << "Total bytes allocated " << PrettySize(total_bytes_allocated) << "\n";
+  os << "Free memory " << PrettySize(GetFreeMemory()) << "\n";
+  os << "Free memory until GC " << PrettySize(GetFreeMemoryUntilGC()) << "\n";
+  os << "Free memory until OOME " << PrettySize(GetFreeMemoryUntilOOME()) << "\n";
+  os << "Total memory " << PrettySize(GetTotalMemory()) << "\n";
+  os << "Max memory " << PrettySize(GetMaxMemory()) << "\n";
   if (kMeasureAllocationTime) {
     os << "Total time spent allocating: " << PrettyDuration(allocation_time) << "\n";
     os << "Mean allocation time: " << PrettyDuration(allocation_time / total_objects_allocated)
@@ -883,7 +888,7 @@
   std::ostringstream oss;
   size_t total_bytes_free = GetFreeMemory();
   oss << "Failed to allocate a " << byte_count << " byte allocation with " << total_bytes_free
-      << " free bytes";
+      << " free bytes and " << PrettySize(GetFreeMemoryUntilOOME()) << " until OOM";
   // If the allocation failed due to fragmentation, print out the largest continuous allocation.
   if (total_bytes_free >= byte_count) {
     space::AllocSpace* space = nullptr;
@@ -1332,11 +1337,11 @@
   return total;
 }
 
-size_t Heap::GetObjectsAllocatedEver() const {
+uint64_t Heap::GetObjectsAllocatedEver() const {
   return GetObjectsFreedEver() + GetObjectsAllocated();
 }
 
-size_t Heap::GetBytesAllocatedEver() const {
+uint64_t Heap::GetBytesAllocatedEver() const {
   return GetBytesFreedEver() + GetBytesAllocated();
 }
 
@@ -2855,7 +2860,7 @@
         remaining_bytes = kMinConcurrentRemainingBytes;
       }
       DCHECK_LE(remaining_bytes, max_allowed_footprint_);
-      DCHECK_LE(max_allowed_footprint_, growth_limit_);
+      DCHECK_LE(max_allowed_footprint_, GetMaxMemory());
       // Start a concurrent GC when we get close to the estimated remaining bytes. When the
       // allocation rate is very high, remaining_bytes could tell us that we should start a GC
       // right away.
@@ -3085,19 +3090,7 @@
 }
 
 size_t Heap::GetTotalMemory() const {
-  size_t ret = 0;
-  for (const auto& space : continuous_spaces_) {
-    // Currently don't include the image space.
-    if (!space->IsImageSpace()) {
-      ret += space->Size();
-    }
-  }
-  for (const auto& space : discontinuous_spaces_) {
-    if (space->IsLargeObjectSpace()) {
-      ret += space->AsLargeObjectSpace()->GetBytesAllocated();
-    }
-  }
-  return ret;
+  return std::max(max_allowed_footprint_, GetBytesAllocated());
 }
 
 void Heap::AddModUnionTable(accounting::ModUnionTable* mod_union_table) {
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 8ffadd5..d91f5af 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -401,18 +401,18 @@
   size_t GetObjectsAllocated() const LOCKS_EXCLUDED(Locks::heap_bitmap_lock_);
 
   // Returns the total number of objects allocated since the heap was created.
-  size_t GetObjectsAllocatedEver() const;
+  uint64_t GetObjectsAllocatedEver() const;
 
   // Returns the total number of bytes allocated since the heap was created.
-  size_t GetBytesAllocatedEver() const;
+  uint64_t GetBytesAllocatedEver() const;
 
   // Returns the total number of objects freed since the heap was created.
-  size_t GetObjectsFreedEver() const {
+  uint64_t GetObjectsFreedEver() const {
     return total_objects_freed_ever_;
   }
 
   // Returns the total number of bytes freed since the heap was created.
-  size_t GetBytesFreedEver() const {
+  uint64_t GetBytesFreedEver() const {
     return total_bytes_freed_ever_;
   }
 
@@ -421,19 +421,32 @@
   // were specified. Android apps start with a growth limit (small heap size) which is
   // cleared/extended for large apps.
   size_t GetMaxMemory() const {
-    return growth_limit_;
+    // There is some race conditions in the allocation code that can cause bytes allocated to
+    // become larger than growth_limit_ in rare cases.
+    return std::max(GetBytesAllocated(), growth_limit_);
   }
 
-  // Implements java.lang.Runtime.totalMemory, returning the amount of memory consumed by an
-  // application.
+  // Implements java.lang.Runtime.totalMemory, returning approximate amount of memory currently
+  // consumed by an application.
   size_t GetTotalMemory() const;
 
-  // Implements java.lang.Runtime.freeMemory.
+  // Returns approximately how much free memory we have until the next GC happens.
+  size_t GetFreeMemoryUntilGC() const {
+    return max_allowed_footprint_ - GetBytesAllocated();
+  }
+
+  // Returns approximately how much free memory we have until the next OOME happens.
+  size_t GetFreeMemoryUntilOOME() const {
+    return growth_limit_ - GetBytesAllocated();
+  }
+
+  // Returns how much free memory we have until we need to grow the heap to perform an allocation.
+  // Similar to GetFreeMemoryUntilGC. Implements java.lang.Runtime.freeMemory.
   size_t GetFreeMemory() const {
     size_t byte_allocated = num_bytes_allocated_.LoadSequentiallyConsistent();
-    // Make sure we don't get a negative number since the max allowed footprint is only updated
-    // after the GC. But we can still allocate even if bytes_allocated > max_allowed_footprint_.
-    return std::max(max_allowed_footprint_, byte_allocated) - byte_allocated;
+    size_t total_memory = GetTotalMemory();
+    // Make sure we don't get a negative number.
+    return total_memory - std::min(total_memory, byte_allocated);
   }
 
   // get the space that corresponds to an object's address. Current implementation searches all
@@ -884,10 +897,10 @@
   size_t concurrent_start_bytes_;
 
   // Since the heap was created, how many bytes have been freed.
-  size_t total_bytes_freed_ever_;
+  uint64_t total_bytes_freed_ever_;
 
   // Since the heap was created, how many objects have been freed.
-  size_t total_objects_freed_ever_;
+  uint64_t total_objects_freed_ever_;
 
   // Number of bytes allocated.  Adjusted after each allocation and free.
   Atomic<size_t> num_bytes_allocated_;
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 16be077..ae42284 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -50,7 +50,7 @@
 // Do we want to deoptimize for method entry and exit listeners or just try to intercept
 // invocations? Deoptimization forces all code to run in the interpreter and considerably hurts the
 // application's performance.
-static constexpr bool kDeoptimizeForAccurateMethodEntryExitListeners = false;
+static constexpr bool kDeoptimizeForAccurateMethodEntryExitListeners = true;
 
 static bool InstallStubsClassVisitor(mirror::Class* klass, void* arg)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 8df3614..c3304e6 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -97,7 +97,7 @@
   void operator=(const NullableScopedUtfChars&);
 };
 
-static jlong DexFile_openDexFile(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName, jint) {
+static jlong DexFile_openDexFileNative(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName, jint) {
   ScopedUtfChars sourceName(env, javaSourceName);
   if (sourceName.c_str() == NULL) {
     return 0;
@@ -571,7 +571,7 @@
   NATIVE_METHOD(DexFile, getClassNameList, "(J)[Ljava/lang/String;"),
   NATIVE_METHOD(DexFile, isDexOptNeeded, "(Ljava/lang/String;)Z"),
   NATIVE_METHOD(DexFile, isDexOptNeededInternal, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)B"),
-  NATIVE_METHOD(DexFile, openDexFile, "(Ljava/lang/String;Ljava/lang/String;I)J"),
+  NATIVE_METHOD(DexFile, openDexFileNative, "(Ljava/lang/String;Ljava/lang/String;I)J"),
 };
 
 void register_dalvik_system_DexFile(JNIEnv* env) {