Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: reintroduce v8 module #131

Merged
merged 1 commit into from
Dec 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/api/_toc.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@
* [UDP/Datagram](dgram.html)
* [URL](url.html)
* [Utilities](util.html)
* [V8](v8.html)
* [VM](vm.html)
* [ZLIB](zlib.html)
1 change: 1 addition & 0 deletions doc/api/all.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@
@include debugger
@include cluster
@include smalloc
@include v8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may also want to add V8 to api/doc/_toc.markdown (for it to show up on the index.)

43 changes: 43 additions & 0 deletions doc/api/v8.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# V8

Stability: 1 - Experimental

This module exposes events and interfaces specific to the version of [V8][]
built with node. These interfaces are subject to change by upstream and are
therefore not covered under the stability index.

### getHeapStatistics()

Returns an object with the following properties

```
{
total_heap_size: 7326976,
total_heap_size_executable: 4194304,
total_physical_size: 7326976,
used_heap_size: 3476208,
heap_size_limit: 1535115264
}
```

### setFlagsFromString()

Set additional V8 command line flags. Use with care; changing settings
after the VM has started may result in unpredictable behavior, including
crashes and data loss. Or it may simply do nothing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably could reference one of the docs here for this.
I tried to research and test what flags have effect and which don't.
More work needs to be done here, but it's a good place to start looking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can others weigh in? I appreciate Thorsten's effort but I don't want to give off an implied promise of support by linking to documentation. Or is that overly cautious? I lean towards pointing people to --v8-options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be in favor of something like:

The V8 options available for a version of node may be determined by running `node --v8-options`. An unofficial, community-maintained list of options and their effects is available [here](https://github.com/thlorenz/v8-flags/blob/master/flags-0.11.md).

Since it stresses that the linked guide isn't the "source of truth" -- that lies within v8 -- but gives casual readers a chance to see what's available through this API.

(Also, great work @thlorenz!)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis Totally agree that implied promises given by linking are bad especially if linked content ends up not being maintained.

On the upside, the v8-flags documentation is entirely generated and can be updated whenever the API changes by simply running npm run flag-doc.
The only part of the docs that is manual and gets merged with the auto generated one is specified here. I was secretly hoping for some v8 folks to jump in and help with adding more details via simple update steps

If linking to a third party thing is worrisome I'm open to adapt the generated docs to be included somewhere within the official node docs.


Thanks @chrisdickinson macros are lots of fun :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thlorenz I incorporated @chrisdickinson's feedback earlier today; it makes it clear that the linked page is a community effort so I think we're good. Is https://github.com/thlorenz/v8-flags/blob/master/flags-0.11.md the best page to link to or is there a better one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until we generate docs for 12, this is the best one.


The V8 options available for a version of node may be determined by running
`iojs --v8-options`. An unofficial, community-maintained list of options
and their effects is available
[here](https://github.com/thlorenz/v8-flags/blob/master/flags-0.11.md).

Usage:

```
// Print GC events to stdout for one minute.
var v8 = require('v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is the best API to use. Using v8-flags you can just do things like

flags.use_strict(true);
flags.max_inlining_levels(2);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered an API like that but the problem I see is that requires updating the argument list whenever we upgrade or downgrade V8. It's perhaps possible to automate that by including deps/v8/src/flag-definitions.h but that assumes the format of that file is fixed and it wouldn't play nice with distro packagers that unbundle V8. It's also a lot more complexity, of course.


[V8]: https://code.google.com/p/v8/
3 changes: 2 additions & 1 deletion lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ exports.writer = util.inspect;
exports._builtinLibs = ['assert', 'buffer', 'child_process', 'cluster',
'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net',
'os', 'path', 'punycode', 'querystring', 'readline', 'stream',
'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib', 'smalloc'];
'string_decoder', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib',
'smalloc'];


function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
Expand Down
41 changes: 41 additions & 0 deletions lib/v8.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2014, StrongLoop Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

'use strict';

var EventEmitter = require('events');
var v8binding = process.binding('v8');

var v8 = module.exports = new EventEmitter();
v8.getHeapStatistics = v8binding.getHeapStatistics;
v8.setFlagsFromString = v8binding.setFlagsFromString;


function emitGC(before, after) {
v8.emit('gc', before, after);
}


v8.on('newListener', function(name) {
if (name === 'gc' && EventEmitter.listenerCount(this, name) === 0) {
v8binding.startGarbageCollectionTracking(emitGC);
}
});


v8.on('removeListener', function(name) {
if (name === 'gc' && EventEmitter.listenerCount(this, name) === 0) {
v8binding.stopGarbageCollectionTracking();
}
});
1 change: 1 addition & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
'lib/tty.js',
'lib/url.js',
'lib/util.js',
'lib/v8.js',
'lib/vm.js',
'lib/zlib.js',
],
Expand Down
26 changes: 26 additions & 0 deletions test/simple/test-v8-flags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2014, StrongLoop Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

var common = require('../common');
var assert = require('assert');
var v8 = require('v8');
var vm = require('vm');

v8.setFlagsFromString('--allow_natives_syntax');
assert(eval('%_IsSmi(42)'));
assert(vm.runInThisContext('%_IsSmi(42)'));

v8.setFlagsFromString('--noallow_natives_syntax');
assert.throws(function() { eval('%_IsSmi(42)') }, SyntaxError);
assert.throws(function() { vm.runInThisContext('%_IsSmi(42)') }, SyntaxError);
46 changes: 46 additions & 0 deletions test/simple/test-v8-gc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2014, StrongLoop Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

// Flags: --expose_gc

var common = require('../common');
var assert = require('assert');
var v8 = require('v8');

assert(typeof gc === 'function', 'Run this test with --expose_gc.');

var ncalls = 0;
var before;
var after;

function ongc(before_, after_) {
// Try very hard to not create garbage because that could kick off another
// garbage collection cycle.
before = before_;
after = after_;
ncalls += 1;
}

gc();
v8.on('gc', ongc);
gc();
v8.removeListener('gc', ongc);
gc();

assert.equal(ncalls, 1);
assert.equal(typeof before, 'object');
assert.equal(typeof after, 'object');
assert.equal(typeof before.timestamp, 'number');
assert.equal(typeof after.timestamp, 'number');
assert.equal(before.timestamp <= after.timestamp, true);
29 changes: 29 additions & 0 deletions test/simple/test-v8-stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2014, StrongLoop Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

var common = require('../common');
var assert = require('assert');
var v8 = require('v8');

var s = v8.getHeapStatistics();
var keys = [
'heap_size_limit',
'total_heap_size',
'total_heap_size_executable',
'total_physical_size',
'used_heap_size'];
assert.deepEqual(Object.keys(s).sort(), keys);
keys.forEach(function(key) {
assert.equal(typeof s[key], 'number');
});