Skip to content

Commit

Permalink
Update to work with latest v8/node/chrome
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanaelA committed Feb 16, 2018
1 parent e3606d6 commit 91f9f41
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 174 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea/
*.tgz
*.tar
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea/
opti-killers.md
examples/
*.tgz
*.tar

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2014 Nathanael Anderson
Copyright (c) 2014-2018 Nathanael Anderson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# v8-Natives
[![npm](https://img.shields.io/npm/v/v8-natives.svg)](https://www.npmjs.com/package/v8-natives)
[![npm](https://img.shields.io/npm/l/v8-natives.svg)](https://www.npmjs.com/package/v8-natives)
[![npm](https://img.shields.io/npm/dt/v8-natives.svg?label=npm%20downloads)](https://www.npmjs.com/package/v8-natives)
[![Twitter Follow](https://img.shields.io/twitter/follow/congocart.svg?style=social&label=Follow%20me)](https://twitter.com/congocart)



## Updated:
Last Tested on Node 8.7 & Chrome 66

### Access v8 Engine Natives easily in Chrome & Node

I was reading a blog/wiki article at [https://github.com/petkaantonov/bluebird/wiki/Optimization-killers](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers) and it presents some really low level diagnostic commands that I was totally unaware of; and so I found them to be totally awesome in scope for several things I do. The V8 engine has a large array of commands that you can call that can get and/or set status in the actual v8 engine. This library is my attempt to make my life a lot easier and eliminate the errors in trying to use the v8 native commands. These low level commands allow you access to tell the v8 engine to optimize a routine and then find out if a routine can/is optimized.

Now, you can call the v8 native commands directly (for example ```%GetV8Version()```); however if you forget to use the --allow-natives-syntax then the v8 engine will immediately stop parsing the file as the v8 commands all start with a '%' which is invalid JavaScript... What this library does is it is a simple wrapper that wraps those calls; so that I can do (v8.getV8Version()). If you forgot the --allow-natives-syntax it will still run your code fine; it just won't return anything but a N/A as it doesn't know the version.
Now, you can call the v8 native commands directly (for example ```%CollectGarbage()```); however if you forget to use the --allow-natives-syntax then the v8 engine will immediately stop parsing the file as the v8 commands all start with a '%' which is invalid JavaScript... What this library does is it is a simple wrapper that wraps those calls; so that I can do (v8.CollectGarbage()). If you forgot the --allow-natives-syntax it will still run your code fine; it just won't do anything.

In the examples folder is a browser example; to show you how it works in Chrome/Chromium (```chrome --js-flags="--allow-natives-syntax" browser.html```). You can run it in a non-v8 browser and it will just use the dummy shim.
In addition there is a NodeJS example to show you the same support in NodeJS. (```node --allow-natives-syntax node.js```)

Please note the examples and helper commands can show you how to use a good chunk of the optimization, general and Memory calls in the library. If someone wants to work up some examples using the variable/opject information commands; they would gladly be accepted!
Please note the examples and helper commands can show you how to use a good chunk of the optimization, general and Memory calls in the library. If someone wants to work up some examples using the variable/opject information commands; they would gladly be accepted!

### Installing V8 Natives
```
Expand Down Expand Up @@ -50,7 +59,6 @@ v8.collectGarbage();

### General Commands
- isNative() - Is the Native Support mode enabled (i.e. true = uses real wrapper; false = use dummy wrapper)
- getV8Version() - Gets the v8 engine version
- functionGetName(func) - Gets the string name of a function

### Memory Commands
Expand Down Expand Up @@ -85,3 +93,13 @@ v8.collectGarbage();
- Tag your function for optimization
- Run your Function
- Verify that the v8 Engine optimized it. If it did not optimized it; then that means you have code that can't be optimized in it.


#### ChangeLog
v8 Internal function list has changed the following functions have been removed:
- getV8Version
- getOptimizationCount


v8 Renamed:
- ClearFunctionTypeFeedback to ClearFunctionFeedback
79 changes: 52 additions & 27 deletions examples/browser.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,56 @@
notice("Tests are now complete, you can now open the Javascript Command Console if you want...");
}

function log(results, routine) {
var id = document.getElementById('log');
var data = '';
switch (results) {
case 0:
data = '<br><b>' + routine + '</b>';
break;
case 1:
data = routine + ' is optimized';
break;
case 2:
data = routine + ' is not optimized';
break;
case 3:
data = routine + ' is always optimized';
break;
case 4:
data = routine + ' is never optimized';
break;
case 6:
data = routine + ' is maybe de-optimized';
break;
default:
data = routine + ' has unknown status of ' + results;
}
function checkBitmap(value, bit) {
return ((value & bit) === bit);
}

function log(optStatus, routine) {
var id = document.getElementById('log');
var data = routine +' ';

var optStat = [];
if (checkBitmap(optStatus,1)) {
optStat.push("is Function");
}
if (checkBitmap(optStatus,2)) {
optStat.push("Never Optimized");
}
if (checkBitmap(optStatus,4)) {
optStat.push("Always Optimized");
}
if (checkBitmap(optStatus,8)) {
optStat.push("Maybe Deopted");
}
if (checkBitmap(optStatus,16)) {
optStat.push("Optimized");
}
if (checkBitmap(optStatus,32)) {
optStat.push("TurboFanned");
}
if (checkBitmap(optStatus,64)) {
optStat.push("Interpreted");
}
if (checkBitmap(optStatus,128)) {
optStat.push("Marked for Optimization");
}
if (checkBitmap(optStatus,256)) {
optStat.push("Marked for Concurrent Optimization");
}
if (checkBitmap(optStatus,512)) {
optStat.push("Conccurently Optimizating");
}
if (checkBitmap(optStatus,1024)) {
optStat.push("Is Executing");
}
if (checkBitmap(optStatus,2048)) {
optStat.push("Topmost frame is Turbo Fanned");
}
data += optStat.join(", ");

id.innerHTML = id.innerHTML + data + '<br>';

if (results !== 0) {
if (optStatus !== 0) {
id.innerHTML = id.innerHTML + "<p style='background-color: #EEE'>" + this[routine].toString() + "</p><br>";
}

Expand All @@ -111,8 +132,12 @@
</head>
<body>
<div style="display:none; background-color: #00F; color: #FFF;" id="notice"></div>
<h2>Chrome v8 Natives Test</h2><br><br>
<h2>Chrome v8 Natives Test</h2><br>

<center><font color="red"><h3>Please note these tests and descriptions were done BEFORE TurboFan;<br>it appears all the rules as we knew them have changed. ;-)</h3></font></center>
<br><br>
<div>Please note the Chrome Dev Tools must be closed when you run this; otherwise the v8 engine optimizer will IGNORE all the optimization requests. </div>
<br><br><div id="log"></div>

</body>
</html>
2 changes: 0 additions & 2 deletions examples/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ if (!v8.isNative()) {
process.exit(0);
}

console.log("Node is using v8 version:", v8.getV8Version(), "\r\n");


function sum(a, b, c) {
var result = 0;
Expand Down
125 changes: 70 additions & 55 deletions lib/v8-browser-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
function testIfAllowNativeSyntax() {
var native = false;
try {
eval('%GetV8Version();');
eval('%NativeScriptsCount();');
native = true;
}
catch (err) {
Expand All @@ -38,40 +38,58 @@
return native;
}

function printStatus(fn, fName) {
if (v8.isNative() === false) return -1;
var optStatus = v8.getOptimizationStatus(fn);
if (fName == null || fName === '') {
fName = v8.functionGetName(fn);
}
switch (optStatus) {
case -1:
console.log("Function", fName, 'status is unknown as Native functions are disabled.');
break;
case 1:
console.log("Function", fName, "is optimized");
break;
case 2:
console.log("Function", fName, "is not optimized");
break;
case 3:
console.log("Function", fName, "is always optimized");
break;
case 4:
console.log("Function", fName, "is never optimized");
break;
case 6:
console.log("Function", fName, "is maybe deoptimized");
break;
case 7:
console.log("Function", fName, "is TurboFan optimized");
break;
default:
console.log("Function", fName, "has unknown status", optStatus);
break;
}
return (optStatus);
}
function checkBitmap(value, bit) {
return ((value & bit) === bit);
}

function printStatus(fn, fName) {
if (v8.isNative() === false) return -1;
var optStatus = v8.getOptimizationStatus(fn);
if (fName == null || fName === '') {
fName = v8.functionGetName(fn);
}
var optStat = [];
if (checkBitmap(optStatus,1)) {
optStat.push("is Function");
}
if (checkBitmap(optStatus,2)) {
optStat.push("Never Optimized");
}
if (checkBitmap(optStatus,4)) {
optStat.push("Always Optimized");
}
if (checkBitmap(optStatus,8)) {
optStat.push("Maybe Deopted");
}
if (checkBitmap(optStatus,16)) {
optStat.push("Optimized");
}
if (checkBitmap(optStatus,32)) {
optStat.push("TurboFanned");
}
if (checkBitmap(optStatus,64)) {
optStat.push("Interpreted");
}
if (checkBitmap(optStatus,128)) {
optStat.push("Marked for Optimization");
}
if (checkBitmap(optStatus,256)) {
optStat.push("Marked for Concurrent Optimization");
}
if (checkBitmap(optStatus,512)) {
optStat.push("Conccurently Optimizating");
}
if (checkBitmap(optStatus,1024)) {
optStat.push("Is Executing");
}
if (checkBitmap(optStatus,2048)) {
optStat.push("Topmost frame is Turbo Fanned");
}
console.log("",fName, optStat.join(", "));


return (optStatus);
}

function testIsDebugging() {
var _test = function() { return true; };
Expand All @@ -83,7 +101,7 @@
}
_test();
var res = v8.getOptimizationStatus(_test);
return !(res === 1 || res === 3);
return !((res & 16) === 16);
}

function testOptimization(f, fname) {
Expand Down Expand Up @@ -163,7 +181,7 @@


if (testIfAllowNativeSyntax()) {

console.log("Useing native");
var v8 = _global.v8 = new Function('"use strict";\
// v8 Functions are located in v8/lib/runtime.cc & runtime.h\
// SMI = SMall Integer\n\
Expand All @@ -173,9 +191,6 @@
getOptimizationStatus: function(fun) {\
return %GetOptimizationStatus(fun);\
},\
getOptimizationCount: function(fun) {\
return %GetOptimizationCount(fun);\
},\
optimizeFunctionOnNextCall: function(fun) {\
return %OptimizeFunctionOnNextCall(fun);\
},\
Expand All @@ -185,8 +200,8 @@
deoptimizeNow: function() { \
return %DeoptimizeNow(); \
}, \
clearFunctionTypeFeedback: function(fun) {\
return %ClearFunctionTypeFeedback(fun);\
ClearFunctionFeedback: function(fun) {\
return %ClearFunctionFeedback(fun);\
},\
debugPrint: function(data) {\
return %DebugPrint(data);\
Expand All @@ -203,9 +218,12 @@
hasFastProperties: function(data) {\
return %HasFastProperties(data);\
},\
hasFastSmiElements: function(data) {\
return %HasFastSmiElements(data);\
hasFastElements: function(data) {\
return %HasFastElements(data);\
},\
hasFastPackedElements: function(data) {\
return %hasFastPackedElements(data);\
},\
hasFastObjectElements: function(data) {\
return %HasFastObjectElements(data);\
},\
Expand All @@ -215,8 +233,8 @@
hasDictionaryElements: function(data) {\
return %HasDictionaryElements(data);\
},\
hasFastHoleyElements: function(data) {\
return %HasFastHoleyElements(data);\
hasHoleyElements: function(data) {\
return %HasHoleyElements(data);\
},\
hasFastSmiOrObjectElements: function(data) {\
return %HasFastSmiOrObjectElements(data);\
Expand All @@ -239,9 +257,6 @@
neverOptimizeFunction: function(func) {\
return %NeverOptimizeFunction(func);\
},\
getV8Version: function() {\
return %GetV8Version();\
},\
setFlags: function(flag) { \
return %SetFlags(flag); \
}, \
Expand All @@ -267,19 +282,19 @@
};

// Returns a value; so we return 0
v8.getOptimizationCount = v8.getHeapUsage = function() { return 0; }
v8.getHeapUsage = function() { return 0; }

// Needs to return a string
v8.getV8Version = v8.functionGetName = function() { return "N/A"};
v8.functionGetName = function() { return "N/A"};

// Returns nothing
v8.optimizeFunctionOnNextCall = v8.clearFunctionTypeFeedback = v8.deoptimizeNow = v8.debugTrace =
v8.optimizeFunctionOnNextCall = v8.ClearFunctionFeedback = v8.deoptimizeNow = v8.debugTrace =
v8.debugPrint = v8.deoptimizeFunction = v8.neverOptimizeFunction = v8.collectGarbage = function() { return; }

// Returns booleans, so we return false
v8.getOptimizationStatus = v8.hasFastProperties = v8.hasFastSmiElements = v8.hasFastObjectElements = v8.hasFastDoubleElements =
v8.hasDictionaryElements = v8.hasFastHoleyElements = v8.haveSameMap = v8.isValidSmi = v8.isSmi =
v8.hasFastSmiOrObjectElements = v8.hasSloppyArgumentsElements =
v8.getOptimizationStatus = v8.hasFastProperties = v8.hasSmiElements = v8.hasFastPackedElements = v8.hasDoubleElements =
v8.hasDictionaryElements = v8.hasHoleyElements = v8.haveSameMap = v8.isValidSmi = v8.isSmi =
v8.hasFastSmiOrObjectElements = v8.hasSloppyArgumentsElements =
v8.traceEnter = v8.traceExit = v8.setFlags = v8.isNative;

}
Expand Down
Loading

0 comments on commit 91f9f41

Please sign in to comment.