[object-stats] Record feedback vector slots separately
Record the various types of feedback vector slot separately, to estimate the relative impact of e.g. load ICs vs call ICs. Also, log the unused (i.e. uninitialized or premonomorphic) ones separately. Bug: v8:7266 Change-Id: Ie035cf48969e39f7156dfe523fd9218749b95cfe Reviewed-on: https://chromium-review.googlesource.com/897813 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#51067}
This commit is contained in:
parent
f4411a32cd
commit
02cf73ccbf
@ -404,17 +404,89 @@ void ObjectStatsCollectorImpl::RecordVirtualJSObjectDetails(JSObject* object) {
|
||||
RecordSimpleVirtualObjectStats(object, elements, ObjectStats::ELEMENTS_TYPE);
|
||||
}
|
||||
|
||||
static ObjectStats::VirtualInstanceType GetFeedbackSlotType(
|
||||
Object* obj, FeedbackSlotKind kind, Isolate* isolate) {
|
||||
switch (kind) {
|
||||
case FeedbackSlotKind::kCall:
|
||||
if (obj == *isolate->factory()->uninitialized_symbol() ||
|
||||
obj == *isolate->factory()->premonomorphic_symbol()) {
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE;
|
||||
}
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_CALL_TYPE;
|
||||
|
||||
case FeedbackSlotKind::kLoadProperty:
|
||||
case FeedbackSlotKind::kLoadGlobalInsideTypeof:
|
||||
case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
|
||||
case FeedbackSlotKind::kLoadKeyed:
|
||||
if (obj == *isolate->factory()->uninitialized_symbol() ||
|
||||
obj == *isolate->factory()->premonomorphic_symbol()) {
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE;
|
||||
}
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_LOAD_TYPE;
|
||||
|
||||
case FeedbackSlotKind::kStoreNamedSloppy:
|
||||
case FeedbackSlotKind::kStoreNamedStrict:
|
||||
case FeedbackSlotKind::kStoreOwnNamed:
|
||||
case FeedbackSlotKind::kStoreGlobalSloppy:
|
||||
case FeedbackSlotKind::kStoreGlobalStrict:
|
||||
case FeedbackSlotKind::kStoreKeyedSloppy:
|
||||
case FeedbackSlotKind::kStoreKeyedStrict:
|
||||
if (obj == *isolate->factory()->uninitialized_symbol() ||
|
||||
obj == *isolate->factory()->premonomorphic_symbol()) {
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE;
|
||||
}
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_STORE_TYPE;
|
||||
|
||||
case FeedbackSlotKind::kBinaryOp:
|
||||
case FeedbackSlotKind::kCompareOp:
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_ENUM_TYPE;
|
||||
|
||||
default:
|
||||
return ObjectStats::FEEDBACK_VECTOR_SLOT_OTHER_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
|
||||
FeedbackVector* vector) {
|
||||
// Except for allocation
|
||||
for (int i = 0; i < vector->length(); i++) {
|
||||
Object* raw_object = vector->get(i);
|
||||
if (!raw_object->IsHeapObject()) continue;
|
||||
HeapObject* object = HeapObject::cast(raw_object);
|
||||
if (object->IsCell() || object->IsFixedArray()) {
|
||||
RecordSimpleVirtualObjectStats(vector, object,
|
||||
ObjectStats::FEEDBACK_VECTOR_ENTRY_TYPE);
|
||||
if (virtual_objects_.find(vector) == virtual_objects_.end()) {
|
||||
// Manually insert the feedback vector into the virtual object list, since
|
||||
// we're logging its component parts separately.
|
||||
virtual_objects_.insert(vector);
|
||||
|
||||
size_t calculated_size = 0;
|
||||
|
||||
// Log the feedback vector's header (fixed fields).
|
||||
size_t header_size =
|
||||
reinterpret_cast<Address>(vector->slots_start()) - vector->address();
|
||||
stats_->RecordVirtualObjectStats(ObjectStats::FEEDBACK_VECTOR_HEADER_TYPE,
|
||||
header_size,
|
||||
ObjectStats::kNoOverAllocation);
|
||||
calculated_size += header_size;
|
||||
|
||||
// Iterate over the feedback slots and log each one.
|
||||
FeedbackMetadataIterator it(vector->metadata());
|
||||
while (it.HasNext()) {
|
||||
FeedbackSlot slot = it.Next();
|
||||
// Log the entry (or entries) taken up by this slot.
|
||||
size_t slot_size = it.entry_size() * kPointerSize;
|
||||
stats_->RecordVirtualObjectStats(
|
||||
GetFeedbackSlotType(vector->Get(slot), it.kind(), heap_->isolate()),
|
||||
slot_size, ObjectStats::kNoOverAllocation);
|
||||
calculated_size += slot_size;
|
||||
|
||||
// Log the monomorphic/polymorphic helper objects that this slot owns.
|
||||
for (int i = 0; i < it.entry_size(); i++) {
|
||||
Object* raw_object = vector->get(slot.ToInt() + i);
|
||||
if (!raw_object->IsHeapObject()) continue;
|
||||
HeapObject* object = HeapObject::cast(raw_object);
|
||||
if (object->IsCell() || object->IsFixedArray()) {
|
||||
RecordSimpleVirtualObjectStats(
|
||||
vector, object, ObjectStats::FEEDBACK_VECTOR_ENTRY_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_EQ(calculated_size, vector->Size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,49 +14,58 @@
|
||||
// tracing.
|
||||
//
|
||||
// Update LAST_VIRTUAL_TYPE below when changing this macro.
|
||||
#define VIRTUAL_INSTANCE_TYPE_LIST(V) \
|
||||
CODE_KIND_LIST(V) \
|
||||
V(BOILERPLATE_ELEMENTS_TYPE) \
|
||||
V(BOILERPLATE_PROPERTY_ARRAY_TYPE) \
|
||||
V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE) \
|
||||
V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE) \
|
||||
V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE) \
|
||||
V(CODE_STUBS_TABLE_TYPE) \
|
||||
V(COW_ARRAY_TYPE) \
|
||||
V(DEOPTIMIZATION_DATA_TYPE) \
|
||||
V(DEPENDENT_CODE_TYPE) \
|
||||
V(ELEMENTS_TYPE) \
|
||||
V(EMBEDDED_OBJECT_TYPE) \
|
||||
V(ENUM_CACHE_TYPE) \
|
||||
V(ENUM_INDICES_CACHE_TYPE) \
|
||||
V(FEEDBACK_METADATA_TYPE) \
|
||||
V(FEEDBACK_VECTOR_ENTRY_TYPE) \
|
||||
V(FUNCTION_CONTEXT_TYPE) \
|
||||
V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE) \
|
||||
V(GLOBAL_ELEMENTS_TYPE) \
|
||||
V(GLOBAL_PROPERTIES_TYPE) \
|
||||
V(JS_ARRAY_BOILERPLATE_TYPE) \
|
||||
V(JS_COLLETION_TABLE_TYPE) \
|
||||
V(JS_OBJECT_BOILERPLATE_TYPE) \
|
||||
V(NATIVE_CONTEXT_TYPE) \
|
||||
V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE) \
|
||||
V(NUMBER_STRING_CACHE_TYPE) \
|
||||
V(OBJECT_PROPERTY_DICTIONARY_TYPE) \
|
||||
V(OBJECT_TO_CODE_TYPE) \
|
||||
V(OPTIMIZED_CODE_LITERALS_TYPE) \
|
||||
V(OTHER_CONTEXT_TYPE) \
|
||||
V(PROTOTYPE_USERS_TYPE) \
|
||||
V(REGEXP_MULTIPLE_CACHE_TYPE) \
|
||||
V(RETAINED_MAPS_TYPE) \
|
||||
V(SCOPE_INFO_TYPE) \
|
||||
V(SCRIPT_LIST_TYPE) \
|
||||
V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE) \
|
||||
V(SERIALIZED_OBJECTS_TYPE) \
|
||||
V(SINGLE_CHARACTER_STRING_CACHE_TYPE) \
|
||||
V(STRING_SPLIT_CACHE_TYPE) \
|
||||
V(STRING_TABLE_TYPE) \
|
||||
V(UNCOMPILED_JS_FUNCTION_TYPE) \
|
||||
V(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE) \
|
||||
#define VIRTUAL_INSTANCE_TYPE_LIST(V) \
|
||||
CODE_KIND_LIST(V) \
|
||||
V(BOILERPLATE_ELEMENTS_TYPE) \
|
||||
V(BOILERPLATE_PROPERTY_ARRAY_TYPE) \
|
||||
V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE) \
|
||||
V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE) \
|
||||
V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE) \
|
||||
V(CODE_STUBS_TABLE_TYPE) \
|
||||
V(COW_ARRAY_TYPE) \
|
||||
V(DEOPTIMIZATION_DATA_TYPE) \
|
||||
V(DEPENDENT_CODE_TYPE) \
|
||||
V(ELEMENTS_TYPE) \
|
||||
V(EMBEDDED_OBJECT_TYPE) \
|
||||
V(ENUM_CACHE_TYPE) \
|
||||
V(ENUM_INDICES_CACHE_TYPE) \
|
||||
V(FEEDBACK_METADATA_TYPE) \
|
||||
V(FEEDBACK_VECTOR_ENTRY_TYPE) \
|
||||
V(FEEDBACK_VECTOR_HEADER_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_CALL_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_LOAD_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_OTHER_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_STORE_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE) \
|
||||
V(FUNCTION_CONTEXT_TYPE) \
|
||||
V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE) \
|
||||
V(GLOBAL_ELEMENTS_TYPE) \
|
||||
V(GLOBAL_PROPERTIES_TYPE) \
|
||||
V(JS_ARRAY_BOILERPLATE_TYPE) \
|
||||
V(JS_COLLETION_TABLE_TYPE) \
|
||||
V(JS_OBJECT_BOILERPLATE_TYPE) \
|
||||
V(NATIVE_CONTEXT_TYPE) \
|
||||
V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE) \
|
||||
V(NUMBER_STRING_CACHE_TYPE) \
|
||||
V(OBJECT_PROPERTY_DICTIONARY_TYPE) \
|
||||
V(OBJECT_TO_CODE_TYPE) \
|
||||
V(OPTIMIZED_CODE_LITERALS_TYPE) \
|
||||
V(OTHER_CONTEXT_TYPE) \
|
||||
V(PROTOTYPE_USERS_TYPE) \
|
||||
V(REGEXP_MULTIPLE_CACHE_TYPE) \
|
||||
V(RETAINED_MAPS_TYPE) \
|
||||
V(SCOPE_INFO_TYPE) \
|
||||
V(SCRIPT_LIST_TYPE) \
|
||||
V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE) \
|
||||
V(SERIALIZED_OBJECTS_TYPE) \
|
||||
V(SINGLE_CHARACTER_STRING_CACHE_TYPE) \
|
||||
V(STRING_SPLIT_CACHE_TYPE) \
|
||||
V(STRING_TABLE_TYPE) \
|
||||
V(UNCOMPILED_JS_FUNCTION_TYPE) \
|
||||
V(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE) \
|
||||
V(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE)
|
||||
|
||||
namespace v8 {
|
||||
|
@ -144,7 +144,16 @@ const CATEGORIES = new Map([
|
||||
'DEOPTIMIZATION_DATA_TYPE',
|
||||
'EMBEDDED_OBJECT_TYPE',
|
||||
'FEEDBACK_METADATA_TYPE',
|
||||
'FEEDBACK_VECTOR_HEADER_TYPE',
|
||||
'FEEDBACK_VECTOR_ENTRY_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_CALL_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_ENUM_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_LOAD_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_OTHER_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_STORE_TYPE',
|
||||
'FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE',
|
||||
'FEEDBACK_VECTOR_TYPE',
|
||||
'LOAD_HANDLER_TYPE',
|
||||
'NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE',
|
||||
|
Loading…
Reference in New Issue
Block a user