mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:19:47 +00:00
Reapply "[vm, service] Gather used and capacity from various mallocs."
Avoid weak linking on iOS. TEST=ci Change-Id: Iafcb5bfdea0520d50363486e67031e1d5302d32b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161461 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
c3c371b971
commit
e67dd9c2c5
|
@ -174,14 +174,28 @@ class VMViewElement extends CustomElement implements Renderable {
|
||||||
..children = <Element>[
|
..children = <Element>[
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberName']
|
..classes = ['memberName']
|
||||||
..text = 'malloc memory',
|
..text = 'malloc used memory',
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberValue']
|
..classes = ['memberValue']
|
||||||
..text = _vm.heapAllocatedMemoryUsage != null
|
..text = _vm.mallocUsed != null
|
||||||
? Utils.formatSize(_vm.heapAllocatedMemoryUsage)
|
? Utils.formatSize(_vm.mallocUsed)
|
||||||
: 'unavailable'
|
: 'unavailable'
|
||||||
..title = _vm.heapAllocatedMemoryUsage != null
|
..title =
|
||||||
? '${_vm.heapAllocatedMemoryUsage} bytes'
|
_vm.mallocUsed != null ? '${_vm.mallocUsed} bytes' : null
|
||||||
|
],
|
||||||
|
new DivElement()
|
||||||
|
..classes = ['memberItem']
|
||||||
|
..children = <Element>[
|
||||||
|
new DivElement()
|
||||||
|
..classes = ['memberName']
|
||||||
|
..text = 'malloc capacity memory',
|
||||||
|
new DivElement()
|
||||||
|
..classes = ['memberValue']
|
||||||
|
..text = _vm.mallocCapacity != null
|
||||||
|
? Utils.formatSize(_vm.mallocCapacity)
|
||||||
|
: 'unavailable'
|
||||||
|
..title = _vm.mallocCapacity != null
|
||||||
|
? '${_vm.mallocCapacity} bytes'
|
||||||
: null
|
: null
|
||||||
],
|
],
|
||||||
new DivElement()
|
new DivElement()
|
||||||
|
@ -189,12 +203,10 @@ class VMViewElement extends CustomElement implements Renderable {
|
||||||
..children = <Element>[
|
..children = <Element>[
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberName']
|
..classes = ['memberName']
|
||||||
..text = 'malloc allocation count',
|
..text = 'malloc implementation',
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberValue']
|
..classes = ['memberValue']
|
||||||
..text = _vm.heapAllocationCount != null
|
..text = _vm.mallocImplementation
|
||||||
? '${_vm.heapAllocationCount}'
|
|
||||||
: 'unavailable'
|
|
||||||
],
|
],
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberItem']
|
..classes = ['memberItem']
|
||||||
|
|
|
@ -35,10 +35,9 @@ abstract class VM implements VMRef {
|
||||||
int get pid;
|
int get pid;
|
||||||
|
|
||||||
/// The current amount of native heap allocated memory within the VM.
|
/// The current amount of native heap allocated memory within the VM.
|
||||||
int get heapAllocatedMemoryUsage;
|
int get mallocUsed;
|
||||||
|
int get mallocCapacity;
|
||||||
/// The current number of allocations on the native heap within the VM.
|
String get mallocImplementation;
|
||||||
int get heapAllocationCount;
|
|
||||||
|
|
||||||
int get currentMemory;
|
int get currentMemory;
|
||||||
int get maxRSS;
|
int get maxRSS;
|
||||||
|
|
|
@ -680,8 +680,9 @@ abstract class VM extends ServiceObjectOwner implements M.VM {
|
||||||
bool typeChecksEnabled = false;
|
bool typeChecksEnabled = false;
|
||||||
int nativeZoneMemoryUsage = 0;
|
int nativeZoneMemoryUsage = 0;
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
int heapAllocatedMemoryUsage = 0;
|
int mallocUsed = 0;
|
||||||
int heapAllocationCount = 0;
|
int mallocCapacity = 0;
|
||||||
|
String mallocImplementation = 'unknown';
|
||||||
int currentMemory = 0;
|
int currentMemory = 0;
|
||||||
int maxRSS = 0;
|
int maxRSS = 0;
|
||||||
int currentRSS = 0;
|
int currentRSS = 0;
|
||||||
|
@ -1041,8 +1042,9 @@ abstract class VM extends ServiceObjectOwner implements M.VM {
|
||||||
nativeZoneMemoryUsage = map['_nativeZoneMemoryUsage'];
|
nativeZoneMemoryUsage = map['_nativeZoneMemoryUsage'];
|
||||||
}
|
}
|
||||||
pid = map['pid'];
|
pid = map['pid'];
|
||||||
heapAllocatedMemoryUsage = map['_heapAllocatedMemoryUsage'];
|
mallocUsed = map['_mallocUsed'];
|
||||||
heapAllocationCount = map['_heapAllocationCount'];
|
mallocCapacity = map['_mallocCapacity'];
|
||||||
|
mallocImplementation = map['_mallocImplementation'];
|
||||||
embedder = map['_embedder'];
|
embedder = map['_embedder'];
|
||||||
currentMemory = map['_currentMemory'];
|
currentMemory = map['_currentMemory'];
|
||||||
maxRSS = map['_maxRSS'];
|
maxRSS = map['_maxRSS'];
|
||||||
|
|
|
@ -174,14 +174,28 @@ class VMViewElement extends CustomElement implements Renderable {
|
||||||
..children = <Element>[
|
..children = <Element>[
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberName']
|
..classes = ['memberName']
|
||||||
..text = 'malloc memory',
|
..text = 'malloc used memory',
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberValue']
|
..classes = ['memberValue']
|
||||||
..text = _vm.heapAllocatedMemoryUsage != null
|
..text = _vm.mallocUsed != null
|
||||||
? Utils.formatSize(_vm.heapAllocatedMemoryUsage)
|
? Utils.formatSize(_vm.mallocUsed)
|
||||||
: 'unavailable'
|
: 'unavailable'
|
||||||
..title = _vm.heapAllocatedMemoryUsage != null
|
..title =
|
||||||
? '${_vm.heapAllocatedMemoryUsage} bytes'
|
_vm.mallocUsed != null ? '${_vm.mallocUsed} bytes' : null
|
||||||
|
],
|
||||||
|
new DivElement()
|
||||||
|
..classes = ['memberItem']
|
||||||
|
..children = <Element>[
|
||||||
|
new DivElement()
|
||||||
|
..classes = ['memberName']
|
||||||
|
..text = 'malloc capacity memory',
|
||||||
|
new DivElement()
|
||||||
|
..classes = ['memberValue']
|
||||||
|
..text = _vm.mallocCapacity != null
|
||||||
|
? Utils.formatSize(_vm.mallocCapacity)
|
||||||
|
: 'unavailable'
|
||||||
|
..title = _vm.mallocCapacity != null
|
||||||
|
? '${_vm.mallocCapacity} bytes'
|
||||||
: null
|
: null
|
||||||
],
|
],
|
||||||
new DivElement()
|
new DivElement()
|
||||||
|
@ -189,12 +203,10 @@ class VMViewElement extends CustomElement implements Renderable {
|
||||||
..children = <Element>[
|
..children = <Element>[
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberName']
|
..classes = ['memberName']
|
||||||
..text = 'malloc allocation count',
|
..text = 'malloc implementation',
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberValue']
|
..classes = ['memberValue']
|
||||||
..text = _vm.heapAllocationCount != null
|
..text = _vm.mallocImplementation
|
||||||
? '${_vm.heapAllocationCount}'
|
|
||||||
: 'unavailable'
|
|
||||||
],
|
],
|
||||||
new DivElement()
|
new DivElement()
|
||||||
..classes = ['memberItem']
|
..classes = ['memberItem']
|
||||||
|
|
|
@ -35,10 +35,9 @@ abstract class VM implements VMRef {
|
||||||
int get pid;
|
int get pid;
|
||||||
|
|
||||||
/// The current amount of native heap allocated memory within the VM.
|
/// The current amount of native heap allocated memory within the VM.
|
||||||
int get heapAllocatedMemoryUsage;
|
int get mallocUsed;
|
||||||
|
int get mallocCapacity;
|
||||||
/// The current number of allocations on the native heap within the VM.
|
String get mallocImplementation;
|
||||||
int get heapAllocationCount;
|
|
||||||
|
|
||||||
int get currentMemory;
|
int get currentMemory;
|
||||||
int get maxRSS;
|
int get maxRSS;
|
||||||
|
|
|
@ -681,8 +681,9 @@ abstract class VM extends ServiceObjectOwner implements M.VM {
|
||||||
bool typeChecksEnabled = false;
|
bool typeChecksEnabled = false;
|
||||||
int nativeZoneMemoryUsage = 0;
|
int nativeZoneMemoryUsage = 0;
|
||||||
int pid = 0;
|
int pid = 0;
|
||||||
int heapAllocatedMemoryUsage = 0;
|
int mallocUsed = 0;
|
||||||
int heapAllocationCount = 0;
|
int mallocCapacity = 0;
|
||||||
|
String mallocImplementation = 'unknown';
|
||||||
int currentMemory;
|
int currentMemory;
|
||||||
int maxRSS;
|
int maxRSS;
|
||||||
int currentRSS;
|
int currentRSS;
|
||||||
|
@ -1044,8 +1045,9 @@ abstract class VM extends ServiceObjectOwner implements M.VM {
|
||||||
nativeZoneMemoryUsage = map['_nativeZoneMemoryUsage'];
|
nativeZoneMemoryUsage = map['_nativeZoneMemoryUsage'];
|
||||||
}
|
}
|
||||||
pid = map['pid'];
|
pid = map['pid'];
|
||||||
heapAllocatedMemoryUsage = map['_heapAllocatedMemoryUsage'];
|
mallocUsed = map['_mallocUsed'];
|
||||||
heapAllocationCount = map['_heapAllocationCount'];
|
mallocCapacity = map['_mallocCapacity'];
|
||||||
|
mallocImplementation = map['_mallocImplementation'];
|
||||||
embedder = map['_embedder'];
|
embedder = map['_embedder'];
|
||||||
currentMemory = map['_currentMemory'];
|
currentMemory = map['_currentMemory'];
|
||||||
maxRSS = map['_maxRSS'];
|
maxRSS = map['_maxRSS'];
|
||||||
|
|
|
@ -30,7 +30,9 @@ class MallocHooks : public AllStatic {
|
||||||
static void set_stack_trace_collection_enabled(bool enabled);
|
static void set_stack_trace_collection_enabled(bool enabled);
|
||||||
static void ResetStats();
|
static void ResetStats();
|
||||||
static bool Active();
|
static bool Active();
|
||||||
static void PrintToJSONObject(JSONObject* jsobj);
|
static bool GetStats(intptr_t* used,
|
||||||
|
intptr_t* capacity,
|
||||||
|
const char** implementation);
|
||||||
static Sample* GetSample(const void* ptr);
|
static Sample* GetSample(const void* ptr);
|
||||||
|
|
||||||
static intptr_t allocation_count();
|
static intptr_t allocation_count();
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include "gperftools/malloc_hook.h"
|
#include "gperftools/malloc_hook.h"
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
#include "platform/assert.h"
|
#include "platform/assert.h"
|
||||||
#include "vm/hash_map.h"
|
#include "vm/hash_map.h"
|
||||||
#include "vm/json_stream.h"
|
#include "vm/json_stream.h"
|
||||||
|
@ -336,29 +338,14 @@ bool MallocHooks::Active() {
|
||||||
return MallocHooksState::Active();
|
return MallocHooksState::Active();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocHooks::PrintToJSONObject(JSONObject* jsobj) {
|
bool MallocHooks::GetStats(intptr_t* used,
|
||||||
if (!FLAG_profiler_native_memory) {
|
intptr_t* capacity,
|
||||||
return;
|
const char** implementation) {
|
||||||
}
|
struct mallinfo info = mallinfo();
|
||||||
intptr_t allocated_memory = 0;
|
*used = info.uordblks;
|
||||||
intptr_t allocation_count = 0;
|
*capacity = *used + info.fordblks;
|
||||||
bool add_usage = false;
|
*implementation = "tcmalloc";
|
||||||
// AddProperty may call malloc which would result in an attempt
|
return true;
|
||||||
// to acquire the lock recursively so we extract the values first
|
|
||||||
// and then add the JSON properties.
|
|
||||||
{
|
|
||||||
MallocLocker ml(MallocHooksState::malloc_hook_mutex(),
|
|
||||||
MallocHooksState::malloc_hook_mutex_owner());
|
|
||||||
if (MallocHooksState::Active()) {
|
|
||||||
allocated_memory = MallocHooksState::heap_allocated_memory_in_bytes();
|
|
||||||
allocation_count = MallocHooksState::allocation_count();
|
|
||||||
add_usage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (add_usage) {
|
|
||||||
jsobj->AddProperty("_heapAllocatedMemoryUsage", allocated_memory);
|
|
||||||
jsobj->AddProperty("_heapAllocationCount", allocation_count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t MallocHooks::allocation_count() {
|
intptr_t MallocHooks::allocation_count() {
|
||||||
|
|
|
@ -8,6 +8,24 @@
|
||||||
|
|
||||||
#include "vm/malloc_hooks.h"
|
#include "vm/malloc_hooks.h"
|
||||||
|
|
||||||
|
#include "vm/json_stream.h"
|
||||||
|
|
||||||
|
#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
|
||||||
|
#include <malloc.h>
|
||||||
|
#elif defined(HOST_OS_MACOS)
|
||||||
|
#include <malloc/malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HOST_OS_WINDOWS) && !defined(TARGET_OS_IOS)
|
||||||
|
extern "C" {
|
||||||
|
__attribute__((weak)) uintptr_t __sanitizer_get_current_allocated_bytes();
|
||||||
|
__attribute__((weak)) uintptr_t __sanitizer_get_heap_size();
|
||||||
|
__attribute__((weak)) int __sanitizer_install_malloc_and_free_hooks(
|
||||||
|
void (*malloc_hook)(const void*, uintptr_t),
|
||||||
|
void (*free_hook)(const void*));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace dart {
|
namespace dart {
|
||||||
|
|
||||||
void MallocHooks::Init() {
|
void MallocHooks::Init() {
|
||||||
|
@ -38,8 +56,37 @@ bool MallocHooks::Active() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MallocHooks::PrintToJSONObject(JSONObject* jsobj) {
|
bool MallocHooks::GetStats(intptr_t* used,
|
||||||
// Do nothing.
|
intptr_t* capacity,
|
||||||
|
const char** implementation) {
|
||||||
|
#if !defined(PRODUCT)
|
||||||
|
#if !defined(HOST_OS_WINDOWS) && !defined(TARGET_OS_IOS)
|
||||||
|
if (__sanitizer_get_current_allocated_bytes != nullptr &&
|
||||||
|
__sanitizer_get_heap_size != nullptr) {
|
||||||
|
*used = __sanitizer_get_current_allocated_bytes();
|
||||||
|
*capacity = __sanitizer_get_heap_size();
|
||||||
|
*implementation = "scudo";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
|
||||||
|
struct mallinfo info = mallinfo();
|
||||||
|
*used = info.uordblks;
|
||||||
|
*capacity = *used + info.fordblks;
|
||||||
|
*implementation = "unknown";
|
||||||
|
return true;
|
||||||
|
#elif defined(HOST_OS_MACOS)
|
||||||
|
struct mstats stats = mstats();
|
||||||
|
*used = stats.bytes_used;
|
||||||
|
*capacity = stats.bytes_total;
|
||||||
|
*implementation = "macos";
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Sample* MallocHooks::GetSample(const void* ptr) {
|
Sample* MallocHooks::GetSample(const void* ptr) {
|
||||||
|
|
|
@ -4329,94 +4329,122 @@ static intptr_t GetProcessMemoryUsageHelper(JSONStream* js) {
|
||||||
rss.AddProperty64("size", Service::CurrentRSS());
|
rss.AddProperty64("size", Service::CurrentRSS());
|
||||||
JSONArray rss_children(&rss, "children");
|
JSONArray rss_children(&rss, "children");
|
||||||
|
|
||||||
JSONObject vm(&rss_children);
|
|
||||||
intptr_t vm_size = 0;
|
intptr_t vm_size = 0;
|
||||||
{
|
{
|
||||||
JSONArray vm_children(&vm, "children");
|
JSONObject vm(&rss_children);
|
||||||
|
{
|
||||||
|
JSONArray vm_children(&vm, "children");
|
||||||
|
|
||||||
|
{
|
||||||
|
JSONObject profiler(&vm_children);
|
||||||
|
profiler.AddProperty("name", "Profiler");
|
||||||
|
profiler.AddProperty("description",
|
||||||
|
"Samples from the Dart VM's profiler");
|
||||||
|
intptr_t size = Profiler::Size();
|
||||||
|
vm_size += size;
|
||||||
|
profiler.AddProperty64("size", size);
|
||||||
|
JSONArray(&profiler, "children");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JSONObject timeline(&vm_children);
|
||||||
|
timeline.AddProperty("name", "Timeline");
|
||||||
|
timeline.AddProperty(
|
||||||
|
"description",
|
||||||
|
"Timeline events from dart:developer and Dart_TimelineEvent");
|
||||||
|
intptr_t size = Timeline::recorder()->Size();
|
||||||
|
vm_size += size;
|
||||||
|
timeline.AddProperty64("size", size);
|
||||||
|
JSONArray(&timeline, "children");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JSONObject zone(&vm_children);
|
||||||
|
zone.AddProperty("name", "Zone");
|
||||||
|
zone.AddProperty("description", "Arena allocation in the Dart VM");
|
||||||
|
intptr_t size = Zone::Size();
|
||||||
|
vm_size += size;
|
||||||
|
zone.AddProperty64("size", size);
|
||||||
|
JSONArray(&zone, "children");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JSONObject semi(&vm_children);
|
||||||
|
semi.AddProperty("name", "SemiSpace Cache");
|
||||||
|
semi.AddProperty("description", "Cached heap regions");
|
||||||
|
intptr_t size = SemiSpace::CachedSize();
|
||||||
|
vm_size += size;
|
||||||
|
semi.AddProperty64("size", size);
|
||||||
|
JSONArray(&semi, "children");
|
||||||
|
}
|
||||||
|
|
||||||
|
IsolateGroup::ForEach([&vm_children,
|
||||||
|
&vm_size](IsolateGroup* isolate_group) {
|
||||||
|
// Note: new_space()->CapacityInWords() includes memory that hasn't been
|
||||||
|
// allocated from the OS yet.
|
||||||
|
int64_t capacity =
|
||||||
|
(isolate_group->heap()->new_space()->UsedInWords() +
|
||||||
|
isolate_group->heap()->old_space()->CapacityInWords()) *
|
||||||
|
kWordSize;
|
||||||
|
int64_t used = isolate_group->heap()->TotalUsedInWords() * kWordSize;
|
||||||
|
int64_t free = capacity - used;
|
||||||
|
|
||||||
|
JSONObject group(&vm_children);
|
||||||
|
group.AddPropertyF("name", "IsolateGroup %s",
|
||||||
|
isolate_group->source()->name);
|
||||||
|
group.AddProperty("description", "Dart heap capacity");
|
||||||
|
vm_size += capacity;
|
||||||
|
group.AddProperty64("size", capacity);
|
||||||
|
JSONArray group_children(&group, "children");
|
||||||
|
|
||||||
|
{
|
||||||
|
JSONObject jsused(&group_children);
|
||||||
|
jsused.AddProperty("name", "Used");
|
||||||
|
jsused.AddProperty("description", "");
|
||||||
|
jsused.AddProperty64("size", used);
|
||||||
|
JSONArray(&jsused, "children");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JSONObject jsfree(&group_children);
|
||||||
|
jsfree.AddProperty("name", "Free");
|
||||||
|
jsfree.AddProperty("description", "");
|
||||||
|
jsfree.AddProperty64("size", free);
|
||||||
|
JSONArray(&jsfree, "children");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} // vm_children
|
||||||
|
|
||||||
|
vm.AddProperty("name", "Dart VM");
|
||||||
|
vm.AddProperty("description", "");
|
||||||
|
vm.AddProperty64("size", vm_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t used, capacity;
|
||||||
|
const char* implementation;
|
||||||
|
if (MallocHooks::GetStats(&used, &capacity, &implementation)) {
|
||||||
|
JSONObject malloc(&rss_children);
|
||||||
|
malloc.AddPropertyF("name", "Malloc (%s)", implementation);
|
||||||
|
malloc.AddProperty("description", "");
|
||||||
|
malloc.AddProperty64("size", capacity);
|
||||||
|
JSONArray malloc_children(&malloc, "children");
|
||||||
|
|
||||||
{
|
{
|
||||||
JSONObject profiler(&vm_children);
|
JSONObject malloc_used(&malloc_children);
|
||||||
profiler.AddProperty("name", "Profiler");
|
malloc_used.AddProperty("name", "Used");
|
||||||
profiler.AddProperty("description",
|
malloc_used.AddProperty("description", "");
|
||||||
"Samples from the Dart VM's profiler");
|
malloc_used.AddProperty64("size", used);
|
||||||
intptr_t size = Profiler::Size();
|
JSONArray(&malloc_used, "children");
|
||||||
vm_size += size;
|
|
||||||
profiler.AddProperty64("size", size);
|
|
||||||
JSONArray(&profiler, "children");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
JSONObject timeline(&vm_children);
|
JSONObject malloc_free(&malloc_children);
|
||||||
timeline.AddProperty("name", "Timeline");
|
malloc_free.AddProperty("name", "Free");
|
||||||
timeline.AddProperty(
|
malloc_free.AddProperty("description", "");
|
||||||
"description",
|
malloc_free.AddProperty64("size", capacity - used);
|
||||||
"Timeline events from dart:developer and Dart_TimelineEvent");
|
JSONArray(&malloc_free, "children");
|
||||||
intptr_t size = Timeline::recorder()->Size();
|
|
||||||
vm_size += size;
|
|
||||||
timeline.AddProperty64("size", size);
|
|
||||||
JSONArray(&timeline, "children");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
{
|
|
||||||
JSONObject zone(&vm_children);
|
|
||||||
zone.AddProperty("name", "Zone");
|
|
||||||
zone.AddProperty("description", "Arena allocation in the Dart VM");
|
|
||||||
intptr_t size = Zone::Size();
|
|
||||||
vm_size += size;
|
|
||||||
zone.AddProperty64("size", size);
|
|
||||||
JSONArray(&zone, "children");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
JSONObject semi(&vm_children);
|
|
||||||
semi.AddProperty("name", "SemiSpace Cache");
|
|
||||||
semi.AddProperty("description", "Cached heap regions");
|
|
||||||
intptr_t size = SemiSpace::CachedSize();
|
|
||||||
vm_size += size;
|
|
||||||
semi.AddProperty64("size", size);
|
|
||||||
JSONArray(&semi, "children");
|
|
||||||
}
|
|
||||||
|
|
||||||
IsolateGroup::ForEach(
|
|
||||||
[&vm_children, &vm_size](IsolateGroup* isolate_group) {
|
|
||||||
// Note: new_space()->CapacityInWords() includes memory that hasn't
|
|
||||||
// been allocated from the OS yet.
|
|
||||||
int64_t capacity =
|
|
||||||
(isolate_group->heap()->new_space()->UsedInWords() +
|
|
||||||
isolate_group->heap()->old_space()->CapacityInWords()) *
|
|
||||||
kWordSize;
|
|
||||||
int64_t used = isolate_group->heap()->TotalUsedInWords() * kWordSize;
|
|
||||||
int64_t free = capacity - used;
|
|
||||||
|
|
||||||
JSONObject group(&vm_children);
|
|
||||||
group.AddPropertyF("name", "IsolateGroup %s",
|
|
||||||
isolate_group->source()->name);
|
|
||||||
group.AddProperty("description", "Dart heap capacity");
|
|
||||||
vm_size += capacity;
|
|
||||||
group.AddProperty64("size", capacity);
|
|
||||||
JSONArray group_children(&group, "children");
|
|
||||||
|
|
||||||
{
|
|
||||||
JSONObject jsused(&group_children);
|
|
||||||
jsused.AddProperty("name", "Used");
|
|
||||||
jsused.AddProperty("description", "");
|
|
||||||
jsused.AddProperty64("size", used);
|
|
||||||
JSONArray(&jsused, "children");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
JSONObject jsfree(&group_children);
|
|
||||||
jsfree.AddProperty("name", "Free");
|
|
||||||
jsfree.AddProperty("description", "");
|
|
||||||
jsfree.AddProperty64("size", free);
|
|
||||||
JSONArray(&jsfree, "children");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} // vm_children
|
|
||||||
|
|
||||||
vm.AddProperty("name", "Dart VM");
|
|
||||||
vm.AddProperty("description", "");
|
|
||||||
vm.AddProperty64("size", vm_size);
|
|
||||||
|
|
||||||
return vm_size;
|
return vm_size;
|
||||||
}
|
}
|
||||||
|
@ -4848,7 +4876,15 @@ void Service::PrintJSONForVM(JSONStream* js, bool ref) {
|
||||||
jsobj.AddProperty64("pid", OS::ProcessId());
|
jsobj.AddProperty64("pid", OS::ProcessId());
|
||||||
jsobj.AddPropertyTimeMillis(
|
jsobj.AddPropertyTimeMillis(
|
||||||
"startTime", OS::GetCurrentTimeMillis() - Dart::UptimeMillis());
|
"startTime", OS::GetCurrentTimeMillis() - Dart::UptimeMillis());
|
||||||
MallocHooks::PrintToJSONObject(&jsobj);
|
{
|
||||||
|
intptr_t used, capacity;
|
||||||
|
const char* implementation;
|
||||||
|
if (MallocHooks::GetStats(&used, &capacity, &implementation)) {
|
||||||
|
jsobj.AddProperty("_mallocUsed", used);
|
||||||
|
jsobj.AddProperty("_mallocCapacity", capacity);
|
||||||
|
jsobj.AddProperty("_mallocImplementation", implementation);
|
||||||
|
}
|
||||||
|
}
|
||||||
PrintJSONForEmbedderInformation(&jsobj);
|
PrintJSONForEmbedderInformation(&jsobj);
|
||||||
// Construct the isolate and isolate_groups list.
|
// Construct the isolate and isolate_groups list.
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue