Skip to content

Commit

Permalink
src: replace heap_utils.createHeapSnapshot with v8.getHeapSnapshot
Browse files Browse the repository at this point in the history
Remove the internal testing utility and use the public API instead.

PR-URL: #26671
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information
joyeecheung committed Mar 18, 2019
1 parent 6d09012 commit ebcd502
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 141 deletions.
89 changes: 0 additions & 89 deletions lib/internal/test/heap.js

This file was deleted.

1 change: 0 additions & 1 deletion node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@
'lib/internal/repl/utils.js',
'lib/internal/socket_list.js',
'lib/internal/test/binding.js',
'lib/internal/test/heap.js',
'lib/internal/timers.js',
'lib/internal/tls.js',
'lib/internal/trace_events_async_hooks.js',
Expand Down
48 changes: 0 additions & 48 deletions src/heap_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,40 +200,6 @@ void BuildEmbedderGraph(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(ret);
}


class BufferOutputStream : public v8::OutputStream {
public:
BufferOutputStream() : buffer_(new JSString()) {}

void EndOfStream() override {}
int GetChunkSize() override { return 1024 * 1024; }
WriteResult WriteAsciiChunk(char* data, int size) override {
buffer_->Append(data, size);
return kContinue;
}

Local<String> ToString(Isolate* isolate) {
return String::NewExternalOneByte(isolate,
buffer_.release()).ToLocalChecked();
}

private:
class JSString : public String::ExternalOneByteStringResource {
public:
void Append(char* data, size_t count) {
store_.append(data, count);
}

const char* data() const override { return store_.data(); }
size_t length() const override { return store_.size(); }

private:
std::string store_;
};

std::unique_ptr<JSString> buffer_;
};

namespace {
class FileOutputStream : public v8::OutputStream {
public:
Expand Down Expand Up @@ -370,17 +336,6 @@ inline bool WriteSnapshot(Isolate* isolate, const char* filename) {

} // namespace

void CreateHeapSnapshot(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
BufferOutputStream out;
TakeSnapshot(isolate, &out);
Local<Value> ret;
if (JSON::Parse(isolate->GetCurrentContext(),
out.ToString(isolate)).ToLocal(&ret)) {
args.GetReturnValue().Set(ret);
}
}

void CreateHeapSnapshotStream(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HandleScope scope(env->isolate());
Expand Down Expand Up @@ -430,9 +385,6 @@ void Initialize(Local<Object> target,
env->SetMethodNoSideEffect(target,
"buildEmbedderGraph",
BuildEmbedderGraph);
env->SetMethodNoSideEffect(target,
"createHeapSnapshot",
CreateHeapSnapshot);
env->SetMethodNoSideEffect(target,
"triggerHeapSnapshot",
TriggerHeapSnapshot);
Expand Down
80 changes: 77 additions & 3 deletions test/common/heap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,88 @@
const assert = require('assert');
const util = require('util');

let internalTestHeap;
let internalBinding;
try {
internalTestHeap = require('internal/test/heap');
internalBinding = require('internal/test/binding').internalBinding;
} catch (e) {
console.log('using `test/common/heap.js` requires `--expose-internals`');
throw e;
}
const { createJSHeapSnapshot, buildEmbedderGraph } = internalTestHeap;

const { buildEmbedderGraph } = internalBinding('heap_utils');
const { getHeapSnapshot } = require('v8');

function createJSHeapSnapshot() {
const stream = getHeapSnapshot();
stream.pause();
const dump = JSON.parse(stream.read());
const meta = dump.snapshot.meta;

const nodes =
readHeapInfo(dump.nodes, meta.node_fields, meta.node_types, dump.strings);
const edges =
readHeapInfo(dump.edges, meta.edge_fields, meta.edge_types, dump.strings);

for (const node of nodes) {
node.incomingEdges = [];
node.outgoingEdges = [];
}

let fromNodeIndex = 0;
let edgeIndex = 0;
for (const { type, name_or_index, to_node } of edges) {
while (edgeIndex === nodes[fromNodeIndex].edge_count) {
edgeIndex = 0;
fromNodeIndex++;
}
const toNode = nodes[to_node / meta.node_fields.length];
const fromNode = nodes[fromNodeIndex];
const edge = {
type,
to: toNode,
from: fromNode,
name: typeof name_or_index === 'string' ? name_or_index : null
};
toNode.incomingEdges.push(edge);
fromNode.outgoingEdges.push(edge);
edgeIndex++;
}

for (const node of nodes) {
assert.strictEqual(node.edge_count, node.outgoingEdges.length,
`${node.edge_count} !== ${node.outgoingEdges.length}`);
}
return nodes;
}

function readHeapInfo(raw, fields, types, strings) {
const items = [];

for (let i = 0; i < raw.length; i += fields.length) {
const item = {};
for (let j = 0; j < fields.length; j++) {
const name = fields[j];
let type = types[j];
if (Array.isArray(type)) {
item[name] = type[raw[i + j]];
} else if (name === 'name_or_index') { // type === 'string_or_number'
if (item.type === 'element' || item.type === 'hidden')
type = 'number';
else
type = 'string';
}

if (type === 'string') {
item[name] = strings[raw[i + j]];
} else if (type === 'number' || type === 'node') {
item[name] = raw[i + j];
}
}
items.push(item);
}

return items;
}

function inspectNode(snapshot) {
return util.inspect(snapshot, { depth: 4 });
Expand Down

0 comments on commit ebcd502

Please sign in to comment.