mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
v8: optimize getHeapStatistics
Since setting object properties in C++ can be slow, pass data to JS using preallocated smalloc buffer and create object in JS instead. PR-URL: https://github.com/iojs/io.js/pull/469 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
5d014637b6
commit
5435cf2f16
26
lib/v8.js
26
lib/v8.js
@ -15,5 +15,29 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var v8binding = process.binding('v8');
|
var v8binding = process.binding('v8');
|
||||||
exports.getHeapStatistics = v8binding.getHeapStatistics;
|
var smalloc = require('smalloc');
|
||||||
|
|
||||||
|
var heapStatisticsBuffer = smalloc.alloc(v8binding.kHeapStatisticsBufferLength,
|
||||||
|
v8binding.kHeapStatisticsBufferType);
|
||||||
|
|
||||||
|
var kTotalHeapSizeIndex = v8binding.kTotalHeapSizeIndex;
|
||||||
|
var kTotalHeapSizeExecutableIndex = v8binding.kTotalHeapSizeExecutableIndex;
|
||||||
|
var kTotalPhysicalSizeIndex = v8binding.kTotalPhysicalSizeIndex;
|
||||||
|
var kUsedHeapSizeIndex = v8binding.kUsedHeapSizeIndex;
|
||||||
|
var kHeapSizeLimitIndex = v8binding.kHeapSizeLimitIndex;
|
||||||
|
|
||||||
|
exports.getHeapStatistics = function() {
|
||||||
|
var buffer = heapStatisticsBuffer;
|
||||||
|
|
||||||
|
v8binding.getHeapStatistics(buffer);
|
||||||
|
|
||||||
|
return {
|
||||||
|
'total_heap_size': buffer[kTotalHeapSizeIndex],
|
||||||
|
'total_heap_size_executable': buffer[kTotalHeapSizeExecutableIndex],
|
||||||
|
'total_physical_size': buffer[kTotalPhysicalSizeIndex],
|
||||||
|
'used_heap_size': buffer[kUsedHeapSizeIndex],
|
||||||
|
'heap_size_limit': buffer[kHeapSizeLimitIndex]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
exports.setFlagsFromString = v8binding.setFlagsFromString;
|
exports.setFlagsFromString = v8binding.setFlagsFromString;
|
||||||
|
@ -92,7 +92,6 @@ namespace node {
|
|||||||
V(fsevent_string, "FSEvent") \
|
V(fsevent_string, "FSEvent") \
|
||||||
V(gid_string, "gid") \
|
V(gid_string, "gid") \
|
||||||
V(handle_string, "handle") \
|
V(handle_string, "handle") \
|
||||||
V(heap_size_limit_string, "heap_size_limit") \
|
|
||||||
V(heap_total_string, "heapTotal") \
|
V(heap_total_string, "heapTotal") \
|
||||||
V(heap_used_string, "heapUsed") \
|
V(heap_used_string, "heapUsed") \
|
||||||
V(hostmaster_string, "hostmaster") \
|
V(hostmaster_string, "hostmaster") \
|
||||||
@ -198,13 +197,9 @@ namespace node {
|
|||||||
V(tls_sni_string, "tls_sni") \
|
V(tls_sni_string, "tls_sni") \
|
||||||
V(tls_string, "tls") \
|
V(tls_string, "tls") \
|
||||||
V(tls_ticket_string, "tlsTicket") \
|
V(tls_ticket_string, "tlsTicket") \
|
||||||
V(total_heap_size_executable_string, "total_heap_size_executable") \
|
|
||||||
V(total_heap_size_string, "total_heap_size") \
|
|
||||||
V(total_physical_size_string, "total_physical_size") \
|
|
||||||
V(type_string, "type") \
|
V(type_string, "type") \
|
||||||
V(uid_string, "uid") \
|
V(uid_string, "uid") \
|
||||||
V(unknown_string, "<unknown>") \
|
V(unknown_string, "<unknown>") \
|
||||||
V(used_heap_size_string, "used_heap_size") \
|
|
||||||
V(user_string, "user") \
|
V(user_string, "user") \
|
||||||
V(uv_string, "uv") \
|
V(uv_string, "uv") \
|
||||||
V(valid_from_string, "valid_from") \
|
V(valid_from_string, "valid_from") \
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
using v8::Context;
|
using v8::Context;
|
||||||
|
using v8::ExternalArrayType;
|
||||||
using v8::Function;
|
using v8::Function;
|
||||||
using v8::FunctionCallbackInfo;
|
using v8::FunctionCallbackInfo;
|
||||||
using v8::Handle;
|
using v8::Handle;
|
||||||
@ -20,25 +21,41 @@ using v8::Uint32;
|
|||||||
using v8::V8;
|
using v8::V8;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
|
#define HEAP_STATISTICS_PROPERTIES(V) \
|
||||||
|
V(0, total_heap_size, kTotalHeapSizeIndex) \
|
||||||
|
V(1, total_heap_size_executable, kTotalHeapSizeExecutableIndex) \
|
||||||
|
V(2, total_physical_size, kTotalPhysicalSizeIndex) \
|
||||||
|
V(3, used_heap_size, kUsedHeapSizeIndex) \
|
||||||
|
V(4, heap_size_limit, kHeapSizeLimitIndex)
|
||||||
|
|
||||||
|
#define V(a, b, c) +1
|
||||||
|
static const size_t kHeapStatisticsBufferLength = HEAP_STATISTICS_PROPERTIES(V);
|
||||||
|
#undef V
|
||||||
|
|
||||||
|
static const ExternalArrayType kHeapStatisticsBufferType =
|
||||||
|
v8::kExternalUint32Array;
|
||||||
|
|
||||||
void GetHeapStatistics(const FunctionCallbackInfo<Value>& args) {
|
void GetHeapStatistics(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
CHECK(args.Length() == 1 && args[0]->IsObject());
|
||||||
|
|
||||||
Isolate* isolate = args.GetIsolate();
|
Isolate* isolate = args.GetIsolate();
|
||||||
HeapStatistics s;
|
HeapStatistics s;
|
||||||
isolate->GetHeapStatistics(&s);
|
isolate->GetHeapStatistics(&s);
|
||||||
Local<Object> info = Object::New(isolate);
|
Local<Object> obj = args[0].As<Object>();
|
||||||
// TODO(trevnorris): Setting many object properties in C++ is a significant
|
uint32_t* data =
|
||||||
// performance hit. Redo this to pass the results to JS and create/set the
|
static_cast<uint32_t*>(obj->GetIndexedPropertiesExternalArrayData());
|
||||||
// properties there.
|
|
||||||
#define V(name) \
|
CHECK_NE(data, nullptr);
|
||||||
info->Set(env->name ## _string(), Uint32::NewFromUnsigned(isolate, s.name()))
|
ASSERT_EQ(obj->GetIndexedPropertiesExternalArrayDataType(),
|
||||||
V(total_heap_size);
|
kHeapStatisticsBufferType);
|
||||||
V(total_heap_size_executable);
|
ASSERT_EQ(obj->GetIndexedPropertiesExternalArrayDataLength(),
|
||||||
V(total_physical_size);
|
kHeapStatisticsBufferLength);
|
||||||
V(used_heap_size);
|
|
||||||
V(heap_size_limit);
|
#define V(i, name, _) \
|
||||||
|
data[i] = static_cast<uint32_t>(s.name());
|
||||||
|
|
||||||
|
HEAP_STATISTICS_PROPERTIES(V)
|
||||||
#undef V
|
#undef V
|
||||||
args.GetReturnValue().Set(info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -54,6 +71,23 @@ void InitializeV8Bindings(Handle<Object> target,
|
|||||||
Environment* env = Environment::GetCurrent(context);
|
Environment* env = Environment::GetCurrent(context);
|
||||||
env->SetMethod(target, "getHeapStatistics", GetHeapStatistics);
|
env->SetMethod(target, "getHeapStatistics", GetHeapStatistics);
|
||||||
env->SetMethod(target, "setFlagsFromString", SetFlagsFromString);
|
env->SetMethod(target, "setFlagsFromString", SetFlagsFromString);
|
||||||
|
|
||||||
|
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
|
||||||
|
"kHeapStatisticsBufferLength"),
|
||||||
|
Uint32::NewFromUnsigned(env->isolate(),
|
||||||
|
kHeapStatisticsBufferLength));
|
||||||
|
|
||||||
|
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(),
|
||||||
|
"kHeapStatisticsBufferType"),
|
||||||
|
Uint32::NewFromUnsigned(env->isolate(),
|
||||||
|
kHeapStatisticsBufferType));
|
||||||
|
|
||||||
|
#define V(i, _, name) \
|
||||||
|
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #name), \
|
||||||
|
Uint32::NewFromUnsigned(env->isolate(), i));
|
||||||
|
|
||||||
|
HEAP_STATISTICS_PROPERTIES(V)
|
||||||
|
#undef V
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
@ -49,7 +49,7 @@ NODE_EXTERN size_t ExternalArraySize(enum v8::ExternalArrayType type);
|
|||||||
* v8::kExternalFloatArray);
|
* v8::kExternalFloatArray);
|
||||||
* v8::Local<v8::Object> obj = v8::Object::New();
|
* v8::Local<v8::Object> obj = v8::Object::New();
|
||||||
* char* data = static_cast<char*>(malloc(byte_length * array_length));
|
* char* data = static_cast<char*>(malloc(byte_length * array_length));
|
||||||
* node::smalloc::Alloc(obj, data, byte_length, v8::kExternalFloatArray);
|
* node::smalloc::Alloc(env, obj, data, byte_length, v8::kExternalFloatArray);
|
||||||
* obj->Set(v8::String::NewFromUtf8("length"),
|
* obj->Set(v8::String::NewFromUtf8("length"),
|
||||||
* v8::Integer::NewFromUnsigned(array_length));
|
* v8::Integer::NewFromUnsigned(array_length));
|
||||||
* \code
|
* \code
|
||||||
|
Loading…
Reference in New Issue
Block a user