Version 3.17.11
Added a version of the v8::HandleScope constructor with an v8::Isolate parameter and made AdjustAmountOfExternalAllocatedMemory an instance method of v8::Isolate. (issue 2487)
Fixed two register allocator bugs (off-by-one error/failure propagation). (issue 2576)
Fixed huge heap snapshot when a heavily shared context has many variables. (Chromium issue 145687)
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@13956 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 5f46678..cdd5a07 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -174,6 +174,7 @@
case kHeapNumber: return "/number/";
case kNative: return "/native/";
case kSynthetic: return "/synthetic/";
+ case kContext: return "/context/";
default: return "???";
}
}
@@ -826,7 +827,7 @@
} else if (object->IsNativeContext()) {
return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
} else if (object->IsContext()) {
- return AddEntry(object, HeapEntry::kHidden, "system / Context");
+ return AddEntry(object, HeapEntry::kContext, "system / Context");
} else if (object->IsFixedArray() ||
object->IsFixedDoubleArray() ||
object->IsByteArray() ||
@@ -1097,6 +1098,27 @@
void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
+ if (context == context->declaration_context()) {
+ ScopeInfo* scope_info = context->closure()->shared()->scope_info();
+ // Add context allocated locals.
+ int context_locals = scope_info->ContextLocalCount();
+ for (int i = 0; i < context_locals; ++i) {
+ String* local_name = scope_info->ContextLocalName(i);
+ int idx = Context::MIN_CONTEXT_SLOTS + i;
+ SetContextReference(context, entry, local_name, context->get(idx),
+ Context::OffsetOfElementAt(idx));
+ }
+ if (scope_info->HasFunctionName()) {
+ String* name = scope_info->FunctionName();
+ VariableMode mode;
+ int idx = scope_info->FunctionContextSlotIndex(name, &mode);
+ if (idx >= 0) {
+ SetContextReference(context, entry, name, context->get(idx),
+ Context::OffsetOfElementAt(idx));
+ }
+ }
+ }
+
#define EXTRACT_CONTEXT_FIELD(index, type, name) \
SetInternalReference(context, entry, #name, context->get(Context::index), \
FixedArray::OffsetOfElementAt(Context::index));
@@ -1286,26 +1308,6 @@
SetNativeBindReference(js_obj, entry, reference_name,
bindings->get(i));
}
- } else {
- Context* context = func->context()->declaration_context();
- ScopeInfo* scope_info = context->closure()->shared()->scope_info();
- // Add context allocated locals.
- int context_locals = scope_info->ContextLocalCount();
- for (int i = 0; i < context_locals; ++i) {
- String* local_name = scope_info->ContextLocalName(i);
- int idx = Context::MIN_CONTEXT_SLOTS + i;
- SetClosureReference(js_obj, entry, local_name, context->get(idx));
- }
-
- // Add function variable.
- if (scope_info->HasFunctionName()) {
- String* name = scope_info->FunctionName();
- VariableMode mode;
- int idx = scope_info->FunctionContextSlotIndex(name, &mode);
- if (idx >= 0) {
- SetClosureReference(js_obj, entry, name, context->get(idx));
- }
- }
}
}
@@ -1580,16 +1582,18 @@
}
-void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
+void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
int parent_entry,
String* reference_name,
- Object* child_obj) {
+ Object* child_obj,
+ int field_offset) {
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry != NULL) {
filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
parent_entry,
collection_->names()->GetName(reference_name),
child_entry);
+ IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
}
}
@@ -2576,7 +2580,8 @@
JSON_S("regexp") ","
JSON_S("number") ","
JSON_S("native") ","
- JSON_S("synthetic")) ","
+ JSON_S("synthetic") ","
+ JSON_S("context")) ","
JSON_S("string") ","
JSON_S("number") ","
JSON_S("number") ","