Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
Fixed #1, now it will use Nan package for v8 stuff, so hopefully no m…
Browse files Browse the repository at this point in the history
…ore breakages with new versions
  • Loading branch information
dainis committed May 9, 2014
1 parent 8ad7224 commit 0b4b039
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
build
build
node_modules

1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
8 changes: 6 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"targets": [{
"target_name" : "gcstats",
"sources" : [ "src/gcstats.cc" ]
"sources" : [ "src/gcstats.cc" ],
"include_dirs" : [
"src",
"<!(node -e \"require('nan')\")"
]
}]
}
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"name" : "gc-stats",
"version" : "0.0.1",
"version" : "0.0.2",
"description" : "Exposes node v8 garbage collection stats",
"main" : "index.js",
"repository" : "[email protected]:dainis/node-gcstats.git",
"scripts" : {
"install" : "node-gyp rebuild"
},
"dependencies" : {
"nan" : "~1.0.0"
},
"gypfile" : true
}
}
85 changes: 52 additions & 33 deletions src/gcstats.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "node.h"
#include "v8.h"
#include "nan.h"
#include <stdio.h>

using namespace v8;

Expand All @@ -18,16 +20,19 @@ struct HeapData {
uint64_t gcEndTime;
};

static Persistent<Object> callbackContext;
static Persistent<Function> afterGCCallback;
static NanCallback* afterGCCallback;

static HeapStatistics beforeGCStats;
uint64_t gcStartTime;

#if NODE_MODULE_VERSION >=14
static void recordBeforeGC(Isolate*, GCType, GCCallbackFlags) {
#else
static void recordBeforeGC(GCType, GCCallbackFlags) {
#endif
//Docs say that new objects should not be created
gcStartTime = uv_hrtime();
V8::GetHeapStatistics(&beforeGCStats);
NanGetHeapStatistics(&beforeGCStats);
}

static void copyHeapStats(HeapStatistics* stats, HeapInfo* info) {
Expand All @@ -39,47 +44,49 @@ static void copyHeapStats(HeapStatistics* stats, HeapInfo* info) {
}

static void formatStats(Handle<Object> obj, HeapInfo* info) {
obj->Set(String::NewSymbol("totalHeapSize"), Number::New(info->totalHeapSize));
obj->Set(String::NewSymbol("totalHeapExecutableSize"), Number::New(info->totalHeapExecutableSize));
obj->Set(String::NewSymbol("usedHeapSize"), Number::New(info->usedHeapSize));
obj->Set(String::NewSymbol("heapSizeLimit"), Number::New(info->heapSizeLimit));
obj->Set(NanSymbol("totalHeapSize"), NanNew<Number>(info->totalHeapSize));
obj->Set(NanSymbol("totalHeapExecutableSize"), NanNew<Number>(info->totalHeapExecutableSize));
obj->Set(NanSymbol("usedHeapSize"), NanNew<Number>(info->usedHeapSize));
obj->Set(NanSymbol("heapSizeLimit"), NanNew<Number>(info->heapSizeLimit));
}

static void formatStatDiff(Handle<Object> obj, HeapInfo* before, HeapInfo* after) {
obj->Set(String::NewSymbol("totalHeapSize"), Number::New(
obj->Set(NanSymbol("totalHeapSize"), NanNew<Number>(
static_cast<double>(after->totalHeapSize) - static_cast<double>(before->totalHeapSize)));
obj->Set(String::NewSymbol("totalHeapExecutableSize"), Number::New(
obj->Set(NanSymbol("totalHeapExecutableSize"), NanNew<Number>(
static_cast<double>(after->totalHeapExecutableSize) - static_cast<double>(before->totalHeapExecutableSize)));
obj->Set(String::NewSymbol("usedHeapSize"), Number::New(
obj->Set(NanSymbol("usedHeapSize"), NanNew<Number>(
static_cast<double>(after->usedHeapSize) - static_cast<double>(before->usedHeapSize)));
obj->Set(String::NewSymbol("heapSizeLimit"), Number::New(
obj->Set(NanSymbol("heapSizeLimit"), NanNew<Number>(
static_cast<double>(after->heapSizeLimit) - static_cast<double>(before->heapSizeLimit)));
}

static void asyncAfter(uv_work_t* work, int status) {
NanScope();

HeapData* data = static_cast<HeapData*>(work->data);

Handle<Object> obj = Object::New();
Handle<Object> beforeGCStats = Object::New();
Handle<Object> afterGCStats = Object::New();
Handle<Object> obj = NanNew<Object>();
Handle<Object> beforeGCStats = NanNew<Object>();
Handle<Object> afterGCStats = NanNew<Object>();

formatStats(beforeGCStats, data->before);
formatStats(afterGCStats, data->after);

Handle<Object> diffStats = Object::New();
Handle<Object> diffStats = NanNew<Object>();
formatStatDiff(diffStats, data->before, data->after);

obj->Set(String::NewSymbol("pause"),
Number::New(static_cast<double>(data->gcEndTime - data->gcStartTime)));
obj->Set(String::NewSymbol("pauseMS"),
Number::New(static_cast<double>((data->gcEndTime - data->gcStartTime) / 1000000)));
obj->Set(String::NewSymbol("before"), beforeGCStats);
obj->Set(String::NewSymbol("after"), afterGCStats);
obj->Set(String::NewSymbol("diff"), diffStats);
obj->Set(NanSymbol("pause"),
NanNew<Number>(static_cast<double>(data->gcEndTime - data->gcStartTime)));
obj->Set(NanSymbol("pauseMS"),
NanNew<Number>(static_cast<double>((data->gcEndTime - data->gcStartTime) / 1000000)));
obj->Set(NanSymbol("before"), beforeGCStats);
obj->Set(NanSymbol("after"), afterGCStats);
obj->Set(NanSymbol("diff"), diffStats);

Handle<Value> arguments[] = {obj};

afterGCCallback->Call(callbackContext, 1, arguments);
afterGCCallback->Call(1, arguments);

delete data->before;
delete data->after;
Expand All @@ -91,15 +98,19 @@ static void asyncWork(uv_work_t* work) {
//can't create V8 objects here because this is different thread?
}

#if NODE_MODULE_VERSION >=14
static void afterGC(Isolate*, GCType, GCCallbackFlags) {
#else
static void afterGC(GCType, GCCallbackFlags) {
#endif
uv_work_t* work = new uv_work_t;

HeapData* data = new HeapData;
data->before = new HeapInfo;
data->after = new HeapInfo;
HeapStatistics stats;

V8::GetHeapStatistics(&stats);
NanGetHeapStatistics(&stats);

data->gcEndTime = uv_hrtime();
data->gcStartTime = gcStartTime;
Expand All @@ -112,26 +123,34 @@ static void afterGC(GCType, GCCallbackFlags) {
uv_queue_work(uv_default_loop(), work, asyncWork, asyncAfter);
}

static Handle<Value> AfterGC(const Arguments& args) {
static NAN_METHOD(AfterGC) {
NanScope();

if(args.Length() != 1 || !args[0]->IsFunction()) {
ThrowException(Exception::TypeError(String::New("Callback is required")));
return Undefined();
return NanThrowError("Callback is required");
}

Handle<Function> callback = Handle<Function>::Cast(args[0]);

afterGCCallback = Persistent<Function>::New(callback);
callbackContext = Persistent<Object>::New(Context::GetCalling()->Global());
Local<Function> callbackHandle = args[0].As<Function>();
afterGCCallback = new NanCallback(callbackHandle);

#if NODE_MODULE_VERSION >=14
NanAddGCEpilogueCallback(afterGC);
#else
V8::AddGCEpilogueCallback(afterGC);
#endif

return Undefined();
NanReturnUndefined();
}

void init(Handle<Object> exports) {
NanScope();
#if NODE_MODULE_VERSION >=14
NanAddGCPrologueCallback(recordBeforeGC);
#else
V8::AddGCPrologueCallback(recordBeforeGC);
exports->Set(String::NewSymbol("afterGC"), FunctionTemplate::New(AfterGC)->GetFunction());
#endif

exports->Set(NanSymbol("afterGC"), NanNew<FunctionTemplate>(AfterGC)->GetFunction());
}

NODE_MODULE(gcstats, init)

0 comments on commit 0b4b039

Please sign in to comment.