Allow arbitrary names for weak references in heap snapshots.
LOG=N BUG= R=ulan@chromium.org, yurys@chromium.org Review URL: https://codereview.chromium.org/146843003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18846 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
1b30de8b55
commit
89ffd30537
@ -6944,11 +6944,11 @@ Handle<Value> HeapGraphEdge::GetName() const {
|
||||
case i::HeapGraphEdge::kInternal:
|
||||
case i::HeapGraphEdge::kProperty:
|
||||
case i::HeapGraphEdge::kShortcut:
|
||||
case i::HeapGraphEdge::kWeak:
|
||||
return ToApiHandle<String>(
|
||||
isolate->factory()->InternalizeUtf8String(edge->name()));
|
||||
case i::HeapGraphEdge::kElement:
|
||||
case i::HeapGraphEdge::kHidden:
|
||||
case i::HeapGraphEdge::kWeak:
|
||||
return ToApiHandle<Number>(
|
||||
isolate->factory()->NewNumberFromInt(edge->index()));
|
||||
default: UNREACHABLE();
|
||||
|
@ -47,7 +47,8 @@ HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to)
|
||||
ASSERT(type == kContextVariable
|
||||
|| type == kProperty
|
||||
|| 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),
|
||||
to_index_(to),
|
||||
index_(index) {
|
||||
ASSERT(type == kElement || type == kHidden || type == kWeak);
|
||||
ASSERT(type == kElement || type == kHidden);
|
||||
}
|
||||
|
||||
|
||||
@ -150,7 +151,7 @@ void HeapEntry::Print(
|
||||
break;
|
||||
case HeapGraphEdge::kWeak:
|
||||
edge_prefix = "w";
|
||||
OS::SNPrintF(index, "%d", edge.index());
|
||||
edge_name = edge.name();
|
||||
break;
|
||||
default:
|
||||
OS::SNPrintF(index, "!!! unknown edge type: %d ", edge.type());
|
||||
@ -1114,11 +1115,13 @@ void V8HeapExplorer::ExtractJSObjectReferences(
|
||||
SetInternalReference(js_fun, entry,
|
||||
"context", js_fun->context(),
|
||||
JSFunction::kContextOffset);
|
||||
for (int i = JSFunction::kNonWeakFieldsEndOffset;
|
||||
i < JSFunction::kSize;
|
||||
i += kPointerSize) {
|
||||
SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i);
|
||||
}
|
||||
SetWeakReference(js_fun, entry,
|
||||
"next_function_link", js_fun->next_function_link(),
|
||||
JSFunction::kNextFunctionLinkOffset);
|
||||
STATIC_CHECK(JSFunction::kNextFunctionLinkOffset
|
||||
== JSFunction::kNonWeakFieldsEndOffset);
|
||||
STATIC_CHECK(JSFunction::kNextFunctionLinkOffset + kPointerSize
|
||||
== JSFunction::kSize);
|
||||
} else if (obj->IsGlobalObject()) {
|
||||
GlobalObject* global_obj = GlobalObject::cast(obj);
|
||||
SetInternalReference(global_obj, entry,
|
||||
@ -1134,13 +1137,14 @@ void V8HeapExplorer::ExtractJSObjectReferences(
|
||||
JSArrayBufferView* view = JSArrayBufferView::cast(obj);
|
||||
SetInternalReference(view, entry, "buffer", view->buffer(),
|
||||
JSArrayBufferView::kBufferOffset);
|
||||
SetWeakReference(view, entry, 1, view->weak_next(),
|
||||
SetWeakReference(view, entry, "weak_next", view->weak_next(),
|
||||
JSArrayBufferView::kWeakNextOffset);
|
||||
} else if (obj->IsJSArrayBuffer()) {
|
||||
JSArrayBuffer* buffer = JSArrayBuffer::cast(obj);
|
||||
SetWeakReference(buffer, entry, 1, buffer->weak_next(),
|
||||
SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(),
|
||||
JSArrayBuffer::kWeakNextOffset);
|
||||
SetWeakReference(buffer, entry, 2, buffer->weak_first_view(),
|
||||
SetWeakReference(buffer, entry,
|
||||
"weak_first_view", buffer->weak_first_view(),
|
||||
JSArrayBuffer::kWeakFirstViewOffset);
|
||||
}
|
||||
TagObject(js_obj->properties(), "(object properties)");
|
||||
@ -1192,8 +1196,13 @@ void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
|
||||
}
|
||||
|
||||
#define EXTRACT_CONTEXT_FIELD(index, type, name) \
|
||||
SetInternalReference(context, entry, #name, context->get(Context::index), \
|
||||
FixedArray::OffsetOfElementAt(Context::index));
|
||||
if (Context::index < Context::FIRST_WEAK_SLOT) { \
|
||||
SetInternalReference(context, entry, #name, context->get(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(PREVIOUS_INDEX, Context, previous);
|
||||
EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension);
|
||||
@ -1205,13 +1214,16 @@ void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
|
||||
TagObject(context->runtime_context(), "(runtime context)");
|
||||
TagObject(context->embedder_data(), "(context data)");
|
||||
NATIVE_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
|
||||
EXTRACT_CONTEXT_FIELD(OPTIMIZED_FUNCTIONS_LIST, unused,
|
||||
optimized_functions_list);
|
||||
EXTRACT_CONTEXT_FIELD(OPTIMIZED_CODE_LIST, unused, optimized_code_list);
|
||||
EXTRACT_CONTEXT_FIELD(DEOPTIMIZED_CODE_LIST, unused, deoptimized_code_list);
|
||||
EXTRACT_CONTEXT_FIELD(NEXT_CONTEXT_LINK, unused, next_context_link);
|
||||
#undef EXTRACT_CONTEXT_FIELD
|
||||
for (int i = Context::FIRST_WEAK_SLOT;
|
||||
i < Context::NATIVE_CONTEXT_SLOTS;
|
||||
++i) {
|
||||
SetWeakReference(context, entry, i, context->get(i),
|
||||
FixedArray::OffsetOfElementAt(i));
|
||||
}
|
||||
STATIC_CHECK(Context::OPTIMIZED_FUNCTIONS_LIST == Context::FIRST_WEAK_SLOT);
|
||||
STATIC_CHECK(Context::NEXT_CONTEXT_LINK + 1
|
||||
== Context::NATIVE_CONTEXT_SLOTS);
|
||||
STATIC_CHECK(Context::FIRST_WEAK_SLOT + 5 == Context::NATIVE_CONTEXT_SLOTS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1305,7 +1317,7 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
|
||||
"optimized_code_map", shared->optimized_code_map(),
|
||||
SharedFunctionInfo::kOptimizedCodeMapOffset);
|
||||
SetWeakReference(obj, entry,
|
||||
1, shared->initial_map(),
|
||||
"initial_map", shared->initial_map(),
|
||||
SharedFunctionInfo::kInitialMapOffset);
|
||||
}
|
||||
|
||||
@ -1835,17 +1847,17 @@ void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
|
||||
|
||||
void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
|
||||
int parent_entry,
|
||||
int index,
|
||||
const char* reference_name,
|
||||
Object* child_obj,
|
||||
int field_offset) {
|
||||
ASSERT(parent_entry == GetEntry(parent_obj)->index());
|
||||
HeapEntry* child_entry = GetEntry(child_obj);
|
||||
if (child_entry == NULL) return;
|
||||
if (IsEssentialObject(child_obj)) {
|
||||
filler_->SetIndexedReference(HeapGraphEdge::kWeak,
|
||||
parent_entry,
|
||||
index,
|
||||
child_entry);
|
||||
filler_->SetNamedReference(HeapGraphEdge::kWeak,
|
||||
parent_entry,
|
||||
reference_name,
|
||||
child_entry);
|
||||
}
|
||||
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
||||
}
|
||||
@ -1917,10 +1929,17 @@ void V8HeapExplorer::SetGcSubrootReference(
|
||||
name,
|
||||
child_entry);
|
||||
} else {
|
||||
filler_->SetIndexedAutoIndexReference(
|
||||
is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kElement,
|
||||
snapshot_->gc_subroot(tag)->index(),
|
||||
child_entry);
|
||||
if (is_weak) {
|
||||
filler_->SetNamedAutoIndexReference(
|
||||
HeapGraphEdge::kWeak,
|
||||
snapshot_->gc_subroot(tag)->index(),
|
||||
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.
|
||||
@ -2654,7 +2673,6 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
|
||||
EmbeddedVector<char, kBufferSize> buffer;
|
||||
int edge_name_or_index = edge->type() == HeapGraphEdge::kElement
|
||||
|| edge->type() == HeapGraphEdge::kHidden
|
||||
|| edge->type() == HeapGraphEdge::kWeak
|
||||
? edge->index() : GetStringId(edge->name());
|
||||
int buffer_pos = 0;
|
||||
if (!first_edge) {
|
||||
|
@ -57,14 +57,15 @@ class HeapGraphEdge BASE_EMBEDDED {
|
||||
|
||||
Type type() const { return static_cast<Type>(type_); }
|
||||
int index() const {
|
||||
ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak);
|
||||
ASSERT(type_ == kElement || type_ == kHidden);
|
||||
return index_;
|
||||
}
|
||||
const char* name() const {
|
||||
ASSERT(type_ == kContextVariable
|
||||
|| type_ == kProperty
|
||||
|| type_ == kInternal
|
||||
|| type_ == kShortcut);
|
||||
|| type_ == kShortcut
|
||||
|| type_ == kWeak);
|
||||
return name_;
|
||||
}
|
||||
INLINE(HeapEntry* from() const);
|
||||
@ -448,7 +449,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
|
||||
Object* child);
|
||||
void SetWeakReference(HeapObject* parent_obj,
|
||||
int parent,
|
||||
int index,
|
||||
const char* reference_name,
|
||||
Object* child_obj,
|
||||
int field_offset);
|
||||
void SetPropertyReference(HeapObject* parent_obj,
|
||||
|
@ -2337,6 +2337,6 @@ TEST(ArrayBufferAndArrayBufferView) {
|
||||
GetProperty(arr1_obj, v8::HeapGraphEdge::kInternal, "buffer");
|
||||
CHECK_NE(NULL, arr1_buffer);
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user