Understanding Javascript Engine To Code Better

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

Understanding Javascript

Engine to Code better


Ihsan Fauzi rahman
What is Javascript
Engine ?
SpiderMonkey Chakra

JavaScriptCore Rhino Carakan


Ignition & Turbofan

Ignition Optimized
Code

Optimize
Bytecode Turbofan

Interpreted Optimized
How to Make use of
that ?
Hidden Class
function Point(x, y) {
this.x = x;
A Point Initial Hidden
this.y = y;
Object Class H0
}
var p1 = new Point(1, 2);

A Point Initial Hidden


var p2 = new Point(1, “2”);
Object Class H1

var p3 = new Point(1, 2); A Point Initial Hidden


p3.z = 3; Object Class H3
Inline Cache
Monomorphic

Offset 0: x Offset 0: x
Offset 1: y Offset 1: y

Polymorphic

Offset 0: x
Offset 1: y
Offset 2: z
Optimization Killer
Unsupported Syntax

Workaround
function containsObjectLiteralWithProto() { var errorObject = {value: null};
return {__proto__: 3}; function tryCatch(fn, ctx, args) {
} try {
return fn.apply(ctx, args);
}
catch(e) {
function containsObjectLiteralWithGetter() {
errorObject.value = e;
return {
return errorObject;
get prop() {
}
return 3;
}
}
};
var result = tryCatch(mightThrow, void 0, [1,2,3]);
}
//Unambiguously tells whether the call threw
if(result === errorObject) {
var error = errorObject.value;
function containsObjectLiteralWithSetter() { }
return { else {
set prop(val) { //result is the returned value
this.val = val; }
}
};
}
Unmanaged Arguments

Workaround
function reAssignParam(a, b_) {
function defaultArgsReassign(a, b) { var b = b_;
if (arguments.length < 2) b = 5; //unlike b_, b can safely be reassigned
} if (arguments.length < 2) b = 5;
}
Unmanaged Arguments

Workaround
function doesntLeakArguments() {
function leaksArguments1() { //.length is just an integer, this doesn't leak
return arguments; //the arguments object itself
} var args = new Array(arguments.length);
for(var i = 0; i < args.length; ++i) {
function leaksArguments2() { //i is always valid index in the arguments object
var args = [].slice.call(arguments); args[i] = arguments[i];
} }
return args;
function leaksArguments3() { }
var a = arguments;
return function() { function anotherNotLeakingExample() {
return a; var i = arguments.length;
}; var args = [];
} while (i--) args[i] = arguments[i];
return args
}
Unmanaged Arguments

function assignToArguments() {
arguments = 3;
return arguments; There’s no workaround, just remove this.
}
Switch-Case

function over128Cases(c) {
switch(c) {
case 1: break;
case 2: break;
case 3: break;
... Use if else or Array of Function
case 128: break;
case 129: break;
}
}
For-In

The key is not a local variable

function nonLocalKey1() {
var obj = {}
for(var key in obj);
return function() {
return key;
};
}
Always use local variable

var key;
function nonLocalKey2() {
var obj = {}
for(key in obj);
}
For-In

The object being iterated is not a


“simple enumerable"

function hashTableIteration() {
var hashTable = {"-": 3};
for(var key in hashTable); Use simple enumerable object
}
For-In

The object has enumerable properties


in its prototype chain

Object.prototype.fn = function() {}; Except Object.create(null)


For-In

Always use Object.keys and


iterate over array using for loop
function iteratesOverArray() {
var arr = [1, 2, 3];
for (var index in arr) {
function inheritedKeys(obj) {
var ret = [];
}
for(var key in obj) {
}
ret.push(key);
}
return ret;
}
let

Workaround
let a = 0;
let a = 0, b = 3; let b = 3;

let a = 0; let a = 0;
a += 5; a = a + 5;
For-In

Infinite loops with deep logic exit conditions


or unclear exit conditions

while (true) { for (;;) {


Thank You

You might also like