Allow arbitrary names for weak references in heap snapshots.

LOG=N
R=ulan@chromium.org, yurys@chromium.org

Review URL: https://codereview.chromium.org/145353003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18838 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
alph@chromium.org 2014-01-24 17:18:34 +00:00
parent 1a67b7f86a
commit f4a470d5bb
4 changed files with 53 additions and 35 deletions

View File

@ -6944,11 +6944,11 @@ Handle<Value> HeapGraphEdge::GetName() const {
case i::HeapGraphEdge::kInternal: case i::HeapGraphEdge::kInternal:
case i::HeapGraphEdge::kProperty: case i::HeapGraphEdge::kProperty:
case i::HeapGraphEdge::kShortcut: case i::HeapGraphEdge::kShortcut:
case i::HeapGraphEdge::kWeak:
return ToApiHandle<String>( return ToApiHandle<String>(
isolate->factory()->InternalizeUtf8String(edge->name())); isolate->factory()->InternalizeUtf8String(edge->name()));
case i::HeapGraphEdge::kElement: case i::HeapGraphEdge::kElement:
case i::HeapGraphEdge::kHidden: case i::HeapGraphEdge::kHidden:
case i::HeapGraphEdge::kWeak:
return ToApiHandle<Number>( return ToApiHandle<Number>(
isolate->factory()->NewNumberFromInt(edge->index())); isolate->factory()->NewNumberFromInt(edge->index()));
default: UNREACHABLE(); default: UNREACHABLE();

View File

@ -47,7 +47,8 @@ HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to)
ASSERT(type == kContextVariable ASSERT(type == kContextVariable
|| type == kProperty || type == kProperty
|| type == kInternal || type == kInternal
|| type == kShortcut); || type == kShortcut
|| type == kWeak);
} }
@ -56,7 +57,7 @@ HeapGraphEdge::HeapGraphEdge(Type type, int index, int from, int to)
from_index_(from), from_index_(from),
to_index_(to), to_index_(to),
index_(index) { index_(index) {
ASSERT(type == kElement || type == kHidden || type == kWeak); ASSERT(type == kElement || type == kHidden);
} }
@ -150,7 +151,7 @@ void HeapEntry::Print(
break; break;
case HeapGraphEdge::kWeak: case HeapGraphEdge::kWeak:
edge_prefix = "w"; edge_prefix = "w";
OS::SNPrintF(index, "%d", edge.index()); edge_name = edge.name();
break; break;
default: default:
OS::SNPrintF(index, "!!! unknown edge type: %d ", edge.type()); OS::SNPrintF(index, "!!! unknown edge type: %d ", edge.type());
@ -1114,11 +1115,13 @@ void V8HeapExplorer::ExtractJSObjectReferences(
SetInternalReference(js_fun, entry, SetInternalReference(js_fun, entry,
"context", js_fun->context(), "context", js_fun->context(),
JSFunction::kContextOffset); JSFunction::kContextOffset);
for (int i = JSFunction::kNonWeakFieldsEndOffset; SetWeakReference(js_fun, entry,
i < JSFunction::kSize; "next_function_link", js_fun->next_function_link(),
i += kPointerSize) { JSFunction::kNextFunctionLinkOffset);
SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i); STATIC_CHECK(JSFunction::kNextFunctionLinkOffset
} == JSFunction::kNonWeakFieldsEndOffset);
STATIC_CHECK(JSFunction::kNextFunctionLinkOffset + kPointerSize
== JSFunction::kSize);
} else if (obj->IsGlobalObject()) { } else if (obj->IsGlobalObject()) {
GlobalObject* global_obj = GlobalObject::cast(obj); GlobalObject* global_obj = GlobalObject::cast(obj);
SetInternalReference(global_obj, entry, SetInternalReference(global_obj, entry,
@ -1134,13 +1137,14 @@ void V8HeapExplorer::ExtractJSObjectReferences(
JSArrayBufferView* view = JSArrayBufferView::cast(obj); JSArrayBufferView* view = JSArrayBufferView::cast(obj);
SetInternalReference(view, entry, "buffer", view->buffer(), SetInternalReference(view, entry, "buffer", view->buffer(),
JSArrayBufferView::kBufferOffset); JSArrayBufferView::kBufferOffset);
SetWeakReference(view, entry, 1, view->weak_next(), SetWeakReference(view, entry, "weak_next", view->weak_next(),
JSArrayBufferView::kWeakNextOffset); JSArrayBufferView::kWeakNextOffset);
} else if (obj->IsJSArrayBuffer()) { } else if (obj->IsJSArrayBuffer()) {
JSArrayBuffer* buffer = JSArrayBuffer::cast(obj); JSArrayBuffer* buffer = JSArrayBuffer::cast(obj);
SetWeakReference(buffer, entry, 1, buffer->weak_next(), SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(),
JSArrayBuffer::kWeakNextOffset); JSArrayBuffer::kWeakNextOffset);
SetWeakReference(buffer, entry, 2, buffer->weak_first_view(), SetWeakReference(buffer, entry,
"weak_first_view", buffer->weak_first_view(),
JSArrayBuffer::kWeakFirstViewOffset); JSArrayBuffer::kWeakFirstViewOffset);
} }
TagObject(js_obj->properties(), "(object properties)"); TagObject(js_obj->properties(), "(object properties)");
@ -1192,8 +1196,13 @@ void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
} }
#define EXTRACT_CONTEXT_FIELD(index, type, name) \ #define EXTRACT_CONTEXT_FIELD(index, type, name) \
if (Context::index < Context::FIRST_WEAK_SLOT) { \
SetInternalReference(context, entry, #name, context->get(Context::index), \ SetInternalReference(context, entry, #name, context->get(Context::index), \
FixedArray::OffsetOfElementAt(Context::index)); FixedArray::OffsetOfElementAt(Context::index)); \
} else { \
SetWeakReference(context, entry, #name, context->get(Context::index), \
FixedArray::OffsetOfElementAt(Context::index)); \
}
EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure); EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure);
EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous); EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous);
EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension); EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension);
@ -1205,13 +1214,15 @@ void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
TagObject(context->runtime_context(), "(runtime context)"); TagObject(context->runtime_context(), "(runtime context)");
TagObject(context->embedder_data(), "(context data)"); TagObject(context->embedder_data(), "(context data)");
NATIVE_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD); NATIVE_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
EXTRACT_CONTEXT_FIELD(OPTIMIZED_FUNCTIONS_LIST, , optimized_functions_list);
EXTRACT_CONTEXT_FIELD(OPTIMIZED_CODE_LIST, , optimized_code_list);
EXTRACT_CONTEXT_FIELD(DEOPTIMIZED_CODE_LIST, , deoptimized_code_list);
EXTRACT_CONTEXT_FIELD(NEXT_CONTEXT_LINK, , next_context_link);
#undef EXTRACT_CONTEXT_FIELD #undef EXTRACT_CONTEXT_FIELD
for (int i = Context::FIRST_WEAK_SLOT; STATIC_CHECK(Context::OPTIMIZED_FUNCTIONS_LIST == Context::FIRST_WEAK_SLOT);
i < Context::NATIVE_CONTEXT_SLOTS; STATIC_CHECK(Context::NEXT_CONTEXT_LINK + 1
++i) { == Context::NATIVE_CONTEXT_SLOTS);
SetWeakReference(context, entry, i, context->get(i), STATIC_CHECK(Context::FIRST_WEAK_SLOT + 5 == Context::NATIVE_CONTEXT_SLOTS);
FixedArray::OffsetOfElementAt(i));
}
} }
} }
@ -1305,7 +1316,7 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
"optimized_code_map", shared->optimized_code_map(), "optimized_code_map", shared->optimized_code_map(),
SharedFunctionInfo::kOptimizedCodeMapOffset); SharedFunctionInfo::kOptimizedCodeMapOffset);
SetWeakReference(obj, entry, SetWeakReference(obj, entry,
1, shared->initial_map(), "initial_map", shared->initial_map(),
SharedFunctionInfo::kInitialMapOffset); SharedFunctionInfo::kInitialMapOffset);
} }
@ -1835,16 +1846,16 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
int parent_entry, int parent_entry,
int index, const char* reference_name,
Object* child_obj, Object* child_obj,
int field_offset) { int field_offset) {
ASSERT(parent_entry == GetEntry(parent_obj)->index()); ASSERT(parent_entry == GetEntry(parent_obj)->index());
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == NULL) return; if (child_entry == NULL) return;
if (IsEssentialObject(child_obj)) { if (IsEssentialObject(child_obj)) {
filler_->SetIndexedReference(HeapGraphEdge::kWeak, filler_->SetNamedReference(HeapGraphEdge::kWeak,
parent_entry, parent_entry,
index, reference_name,
child_entry); child_entry);
} }
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
@ -1917,10 +1928,17 @@ void V8HeapExplorer::SetGcSubrootReference(
name, name,
child_entry); child_entry);
} else { } else {
filler_->SetIndexedAutoIndexReference( if (is_weak) {
is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement, filler_->SetNamedAutoIndexReference(
HeapGraphEdge::kWeak,
snapshot_->gc_subroot(tag)->index(), snapshot_->gc_subroot(tag)->index(),
child_entry); child_entry);
} else {
filler_->SetIndexedAutoIndexReference(
HeapGraphEdge::kElement,
snapshot_->gc_subroot(tag)->index(),
child_entry);
}
} }
// Add a shortcut to JS global object reference at snapshot root. // Add a shortcut to JS global object reference at snapshot root.
@ -2654,7 +2672,6 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
EmbeddedVector<char, kBufferSize> buffer; EmbeddedVector<char, kBufferSize> buffer;
int edge_name_or_index = edge->type() == HeapGraphEdge::kElement int edge_name_or_index = edge->type() == HeapGraphEdge::kElement
|| edge->type() == HeapGraphEdge::kHidden || edge->type() == HeapGraphEdge::kHidden
|| edge->type() == HeapGraphEdge::kWeak
? edge->index() : GetStringId(edge->name()); ? edge->index() : GetStringId(edge->name());
int buffer_pos = 0; int buffer_pos = 0;
if (!first_edge) { if (!first_edge) {

View File

@ -57,14 +57,15 @@ class HeapGraphEdge BASE_EMBEDDED {
Type type() const { return static_cast<Type>(type_); } Type type() const { return static_cast<Type>(type_); }
int index() const { int index() const {
ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak); ASSERT(type_ == kElement || type_ == kHidden);
return index_; return index_;
} }
const char* name() const { const char* name() const {
ASSERT(type_ == kContextVariable ASSERT(type_ == kContextVariable
|| type_ == kProperty || type_ == kProperty
|| type_ == kInternal || type_ == kInternal
|| type_ == kShortcut); || type_ == kShortcut
|| type_ == kWeak);
return name_; return name_;
} }
INLINE(HeapEntry* from() const); INLINE(HeapEntry* from() const);
@ -448,7 +449,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
Object* child); Object* child);
void SetWeakReference(HeapObject* parent_obj, void SetWeakReference(HeapObject* parent_obj,
int parent, int parent,
int index, const char* reference_name,
Object* child_obj, Object* child_obj,
int field_offset); int field_offset);
void SetPropertyReference(HeapObject* parent_obj, void SetPropertyReference(HeapObject* parent_obj,

View File

@ -2337,6 +2337,6 @@ TEST(ArrayBufferAndArrayBufferView) {
GetProperty(arr1_obj, v8::HeapGraphEdge::kInternal, "buffer"); GetProperty(arr1_obj, v8::HeapGraphEdge::kInternal, "buffer");
CHECK_NE(NULL, arr1_buffer); CHECK_NE(NULL, arr1_buffer);
const v8::HeapGraphNode* first_view = const v8::HeapGraphNode* first_view =
GetProperty(arr1_buffer, v8::HeapGraphEdge::kWeak, "2"); GetProperty(arr1_buffer, v8::HeapGraphEdge::kWeak, "weak_first_view");
CHECK_NE(NULL, first_view); CHECK_NE(NULL, first_view);
} }