Commit 02cf73cc authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[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: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51067}
parent f4411a32
...@@ -404,17 +404,89 @@ void ObjectStatsCollectorImpl::RecordVirtualJSObjectDetails(JSObject* object) { ...@@ -404,17 +404,89 @@ void ObjectStatsCollectorImpl::RecordVirtualJSObjectDetails(JSObject* object) {
RecordSimpleVirtualObjectStats(object, elements, ObjectStats::ELEMENTS_TYPE); 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( void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
FeedbackVector* vector) { FeedbackVector* vector) {
// Except for allocation if (virtual_objects_.find(vector) == virtual_objects_.end()) {
for (int i = 0; i < vector->length(); i++) { // Manually insert the feedback vector into the virtual object list, since
Object* raw_object = vector->get(i); // we're logging its component parts separately.
if (!raw_object->IsHeapObject()) continue; virtual_objects_.insert(vector);
HeapObject* object = HeapObject::cast(raw_object);
if (object->IsCell() || object->IsFixedArray()) { size_t calculated_size = 0;
RecordSimpleVirtualObjectStats(vector, object,
ObjectStats::FEEDBACK_VECTOR_ENTRY_TYPE); // 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 @@ ...@@ -14,49 +14,58 @@
// tracing. // tracing.
// //
// Update LAST_VIRTUAL_TYPE below when changing this macro. // Update LAST_VIRTUAL_TYPE below when changing this macro.
#define VIRTUAL_INSTANCE_TYPE_LIST(V) \ #define VIRTUAL_INSTANCE_TYPE_LIST(V) \
CODE_KIND_LIST(V) \ CODE_KIND_LIST(V) \
V(BOILERPLATE_ELEMENTS_TYPE) \ V(BOILERPLATE_ELEMENTS_TYPE) \
V(BOILERPLATE_PROPERTY_ARRAY_TYPE) \ V(BOILERPLATE_PROPERTY_ARRAY_TYPE) \
V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE) \ V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE) \
V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE) \ V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE) \
V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE) \ V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE) \
V(CODE_STUBS_TABLE_TYPE) \ V(CODE_STUBS_TABLE_TYPE) \
V(COW_ARRAY_TYPE) \ V(COW_ARRAY_TYPE) \
V(DEOPTIMIZATION_DATA_TYPE) \ V(DEOPTIMIZATION_DATA_TYPE) \
V(DEPENDENT_CODE_TYPE) \ V(DEPENDENT_CODE_TYPE) \
V(ELEMENTS_TYPE) \ V(ELEMENTS_TYPE) \
V(EMBEDDED_OBJECT_TYPE) \ V(EMBEDDED_OBJECT_TYPE) \
V(ENUM_CACHE_TYPE) \ V(ENUM_CACHE_TYPE) \
V(ENUM_INDICES_CACHE_TYPE) \ V(ENUM_INDICES_CACHE_TYPE) \
V(FEEDBACK_METADATA_TYPE) \ V(FEEDBACK_METADATA_TYPE) \
V(FEEDBACK_VECTOR_ENTRY_TYPE) \ V(FEEDBACK_VECTOR_ENTRY_TYPE) \
V(FUNCTION_CONTEXT_TYPE) \ V(FEEDBACK_VECTOR_HEADER_TYPE) \
V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE) \ V(FEEDBACK_VECTOR_SLOT_CALL_TYPE) \
V(GLOBAL_ELEMENTS_TYPE) \ V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE) \
V(GLOBAL_PROPERTIES_TYPE) \ V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE) \
V(JS_ARRAY_BOILERPLATE_TYPE) \ V(FEEDBACK_VECTOR_SLOT_LOAD_TYPE) \
V(JS_COLLETION_TABLE_TYPE) \ V(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE) \
V(JS_OBJECT_BOILERPLATE_TYPE) \ V(FEEDBACK_VECTOR_SLOT_OTHER_TYPE) \
V(NATIVE_CONTEXT_TYPE) \ V(FEEDBACK_VECTOR_SLOT_STORE_TYPE) \
V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE) \ V(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE) \
V(NUMBER_STRING_CACHE_TYPE) \ V(FUNCTION_CONTEXT_TYPE) \
V(OBJECT_PROPERTY_DICTIONARY_TYPE) \ V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE) \
V(OBJECT_TO_CODE_TYPE) \ V(GLOBAL_ELEMENTS_TYPE) \
V(OPTIMIZED_CODE_LITERALS_TYPE) \ V(GLOBAL_PROPERTIES_TYPE) \
V(OTHER_CONTEXT_TYPE) \ V(JS_ARRAY_BOILERPLATE_TYPE) \
V(PROTOTYPE_USERS_TYPE) \ V(JS_COLLETION_TABLE_TYPE) \
V(REGEXP_MULTIPLE_CACHE_TYPE) \ V(JS_OBJECT_BOILERPLATE_TYPE) \
V(RETAINED_MAPS_TYPE) \ V(NATIVE_CONTEXT_TYPE) \
V(SCOPE_INFO_TYPE) \ V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE) \
V(SCRIPT_LIST_TYPE) \ V(NUMBER_STRING_CACHE_TYPE) \
V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE) \ V(OBJECT_PROPERTY_DICTIONARY_TYPE) \
V(SERIALIZED_OBJECTS_TYPE) \ V(OBJECT_TO_CODE_TYPE) \
V(SINGLE_CHARACTER_STRING_CACHE_TYPE) \ V(OPTIMIZED_CODE_LITERALS_TYPE) \
V(STRING_SPLIT_CACHE_TYPE) \ V(OTHER_CONTEXT_TYPE) \
V(STRING_TABLE_TYPE) \ V(PROTOTYPE_USERS_TYPE) \
V(UNCOMPILED_JS_FUNCTION_TYPE) \ V(REGEXP_MULTIPLE_CACHE_TYPE) \
V(UNCOMPILED_SHARED_FUNCTION_INFO_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) V(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE)
namespace v8 { namespace v8 {
......
...@@ -144,7 +144,16 @@ const CATEGORIES = new Map([ ...@@ -144,7 +144,16 @@ const CATEGORIES = new Map([
'DEOPTIMIZATION_DATA_TYPE', 'DEOPTIMIZATION_DATA_TYPE',
'EMBEDDED_OBJECT_TYPE', 'EMBEDDED_OBJECT_TYPE',
'FEEDBACK_METADATA_TYPE', 'FEEDBACK_METADATA_TYPE',
'FEEDBACK_VECTOR_HEADER_TYPE',
'FEEDBACK_VECTOR_ENTRY_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', 'FEEDBACK_VECTOR_TYPE',
'LOAD_HANDLER_TYPE', 'LOAD_HANDLER_TYPE',
'NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE', 'NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE',
......
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