Skip to content

Commit

Permalink
src: export v8.GetHeapCodeAndMetadataStatistics()
Browse files Browse the repository at this point in the history
Export statistic provided by V8 through HeapCodeStatistics class and
and GetHeapCodeAndMetadataStatistics function to v8 Node.js module

PR-URL: nodejs#27978
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
Yuriy Vasiyarov authored and Trott committed Jul 30, 2019
1 parent 8be3766 commit 21a7c69
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 3 deletions.
22 changes: 22 additions & 0 deletions doc/api/v8.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,28 @@ being non-zero indicates a potential memory leak.
}
```

## v8.getHeapCodeStatistics()
<!-- YAML
added: REPLACEME
-->

* Returns: {Object}

Returns an object with the following properties:

* `code_and_metadata_size` {number}
* `bytecode_and_metadata_size` {number}
* `external_script_source_size` {number}

<!-- eslint-skip -->
```js
{
code_and_metadata_size: 212208,
bytecode_and_metadata_size: 161368,
external_script_source_size: 1410794
}
```

## v8.setFlagsFromString(flags)
<!-- YAML
added: v1.0.0
Expand Down
30 changes: 27 additions & 3 deletions lib/v8.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,12 @@ const {
setFlagsFromString: _setFlagsFromString,
heapStatisticsArrayBuffer,
heapSpaceStatisticsArrayBuffer,
heapCodeStatisticsArrayBuffer,
updateHeapStatisticsArrayBuffer,
updateHeapSpaceStatisticsArrayBuffer,
updateHeapCodeStatisticsArrayBuffer,

// Properties for heap and heap space statistics buffer extraction.
// Properties for heap statistics buffer extraction.
kTotalHeapSizeIndex,
kTotalHeapSizeExecutableIndex,
kTotalPhysicalSizeIndex,
Expand All @@ -104,14 +106,21 @@ const {
kDoesZapGarbageIndex,
kMallocedMemoryIndex,
kPeakMallocedMemoryIndex,
kNumberOfNativeContextsIndex,
kNumberOfDetachedContextsIndex,

// Properties for heap spaces statistics buffer extraction.
kHeapSpaces,
kHeapSpaceStatisticsPropertiesCount,
kSpaceSizeIndex,
kSpaceUsedSizeIndex,
kSpaceAvailableSizeIndex,
kPhysicalSpaceSizeIndex,
kNumberOfNativeContextsIndex,
kNumberOfDetachedContextsIndex

// Properties for heap code statistics buffer extraction.
kCodeAndMetadataSizeIndex,
kBytecodeAndMetadataSizeIndex,
kExternalScriptSourceSizeIndex
} = internalBinding('v8');

const kNumberOfHeapSpaces = kHeapSpaces.length;
Expand All @@ -122,6 +131,9 @@ const heapStatisticsBuffer =
const heapSpaceStatisticsBuffer =
new Float64Array(heapSpaceStatisticsArrayBuffer);

const heapCodeStatisticsBuffer =
new Float64Array(heapCodeStatisticsArrayBuffer);

function setFlagsFromString(flags) {
validateString(flags, 'flags');
_setFlagsFromString(flags);
Expand Down Expand Up @@ -166,6 +178,17 @@ function getHeapSpaceStatistics() {
return heapSpaceStatistics;
}

function getHeapCodeStatistics() {
const buffer = heapCodeStatisticsBuffer;

updateHeapCodeStatisticsArrayBuffer();
return {
'code_and_metadata_size': buffer[kCodeAndMetadataSizeIndex],
'bytecode_and_metadata_size': buffer[kBytecodeAndMetadataSizeIndex],
'external_script_source_size': buffer[kExternalScriptSourceSizeIndex]
};
}

/* V8 serialization API */

/* JS methods for the base objects */
Expand Down Expand Up @@ -272,6 +295,7 @@ module.exports = {
getHeapSnapshot,
getHeapStatistics,
getHeapSpaceStatistics,
getHeapCodeStatistics,
setFlagsFromString,
Serializer,
Deserializer,
Expand Down
10 changes: 10 additions & 0 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,16 @@ inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
heap_space_statistics_buffer_ = pointer;
}

inline double* Environment::heap_code_statistics_buffer() const {
CHECK_NOT_NULL(heap_code_statistics_buffer_);
return heap_code_statistics_buffer_;
}

inline void Environment::set_heap_code_statistics_buffer(double* pointer) {
CHECK_NULL(heap_code_statistics_buffer_); // Should be set only once.
heap_code_statistics_buffer_ = pointer;
}

inline char* Environment::http_parser_buffer() const {
return http_parser_buffer_;
}
Expand Down
1 change: 1 addition & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ Environment::~Environment() {
delete[] heap_statistics_buffer_;
delete[] heap_space_statistics_buffer_;
delete[] http_parser_buffer_;
delete[] heap_code_statistics_buffer_;

TRACE_EVENT_NESTABLE_ASYNC_END0(
TRACING_CATEGORY_NODE1(environment), "Environment", this);
Expand Down
4 changes: 4 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,9 @@ class Environment : public MemoryRetainer {
inline double* heap_space_statistics_buffer() const;
inline void set_heap_space_statistics_buffer(double* pointer);

inline double* heap_code_statistics_buffer() const;
inline void set_heap_code_statistics_buffer(double* pointer);

inline char* http_parser_buffer() const;
inline void set_http_parser_buffer(char* buffer);
inline bool http_parser_buffer_in_use() const;
Expand Down Expand Up @@ -1345,6 +1348,7 @@ class Environment : public MemoryRetainer {

double* heap_statistics_buffer_ = nullptr;
double* heap_space_statistics_buffer_ = nullptr;
double* heap_code_statistics_buffer_ = nullptr;

char* http_parser_buffer_ = nullptr;
bool http_parser_buffer_in_use_ = false;
Expand Down
56 changes: 56 additions & 0 deletions src/node_v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ using v8::Array;
using v8::ArrayBuffer;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::HeapCodeStatistics;
using v8::HeapSpaceStatistics;
using v8::HeapStatistics;
using v8::Integer;
Expand All @@ -43,6 +44,7 @@ using v8::Uint32;
using v8::V8;
using v8::Value;


#define HEAP_STATISTICS_PROPERTIES(V) \
V(0, total_heap_size, kTotalHeapSizeIndex) \
V(1, total_heap_size_executable, kTotalHeapSizeExecutableIndex) \
Expand All @@ -61,6 +63,7 @@ static const size_t kHeapStatisticsPropertiesCount =
HEAP_STATISTICS_PROPERTIES(V);
#undef V


#define HEAP_SPACE_STATISTICS_PROPERTIES(V) \
V(0, space_size, kSpaceSizeIndex) \
V(1, space_used_size, kSpaceUsedSizeIndex) \
Expand All @@ -73,6 +76,16 @@ static const size_t kHeapSpaceStatisticsPropertiesCount =
#undef V


#define HEAP_CODE_STATISTICS_PROPERTIES(V) \
V(0, code_and_metadata_size, kCodeAndMetadataSizeIndex) \
V(1, bytecode_and_metadata_size, kBytecodeAndMetadataSizeIndex) \
V(2, external_script_source_size, kExternalScriptSourceSizeIndex)

#define V(a, b, c) +1
static const size_t kHeapCodeStatisticsPropertiesCount =
HEAP_CODE_STATISTICS_PROPERTIES(V);
#undef V

void CachedDataVersionTag(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Local<Integer> result =
Expand Down Expand Up @@ -111,6 +124,18 @@ void UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo<Value>& args) {
}


void UpdateHeapCodeStatisticsArrayBuffer(
const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
HeapCodeStatistics s;
env->isolate()->GetHeapCodeAndMetadataStatistics(&s);
double* const buffer = env->heap_code_statistics_buffer();
#define V(index, name, _) buffer[index] = static_cast<double>(s.name());
HEAP_CODE_STATISTICS_PROPERTIES(V)
#undef V
}


void SetFlagsFromString(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());
String::Utf8Value flags(args.GetIsolate(), args[0]);
Expand All @@ -127,6 +152,7 @@ void Initialize(Local<Object> target,
env->SetMethodNoSideEffect(target, "cachedDataVersionTag",
CachedDataVersionTag);

// Export symbols used by v8.getHeapStatistics()
env->SetMethod(target,
"updateHeapStatisticsArrayBuffer",
UpdateHeapStatisticsArrayBuffer);
Expand All @@ -151,6 +177,35 @@ void Initialize(Local<Object> target,
HEAP_STATISTICS_PROPERTIES(V)
#undef V

// Export symbols used by v8.getHeapCodeStatistics()
env->SetMethod(target,
"updateHeapCodeStatisticsArrayBuffer",
UpdateHeapCodeStatisticsArrayBuffer);

env->set_heap_code_statistics_buffer(
new double[kHeapCodeStatisticsPropertiesCount]);

const size_t heap_code_statistics_buffer_byte_length =
sizeof(*env->heap_code_statistics_buffer())
* kHeapCodeStatisticsPropertiesCount;

target->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(),
"heapCodeStatisticsArrayBuffer"),
ArrayBuffer::New(env->isolate(),
env->heap_code_statistics_buffer(),
heap_code_statistics_buffer_byte_length))
.Check();

#define V(i, _, name) \
target->Set(env->context(), \
FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
Uint32::NewFromUnsigned(env->isolate(), i)).Check();

HEAP_CODE_STATISTICS_PROPERTIES(V)
#undef V

// Export symbols used by v8.getHeapSpaceStatistics()
target->Set(env->context(),
FIXED_ONE_BYTE_STRING(env->isolate(),
"kHeapSpaceStatisticsPropertiesCount"),
Expand Down Expand Up @@ -205,6 +260,7 @@ void Initialize(Local<Object> target,
HEAP_SPACE_STATISTICS_PROPERTIES(V)
#undef V

// Export symbols used by v8.setFlagsFromString()
env->SetMethod(target, "setFlagsFromString", SetFlagsFromString);
}

Expand Down
12 changes: 12 additions & 0 deletions test/parallel/test-v8-stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ keys.forEach(function(key) {
});


const heapCodeStatistics = v8.getHeapCodeStatistics();
const heapCodeStatisticsKeys = [
'bytecode_and_metadata_size',
'code_and_metadata_size',
'external_script_source_size'];
assert.deepStrictEqual(Object.keys(heapCodeStatistics).sort(),
heapCodeStatisticsKeys);
heapCodeStatisticsKeys.forEach(function(key) {
assert.strictEqual(typeof heapCodeStatistics[key], 'number');
});


const expectedHeapSpaces = [
'code_large_object_space',
'code_space',
Expand Down

0 comments on commit 21a7c69

Please sign in to comment.