am 98b6b185: Fix build
* commit '98b6b185837bed9e7a7d8cd9deb2fe3a05f60644':
Fix build
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index dea52a6..b924798 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -53,7 +53,7 @@
class ScopedContentionRecorder;
class Thread;
-const bool kDebugLocking = kIsDebugBuild;
+const bool kDebugLocking = true || kIsDebugBuild;
// Base class for all Mutex implementations
class BaseMutex {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index edc5529..1c18188 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -148,7 +148,7 @@
CHECK(large_object_space_ != NULL) << "Failed to create large object space";
AddDiscontinuousSpace(large_object_space_);
- alloc_space_ = space::DlMallocSpace::Create("alloc space",
+ alloc_space_ = space::DlMallocSpace::Create(Runtime::Current()->IsZygote() ? "zygote space" : "alloc space",
initial_size,
growth_limit, capacity,
requested_alloc_space_begin);
@@ -972,7 +972,7 @@
// Turns the current alloc space into a Zygote space and obtain the new alloc space composed
// of the remaining available heap memory.
space::DlMallocSpace* zygote_space = alloc_space_;
- alloc_space_ = zygote_space->CreateZygoteSpace();
+ alloc_space_ = zygote_space->CreateZygoteSpace("alloc space");
alloc_space_->SetFootprintLimit(alloc_space_->Capacity());
// Change the GC retention policy of the zygote space to only collect when full.
@@ -1934,5 +1934,27 @@
} while (!native_bytes_allocated_.compare_and_swap(expected_size, new_size));
}
+int64_t Heap::GetTotalMemory() const {
+ int64_t ret = 0;
+ typedef std::vector<space::ContinuousSpace*>::const_iterator It;
+ for (It it = continuous_spaces_.begin(), end = continuous_spaces_.end(); it != end; ++it) {
+ space::ContinuousSpace* space = *it;
+ if (space->IsImageSpace()) {
+ // Currently don't include the image space.
+ } else if (space->IsDlMallocSpace()) {
+ // Zygote or alloc space
+ ret += space->AsDlMallocSpace()->GetFootprint();
+ }
+ }
+ typedef std::vector<space::DiscontinuousSpace*>::const_iterator It2;
+ for (It2 it = discontinuous_spaces_.begin(), end = discontinuous_spaces_.end(); it != end; ++it) {
+ space::DiscontinuousSpace* space = *it;
+ if (space->IsLargeObjectSpace()) {
+ ret += space->AsLargeObjectSpace()->GetBytesAllocated();
+ }
+ }
+ return ret;
+}
+
} // namespace gc
} // namespace art
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 853db93..b7b2e84 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -331,11 +331,7 @@
// Implements java.lang.Runtime.totalMemory, returning the amount of memory consumed by an
// application.
- int64_t GetTotalMemory() const {
- // TODO: we use the footprint limit here which is conservative wrt number of pages really used.
- // We could implement a more accurate count across all spaces.
- return max_allowed_footprint_;
- }
+ int64_t GetTotalMemory() const;
// Implements java.lang.Runtime.freeMemory.
int64_t GetFreeMemory() const {
diff --git a/runtime/gc/space/dlmalloc_space.cc b/runtime/gc/space/dlmalloc_space.cc
index 9f85394..550f44b 100644
--- a/runtime/gc/space/dlmalloc_space.cc
+++ b/runtime/gc/space/dlmalloc_space.cc
@@ -286,7 +286,7 @@
}
}
-DlMallocSpace* DlMallocSpace::CreateZygoteSpace() {
+DlMallocSpace* DlMallocSpace::CreateZygoteSpace(const char* alloc_space_name) {
end_ = reinterpret_cast<byte*>(RoundUp(reinterpret_cast<uintptr_t>(end_), kPageSize));
DCHECK(IsAligned<accounting::CardTable::kCardSize>(begin_));
DCHECK(IsAligned<accounting::CardTable::kCardSize>(end_));
@@ -316,20 +316,19 @@
VLOG(heap) << "Size " << GetMemMap()->Size();
VLOG(heap) << "GrowthLimit " << PrettySize(growth_limit);
VLOG(heap) << "Capacity " << PrettySize(capacity);
- UniquePtr<MemMap> mem_map(MemMap::MapAnonymous(GetName(), End(), capacity, PROT_READ | PROT_WRITE));
+ UniquePtr<MemMap> mem_map(MemMap::MapAnonymous(alloc_space_name, End(), capacity, PROT_READ | PROT_WRITE));
void* mspace = CreateMallocSpace(end_, starting_size, initial_size);
// Protect memory beyond the initial size.
byte* end = mem_map->Begin() + starting_size;
if (capacity - initial_size > 0) {
- CHECK_MEMORY_CALL(mprotect, (end, capacity - initial_size, PROT_NONE), name_.c_str());
+ CHECK_MEMORY_CALL(mprotect, (end, capacity - initial_size, PROT_NONE), alloc_space_name);
}
DlMallocSpace* alloc_space =
- new DlMallocSpace(name_, mem_map.release(), mspace, end_, end, growth_limit);
+ new DlMallocSpace(alloc_space_name, mem_map.release(), mspace, end_, end, growth_limit);
live_bitmap_->SetHeapLimit(reinterpret_cast<uintptr_t>(End()));
CHECK_EQ(live_bitmap_->HeapLimit(), reinterpret_cast<uintptr_t>(End()));
mark_bitmap_->SetHeapLimit(reinterpret_cast<uintptr_t>(End()));
CHECK_EQ(mark_bitmap_->HeapLimit(), reinterpret_cast<uintptr_t>(End()));
- name_ += "-zygote-transformed";
VLOG(heap) << "zygote space creation done";
return alloc_space;
}
@@ -449,6 +448,11 @@
callback(NULL, NULL, 0, arg); // Indicate end of a space.
}
+size_t DlMallocSpace::GetFootprint() {
+ MutexLock mu(Thread::Current(), lock_);
+ return mspace_footprint(mspace_);
+}
+
size_t DlMallocSpace::GetFootprintLimit() {
MutexLock mu(Thread::Current(), lock_);
return mspace_footprint_limit(mspace_);
diff --git a/runtime/gc/space/dlmalloc_space.h b/runtime/gc/space/dlmalloc_space.h
index 8a4314c..c15d0ba 100644
--- a/runtime/gc/space/dlmalloc_space.h
+++ b/runtime/gc/space/dlmalloc_space.h
@@ -73,6 +73,10 @@
// in use, indicated by num_bytes equaling zero.
void Walk(WalkCallback callback, void* arg);
+ // Returns the number of bytes that the space has currently obtained from the system. This is
+ // greater or equal to the amount of live data in the space.
+ size_t GetFootprint();
+
// Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore.
size_t GetFootprintLimit();
@@ -113,7 +117,7 @@
void SwapBitmaps();
// Turn ourself into a zygote space and return a new alloc space which has our unused memory.
- DlMallocSpace* CreateZygoteSpace();
+ DlMallocSpace* CreateZygoteSpace(const char* alloc_space_name);
uint64_t GetBytesAllocated() const {
return num_bytes_allocated_;
diff --git a/runtime/gc/space/space_test.cc b/runtime/gc/space/space_test.cc
index 08ae894..3003140 100644
--- a/runtime/gc/space/space_test.cc
+++ b/runtime/gc/space/space_test.cc
@@ -123,7 +123,7 @@
// Make sure that the zygote space isn't directly at the start of the space.
space->Alloc(self, 1U * MB);
- space = space->CreateZygoteSpace();
+ space = space->CreateZygoteSpace("alloc space");
// Make space findable to the heap, will also delete space when runtime is cleaned up
AddContinuousSpace(space);
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 992998e..1cc42df 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -20,6 +20,9 @@
#include "class_linker.h"
#include "common_throws.h"
#include "debugger.h"
+#include "gc/space/dlmalloc_space.h"
+#include "gc/space/large_object_space.h"
+#include "gc/space/space-inl.h"
#include "hprof/hprof.h"
#include "jni_internal.h"
#include "mirror/class.h"
@@ -234,6 +237,69 @@
return count;
}
+// We export the VM internal per-heap-space size/alloc/free metrics
+// for the zygote space, alloc space (application heap), and the large
+// object space for dumpsys meminfo. The other memory region data such
+// as PSS, private/shared dirty/shared data are available via
+// /proc/<pid>/smaps.
+static void VMDebug_getHeapSpaceStats(JNIEnv* env, jclass, jlongArray data) {
+ jlong* arr = reinterpret_cast<jlong*>(env->GetPrimitiveArrayCritical(data, 0));
+ if (arr == NULL || env->GetArrayLength(data) < 9) {
+ return;
+ }
+
+ size_t allocSize = 0;
+ size_t allocUsed = 0;
+ size_t zygoteSize = 0;
+ size_t zygoteUsed = 0;
+ size_t largeObjectsSize = 0;
+ size_t largeObjectsUsed = 0;
+
+ gc::Heap* heap = Runtime::Current()->GetHeap();
+ const std::vector<gc::space::ContinuousSpace*>& continuous_spaces = heap->GetContinuousSpaces();
+ const std::vector<gc::space::DiscontinuousSpace*>& discontinuous_spaces = heap->GetDiscontinuousSpaces();
+ typedef std::vector<gc::space::ContinuousSpace*>::const_iterator It;
+ for (It it = continuous_spaces.begin(), end = continuous_spaces.end(); it != end; ++it) {
+ gc::space::ContinuousSpace* space = *it;
+ if (space->IsImageSpace()) {
+ // Currently don't include the image space.
+ } else if (space->IsZygoteSpace()) {
+ gc::space::DlMallocSpace* dlmalloc_space = space->AsDlMallocSpace();
+ zygoteSize += dlmalloc_space->GetFootprint();
+ zygoteUsed += dlmalloc_space->GetBytesAllocated();
+ } else {
+ // This is the alloc space.
+ gc::space::DlMallocSpace* dlmalloc_space = space->AsDlMallocSpace();
+ allocSize += dlmalloc_space->GetFootprint();
+ allocUsed += dlmalloc_space->GetBytesAllocated();
+ }
+ }
+ typedef std::vector<gc::space::DiscontinuousSpace*>::const_iterator It2;
+ for (It2 it = discontinuous_spaces.begin(), end = discontinuous_spaces.end(); it != end; ++it) {
+ gc::space::DiscontinuousSpace* space = *it;
+ if (space->IsLargeObjectSpace()) {
+ largeObjectsSize += space->AsLargeObjectSpace()->GetBytesAllocated();
+ largeObjectsUsed += largeObjectsSize;
+ }
+ }
+
+ size_t allocFree = allocSize - allocUsed;
+ size_t zygoteFree = zygoteSize - zygoteUsed;
+ size_t largeObjectsFree = largeObjectsSize - largeObjectsUsed;
+
+ int j = 0;
+ arr[j++] = allocSize;
+ arr[j++] = allocUsed;
+ arr[j++] = allocFree;
+ arr[j++] = zygoteSize;
+ arr[j++] = zygoteUsed;
+ arr[j++] = zygoteFree;
+ arr[j++] = largeObjectsSize;
+ arr[j++] = largeObjectsUsed;
+ arr[j++] = largeObjectsFree;
+ env->ReleasePrimitiveArrayCritical(data, arr, 0);
+}
+
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"),
NATIVE_METHOD(VMDebug, crash, "()V"),
@@ -241,6 +307,7 @@
NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"),
NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"),
NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"),
+ NATIVE_METHOD(VMDebug, getHeapSpaceStats, "([J)V"),
NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"),
NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"),
NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"),