Commit a7b368ee authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

Heap Object Stats: Track external string resources

This CL adds support for the following virtual string types:
 - SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE
 - SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE
 - SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE
 - SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE
 - STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE
 - STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE

Change-Id: I8d278ede356bae4ba63c1dae45a347f1261c75cc
Reviewed-on: https://chromium-review.googlesource.com/1174392Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55230}
parent 67b54993
......@@ -341,6 +341,9 @@ class ObjectStatsCollectorImpl {
ObjectStats::VirtualInstanceType type,
size_t size, size_t over_allocated,
CowMode check_cow_array = kCheckCow);
void RecordExternalResourceStats(Address resource,
ObjectStats::VirtualInstanceType type,
size_t size);
// Gets size from |ob| and assumes no over allocating.
bool RecordSimpleVirtualObjectStats(HeapObject* parent, HeapObject* obj,
ObjectStats::VirtualInstanceType type);
......@@ -379,6 +382,7 @@ class ObjectStatsCollectorImpl {
void RecordVirtualJSObjectDetails(JSObject* object);
void RecordVirtualMapDetails(Map* map);
void RecordVirtualScriptDetails(Script* script);
void RecordVirtualExternalStringDetails(ExternalString* script);
void RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo* info);
void RecordVirtualJSFunctionDetails(JSFunction* function);
......@@ -388,6 +392,7 @@ class ObjectStatsCollectorImpl {
ObjectStats* stats_;
MarkCompactCollector::NonAtomicMarkingState* marking_state_;
std::unordered_set<HeapObject*> virtual_objects_;
std::unordered_set<Address> external_resources_;
FieldStatsCollector field_stats_collector_;
};
......@@ -431,8 +436,9 @@ bool ObjectStatsCollectorImpl::RecordSimpleVirtualObjectStats(
bool ObjectStatsCollectorImpl::RecordVirtualObjectStats(
HeapObject* parent, HeapObject* obj, ObjectStats::VirtualInstanceType type,
size_t size, size_t over_allocated, CowMode check_cow_array) {
if (!SameLiveness(parent, obj) || !ShouldRecordObject(obj, check_cow_array))
if (!SameLiveness(parent, obj) || !ShouldRecordObject(obj, check_cow_array)) {
return false;
}
if (virtual_objects_.find(obj) == virtual_objects_.end()) {
virtual_objects_.insert(obj);
......@@ -442,6 +448,14 @@ bool ObjectStatsCollectorImpl::RecordVirtualObjectStats(
return false;
}
void ObjectStatsCollectorImpl::RecordExternalResourceStats(
Address resource, ObjectStats::VirtualInstanceType type, size_t size) {
if (external_resources_.find(resource) == external_resources_.end()) {
external_resources_.insert(resource);
stats_->RecordVirtualObjectStats(type, size, 0);
}
}
void ObjectStatsCollectorImpl::RecordVirtualAllocationSiteDetails(
AllocationSite* site) {
if (!site->PointsToLiteral()) return;
......@@ -663,6 +677,8 @@ void ObjectStatsCollectorImpl::CollectStatistics(
RecordVirtualContext(Context::cast(obj));
} else if (obj->IsScript()) {
RecordVirtualScriptDetails(Script::cast(obj));
} else if (obj->IsExternalString()) {
RecordVirtualExternalStringDetails(ExternalString::cast(obj));
} else if (obj->IsArrayBoilerplateDescription()) {
RecordVirtualArrayBoilerplateDescription(
ArrayBoilerplateDescription::cast(obj));
......@@ -775,24 +791,44 @@ void ObjectStatsCollectorImpl::RecordVirtualScriptDetails(Script* script) {
ObjectStats::SCRIPT_SHARED_FUNCTION_INFOS_TYPE);
// Log the size of external source code.
Object* source = script->source();
if (source->IsExternalString()) {
Object* raw_source = script->source();
if (raw_source->IsExternalString()) {
// The contents of external strings aren't on the heap, so we have to record
// them manually.
ExternalString* external_source_string = ExternalString::cast(source);
size_t off_heap_size = external_source_string->ExternalPayloadSize();
size_t on_heap_size = external_source_string->Size();
RecordVirtualObjectStats(script, external_source_string,
ObjectStats::SCRIPT_SOURCE_EXTERNAL_TYPE,
on_heap_size + off_heap_size,
ObjectStats::kNoOverAllocation);
} else if (source->IsHeapObject()) {
// them manually. The on-heap String object is recorded indepentendely in
// the normal pass.
ExternalString* string = ExternalString::cast(raw_source);
Address resource = string->resource_as_address();
size_t off_heap_size = string->ExternalPayloadSize();
RecordExternalResourceStats(
resource,
string->IsOneByteRepresentation()
? ObjectStats::SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE
: ObjectStats::SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE,
off_heap_size);
} else if (raw_source->IsString()) {
String* source = String::cast(raw_source);
RecordSimpleVirtualObjectStats(
script, HeapObject::cast(source),
ObjectStats::SCRIPT_SOURCE_NON_EXTERNAL_TYPE);
script, HeapObject::cast(raw_source),
source->IsOneByteRepresentation()
? ObjectStats::SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE
: ObjectStats::SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE);
}
}
void ObjectStatsCollectorImpl::RecordVirtualExternalStringDetails(
ExternalString* string) {
// Track the external string resource size in a separate category.
Address resource = string->resource_as_address();
size_t off_heap_size = string->ExternalPayloadSize();
RecordExternalResourceStats(
resource,
string->IsOneByteRepresentation()
? ObjectStats::STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE
: ObjectStats::STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE,
off_heap_size);
}
void ObjectStatsCollectorImpl::RecordVirtualSharedFunctionInfoDetails(
SharedFunctionInfo* info) {
// Uncompiled SharedFunctionInfo gets its own category.
......
......@@ -58,11 +58,15 @@
V(RETAINED_MAPS_TYPE) \
V(SCRIPT_LIST_TYPE) \
V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE) \
V(SCRIPT_SOURCE_EXTERNAL_TYPE) \
V(SCRIPT_SOURCE_NON_EXTERNAL_TYPE) \
V(SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE) \
V(SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE) \
V(SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE) \
V(SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE) \
V(SERIALIZED_OBJECTS_TYPE) \
V(SINGLE_CHARACTER_STRING_CACHE_TYPE) \
V(STRING_SPLIT_CACHE_TYPE) \
V(STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE) \
V(STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE) \
V(SOURCE_POSITION_TABLE_TYPE) \
V(UNCOMPILED_JS_FUNCTION_TYPE) \
V(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE) \
......
......@@ -76,6 +76,8 @@ const CATEGORIES = new Map([
'SHORT_EXTERNAL_STRING_TYPE',
'SLICED_ONE_BYTE_STRING_TYPE',
'SLICED_STRING_TYPE',
'STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE',
'STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE',
'STRING_TYPE',
'SYMBOL_TYPE',
'THIN_ONE_BYTE_STRING_TYPE',
......@@ -140,13 +142,10 @@ const CATEGORIES = new Map([
[
'code', new Set([
'BUILTIN',
'BYTECODE_HANDLER',
'OPTIMIZED_FUNCTION',
'REGEXP',
'STUB',
'BYTECODE_ARRAY_CONSTANT_POOL_TYPE',
'BYTECODE_ARRAY_HANDLER_TABLE_TYPE',
'BYTECODE_ARRAY_TYPE',
'BYTECODE_HANDLER',
'CODE_DATA_CONTAINER_TYPE',
'DEOPTIMIZATION_DATA_TYPE',
'EMBEDDED_OBJECT_TYPE',
......@@ -166,15 +165,24 @@ const CATEGORIES = new Map([
'LOAD_HANDLER_TYPE',
'NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE',
'OPTIMIZED_CODE_LITERALS_TYPE',
'OPTIMIZED_FUNCTION',
'PRE_PARSED_SCOPE_DATA_TYPE',
'REGEXP',
'RELOC_INFO_TYPE',
'SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE',
'SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE',
'SCRIPT_SOURCE_EXTERNAL_TYPE',
'SCRIPT_SOURCE_NON_EXTERNAL_TYPE',
'SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE',
'SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE',
'SCRIPT_TYPE',
'SHARED_FUNCTION_INFO_TYPE',
'SOURCE_POSITION_TABLE_TYPE',
'STORE_HANDLER_TYPE',
'STUB',
'UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE',
'UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE',
'UNCOMPILED_JS_FUNCTION_TYPE',
'UNCOMPILED_SHARED_FUNCTION_INFO_TYPE',
'UNCOMPILED_SHARED_FUNCTION_INFO_TYPE'
])
],
['unclassified', new Set()],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment