Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/profiler/heap-snapshot-generator.cc')
-rw-r--r--deps/v8/src/profiler/heap-snapshot-generator.cc133
1 files changed, 109 insertions, 24 deletions
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc
index b51ea0de7e4..96ac785273c 100644
--- a/deps/v8/src/profiler/heap-snapshot-generator.cc
+++ b/deps/v8/src/profiler/heap-snapshot-generator.cc
@@ -6,7 +6,7 @@
#include <utility>
-#include "src/api.h"
+#include "src/api-inl.h"
#include "src/code-stubs.h"
#include "src/conversions.h"
#include "src/debug/debug.h"
@@ -16,7 +16,10 @@
#include "src/objects-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/hash-table-inl.h"
+#include "src/objects/js-array-buffer-inl.h"
+#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
+#include "src/objects/js-generator-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/literal-objects-inl.h"
@@ -246,6 +249,9 @@ HeapEntry* HeapSnapshot::AddGcSubrootEntry(Root root, SnapshotObjectId id) {
return entry;
}
+void HeapSnapshot::AddLocation(int entry, int scriptId, int line, int col) {
+ locations_.emplace_back(entry, scriptId, line, col);
+}
HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
const char* name,
@@ -608,6 +614,33 @@ HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) {
return AddEntry(reinterpret_cast<HeapObject*>(ptr));
}
+void V8HeapExplorer::ExtractLocation(int entry, HeapObject* object) {
+ if (object->IsJSFunction()) {
+ JSFunction* func = JSFunction::cast(object);
+ ExtractLocationForJSFunction(entry, func);
+
+ } else if (object->IsJSGeneratorObject()) {
+ JSGeneratorObject* gen = JSGeneratorObject::cast(object);
+ ExtractLocationForJSFunction(entry, gen->function());
+
+ } else if (object->IsJSObject()) {
+ JSObject* obj = JSObject::cast(object);
+ JSFunction* maybe_constructor = GetConstructor(obj);
+
+ if (maybe_constructor)
+ ExtractLocationForJSFunction(entry, maybe_constructor);
+ }
+}
+
+void V8HeapExplorer::ExtractLocationForJSFunction(int entry, JSFunction* func) {
+ if (!func->shared()->script()->IsScript()) return;
+ Script* script = Script::cast(func->shared()->script());
+ int scriptId = script->id();
+ int start = func->shared()->StartPosition();
+ int line = script->GetLineNumber(start);
+ int col = script->GetColumnNumber(start);
+ snapshot_->AddLocation(entry, scriptId, line, col);
+}
HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
if (object->IsJSFunction()) {
@@ -854,6 +887,8 @@ void V8HeapExplorer::ExtractReferences(int entry, HeapObject* obj) {
ExtractJSCollectionReferences(entry, JSMap::cast(obj));
} else if (obj->IsJSPromise()) {
ExtractJSPromiseReferences(entry, JSPromise::cast(obj));
+ } else if (obj->IsJSGeneratorObject()) {
+ ExtractJSGeneratorObjectReferences(entry, JSGeneratorObject::cast(obj));
}
ExtractJSObjectReferences(entry, JSObject::cast(obj));
} else if (obj->IsString()) {
@@ -876,8 +911,6 @@ void V8HeapExplorer::ExtractReferences(int entry, HeapObject* obj) {
ExtractCellReferences(entry, Cell::cast(obj));
} else if (obj->IsFeedbackCell()) {
ExtractFeedbackCellReferences(entry, FeedbackCell::cast(obj));
- } else if (obj->IsWeakCell()) {
- ExtractWeakCellReferences(entry, WeakCell::cast(obj));
} else if (obj->IsPropertyCell()) {
ExtractPropertyCellReferences(entry, PropertyCell::cast(obj));
} else if (obj->IsAllocationSite()) {
@@ -1119,8 +1152,6 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
Map::kTransitionsOrPrototypeInfoOffset);
} else if (maybe_raw_transitions_or_prototype_info->ToStrongHeapObject(
&raw_transitions_or_prototype_info)) {
- DCHECK(!raw_transitions_or_prototype_info->IsWeakCell());
-
if (raw_transitions_or_prototype_info->IsTransitionArray()) {
TransitionArray* transitions =
TransitionArray::cast(raw_transitions_or_prototype_info);
@@ -1172,9 +1203,6 @@ void V8HeapExplorer::ExtractMapReferences(int entry, Map* map) {
TagObject(map->dependent_code(), "(dependent code)");
SetInternalReference(map, entry, "dependent_code", map->dependent_code(),
Map::kDependentCodeOffset);
- TagObject(map->weak_cell_cache(), "(weak cell)");
- SetInternalReference(map, entry, "weak_cell_cache", map->weak_cell_cache(),
- Map::kWeakCellCacheOffset);
}
@@ -1198,17 +1226,13 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
SetInternalReference(obj, entry, "name_or_scope_info",
shared->name_or_scope_info(),
SharedFunctionInfo::kNameOrScopeInfoOffset);
- SetInternalReference(obj, entry,
- "script", shared->script(),
- SharedFunctionInfo::kScriptOffset);
+ SetInternalReference(obj, entry, "script_or_debug_info",
+ shared->script_or_debug_info(),
+ SharedFunctionInfo::kScriptOrDebugInfoOffset);
SetInternalReference(obj, entry,
"function_data", shared->function_data(),
SharedFunctionInfo::kFunctionDataOffset);
SetInternalReference(
- obj, entry, "function_identifier_or_debug_info",
- shared->function_identifier_or_debug_info(),
- SharedFunctionInfo::kFunctionIdentifierOrDebugInfoOffset);
- SetInternalReference(
obj, entry, "raw_outer_scope_info_or_feedback_metadata",
shared->raw_outer_scope_info_or_feedback_metadata(),
SharedFunctionInfo::kOuterScopeInfoOrFeedbackMetadataOffset);
@@ -1294,12 +1318,6 @@ void V8HeapExplorer::ExtractFeedbackCellReferences(
FeedbackCell::kValueOffset);
}
-void V8HeapExplorer::ExtractWeakCellReferences(int entry, WeakCell* weak_cell) {
- TagObject(weak_cell, "(weak cell)");
- SetWeakReference(weak_cell, entry, "value", weak_cell->value(),
- WeakCell::kValueOffset);
-}
-
void V8HeapExplorer::ExtractPropertyCellReferences(int entry,
PropertyCell* cell) {
SetInternalReference(cell, entry, "value", cell->value(),
@@ -1363,6 +1381,19 @@ void V8HeapExplorer::ExtractJSPromiseReferences(int entry, JSPromise* promise) {
JSPromise::kReactionsOrResultOffset);
}
+void V8HeapExplorer::ExtractJSGeneratorObjectReferences(
+ int entry, JSGeneratorObject* generator) {
+ SetInternalReference(generator, entry, "function", generator->function(),
+ JSGeneratorObject::kFunctionOffset);
+ SetInternalReference(generator, entry, "context", generator->context(),
+ JSGeneratorObject::kContextOffset);
+ SetInternalReference(generator, entry, "receiver", generator->receiver(),
+ JSGeneratorObject::kReceiverOffset);
+ SetInternalReference(generator, entry, "parameters_and_registers",
+ generator->parameters_and_registers(),
+ JSGeneratorObject::kParametersAndRegistersOffset);
+}
+
void V8HeapExplorer::ExtractFixedArrayReferences(int entry, FixedArray* array) {
for (int i = 0, l = array->length(); i < l; ++i) {
DCHECK(!HasWeakHeapObjectTag(array->get(i)));
@@ -1513,6 +1544,17 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj, int entry) {
}
}
+JSFunction* V8HeapExplorer::GetConstructor(JSReceiver* receiver) {
+ Isolate* isolate = receiver->GetIsolate();
+ DisallowHeapAllocation no_gc;
+ HandleScope scope(isolate);
+ MaybeHandle<JSFunction> maybe_constructor =
+ JSReceiver::GetConstructor(handle(receiver, isolate));
+
+ if (maybe_constructor.is_null()) return nullptr;
+
+ return *maybe_constructor.ToHandleChecked();
+}
String* V8HeapExplorer::GetConstructorName(JSObject* object) {
Isolate* isolate = object->GetIsolate();
@@ -1602,6 +1644,9 @@ bool V8HeapExplorer::IterateAndExtractReferences(SnapshotFiller* filler) {
DCHECK(!visited_fields_[i]);
}
+ // Extract location for specific object types
+ ExtractLocation(entry, obj);
+
if (!progress_->ProgressReport(false)) interrupted = true;
}
@@ -2630,6 +2675,11 @@ void HeapSnapshotJSONSerializer::SerializeImpl() {
if (writer_->aborted()) return;
writer_->AddString("],\n");
+ writer_->AddString("\"locations\":[");
+ SerializeLocations();
+ if (writer_->aborted()) return;
+ writer_->AddString("],\n");
+
writer_->AddString("\"strings\":[");
SerializeStrings();
if (writer_->aborted()) return;
@@ -2709,7 +2759,7 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
buffer[buffer_pos++] = ',';
buffer_pos = utoa(edge_name_or_index, buffer, buffer_pos);
buffer[buffer_pos++] = ',';
- buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos);
+ buffer_pos = utoa(to_node_index(edge->to()), buffer, buffer_pos);
buffer[buffer_pos++] = '\n';
buffer[buffer_pos++] = '\0';
writer_->AddString(buffer.start());
@@ -2734,7 +2784,7 @@ void HeapSnapshotJSONSerializer::SerializeNode(const HeapEntry* entry) {
+ 6 + 1 + 1;
EmbeddedVector<char, kBufferSize> buffer;
int buffer_pos = 0;
- if (entry_index(entry) != 0) {
+ if (to_node_index(entry) != 0) {
buffer[buffer_pos++] = ',';
}
buffer_pos = utoa(entry->type(), buffer, buffer_pos);
@@ -2767,6 +2817,8 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() {
writer_->AddString("\"meta\":");
// The object describing node serialization layout.
// We use a set of macros to improve readability.
+
+// clang-format off
#define JSON_A(s) "[" s "]"
#define JSON_O(s) "{" s "}"
#define JSON_S(s) "\"" s "\""
@@ -2830,7 +2882,13 @@ void HeapSnapshotJSONSerializer::SerializeSnapshot() {
JSON_S("children")) ","
JSON_S("sample_fields") ":" JSON_A(
JSON_S("timestamp_us") ","
- JSON_S("last_assigned_id"))));
+ JSON_S("last_assigned_id")) ","
+ JSON_S("location_fields") ":" JSON_A(
+ JSON_S("object_index") ","
+ JSON_S("script_id") ","
+ JSON_S("line") ","
+ JSON_S("column"))));
+// clang-format on
#undef JSON_S
#undef JSON_O
#undef JSON_A
@@ -3037,6 +3095,33 @@ void HeapSnapshotJSONSerializer::SerializeStrings() {
}
}
+void HeapSnapshotJSONSerializer::SerializeLocation(
+ const SourceLocation& location) {
+ // The buffer needs space for 4 unsigned ints, 3 commas, \n and \0
+ static const int kBufferSize =
+ MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 4 + 3 + 2;
+ EmbeddedVector<char, kBufferSize> buffer;
+ int buffer_pos = 0;
+ buffer_pos = utoa(to_node_index(location.entry_index), buffer, buffer_pos);
+ buffer[buffer_pos++] = ',';
+ buffer_pos = utoa(location.scriptId, buffer, buffer_pos);
+ buffer[buffer_pos++] = ',';
+ buffer_pos = utoa(location.line, buffer, buffer_pos);
+ buffer[buffer_pos++] = ',';
+ buffer_pos = utoa(location.col, buffer, buffer_pos);
+ buffer[buffer_pos++] = '\n';
+ buffer[buffer_pos++] = '\0';
+ writer_->AddString(buffer.start());
+}
+
+void HeapSnapshotJSONSerializer::SerializeLocations() {
+ const std::vector<SourceLocation>& locations = snapshot_->locations();
+ for (size_t i = 0; i < locations.size(); i++) {
+ if (i > 0) writer_->AddCharacter(',');
+ SerializeLocation(locations[i]);
+ if (writer_->aborted()) return;
+ }
+}
} // namespace internal
} // namespace v8