Trim reference tables when we trim the heap

Before:
System server:
 virtual                     shared   shared  private  private
  size      RSS      PSS    clean    dirty    clean    dirty    # object
2200      300      229        0       80        0      220   77 /dev/ashmem/dalvik-indirect ref table (deleted)
Location:
1896      128      102        0       28        0      100   39 /dev/ashmem/dalvik-indirect ref table (deleted)

After:
 virtual                     shared   shared  private  private
  size      RSS      PSS    clean    dirty    clean    dirty    # object
System server:
2216       64       64        0        0        0       64   79 /dev/ashmem/dalvik-indirect ref table (deleted)
Location:
2120       48       48        0        0        0       48   67 /dev/ashmem/dalvik-indirect ref table (deleted)

No pause time regression measured in memalloc test.

(cherry picked from commit 84dc99d2fa67e5dff018685661cb2bff62132989)

Change-Id: I80d9bd3b98e888fa8f77d03df69f8479ed209986
diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc
index 4d177a3..0d84a1e 100644
--- a/runtime/indirect_reference_table.cc
+++ b/runtime/indirect_reference_table.cc
@@ -162,13 +162,12 @@
   DCHECK(table_ != NULL);
   DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);
 
-  int idx = ExtractIndex(iref);
-
   if (GetIndirectRefKind(iref) == kHandleScopeOrInvalid &&
       Thread::Current()->HandleScopeContains(reinterpret_cast<jobject>(iref))) {
     LOG(WARNING) << "Attempt to remove local handle scope entry from IRT, ignoring";
     return true;
   }
+  const int idx = ExtractIndex(iref);
   if (idx < bottomIndex) {
     // Wrong segment.
     LOG(WARNING) << "Attempt to remove index outside index area (" << idx
@@ -236,6 +235,13 @@
   return true;
 }
 
+void IndirectReferenceTable::Trim() {
+  const size_t top_index = Capacity();
+  auto* release_start = AlignUp(reinterpret_cast<uint8_t*>(&table_[top_index]), kPageSize);
+  uint8_t* release_end = table_mem_map_->End();
+  madvise(release_start, release_end - release_start, MADV_DONTNEED);
+}
+
 void IndirectReferenceTable::VisitRoots(RootCallback* callback, void* arg, uint32_t tid,
                                         RootType root_type) {
   for (auto ref : *this) {