• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Understanding Javascript Engines
 

Understanding Javascript Engines

on

  • 5,001 views

A quick introduction to how Javascript engi

A quick introduction to how Javascript engi

Statistics

Views

Total Views
5,001
Views on SlideShare
80
Embed Views
4,921

Actions

Likes
3
Downloads
26
Comments
0

9 Embeds 4,921

http://blog.nparashuram.com 2447
http://blog.nparashuram.com 2447
http://feeds.feedburner.com 11
http://feeds2.feedburner.com 8
http://www.linkedin.com 3
http://207.46.192.232 2
http://translate.googleusercontent.com 1
http://webcache.googleusercontent.com 1
http://ps.googleusercontent.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Understanding Javascript Engines Understanding Javascript Engines Presentation Transcript

    • JavaScript Engines
      Pop the hood
    • z = x + y
    • Executing z = x + y
      Read operation from memory
      Get location of x and y
      Read values for x and y
      Unbox x and y.
      Choose meaning of “+”, perform “+”
      Save z to memory
      Do garbage.
    • 1. Read operation from memory…
      String “z = x + y” is passed into tokenizer.
      Webkit uses Flex (LEX)
      Accommodate semi colon insertion, etc.
      Tokenizer output fed to parser
      Webkit uses Bison, bottom up shift reduce parser
      Gecko has top down parser
      Statement now available as Abstract Syntax Tree (AST)
    • 2. Get locations of x and y
      X & Y could be number, string, object, null, undefined, array, etc.
      Offsets directly available for primitives
      Values also depend on context of execution
      Closures (activation contexts)
      Local Variables
      Object properties
      Scope modifiers – eval, with, etc.
    • 2. Get values of x – Array
      If x is a actually array - obj[x]
      Dense array have offsets
      Created using 0..N or push
      Gecko creates sparse array on N..0
      Adding obj[“name”] fails optimization
    • 2. Get values of x – Object
      If X is an object property (obj.x)
      Looks up current object or up the prototype chain
      Inline Cache (IC) the value
      Objects have shape – {x:1} is different from {x:1,y:2}
      Webkit stores memory offsets in hidden classes
      New shape created for every new property.
      IC can read from prototype without walking tree
      Closures only save path, still have to walk every time.
      OpCodes generated for each shape
      Obj.x ==> read shape1[member1]
    • 3. Read boxed input …
      JavaScript variable assignments are un-typed.
      Assignments stored as boxed inputs
      x could be (int32 | 100) – indicating type and value
      Javascript numbers are IEEE-754 floating point.
      Who cares, just use 32 bit to optimize.
      Overflow to doubles.
      Ways to Box values (ref)
      Tagging the LSBs (ref)
      Nan Boxing (ref) – 51 bit of NaN space for non-doubles (Webkit)
      Nun Boxing (favor doubles in NAN – Mozilla pun)
    • 4. Unbox x and y
      • From box, infer type and value, represent it in native type
      • Int32 x = 100;
      • From NunBoxed Values
      • 0x400c 0000 | 0x0000 0000 = not a nan, so double (3.5)
      • 0xFFFF0001 | 0x0000 0040 = Nan space, so Int32 (0x0000 0040)
      • From NanBoxed Values (0xFFFF80 00000040)
      • Mask to get pointer, shift to get double
      • X64 portability, fits in register, but harder to decode
    • 5. Perform “+” : Interpreter
      • If (typeof x == int32 && typeof y == int32)
      • result = x <operator> y
      • If (result overflows), result = float
      • If (result Nan), result = NaN.
      • If (typeof x == int32 && typeof y === float)
      • result = CoarceToFloat(x) + y
      • // Same sanity checks
      • …..
      • If (typeof x === Object)
      • ….
    • 5. Perform “+” : Basic JIT
      • If type of x and y are known,
      • generate opcodes
      • Fall to opcode when routine is hit.
      • Save cost of boxing, unboxing.
      • Determined opcode Paths for each shape
      • Multiple shapes mean multiple if-else branches
      • Still have to check for validity/dirtiness of opcpdes
      • Typical JagerMonkeyJITing
    • 5. Perform “+” : Typed JIT
      • Observe and identify hot code
      • 70 iterations
      • Crankshaft – according to profiler
      • Other heuristics
      • Execute opcode routine for specific type
      • Initial compilation cost
      • OpCodes may be thrown away if types change
      • Fallback to non-optimized version (Performance fault)
      • Classic Tracemonkey
    • 5. Perform “+” : Next Gen JIT
      • Static analysis of code to “prove” types
      • Reduce checks, ensure only one path taken at all times.
      • Type stable Javascript
      • IonMonkey Internals.
      • Use multicore processors
      • To box/unbox values
      • To generate compiled opcodes (Chakra)
    • 5. Perform “+” : GPU Enabled
      • Used by WebGL and Canvas render computation routines
      • Shaders and alpha channel (no direct JS code)
      • Super fast floating point math
      • Note that variables is strongly typed as Blobs
    • 5. Perform “+” : Datatypes
      • Strings
      • Substring is O(1), Concat also optimized
      • Concat fault on Opera, Chrome
      • Array
      • Denser the better
      • Named property is sparse in FF, IE
      • Iterate using index, not for:in or functional
      • Functions
      • F() faster than f.call(), f.apply().
      • Using arguments slows down execution
    • 5. Perform “+” : Datatypes
      • Objects
      • Prototypes are better than closures
      • Exceptions
      • Try is mostly free, catch is expensive
      • May cause optimizer to stop
      • Eval and With
      • Cause scope sudden change, prevent JIT
    • 6. Save Z
      • Box “z” and put it on heap if required.
      • Leave “z” in register if used subsequently
      • Create shape for “z” if object
    • 7. Garbage Collection
      • Mark and Sweep
      • Causes GC to pause main routine
      • Jittery animation, unresponsive UI thread
      • Incremental GC
      • Mark and sweep only parts
      • Generational GC
      • Separate objects in nursery and tenured areas
      • Promoting young to old is expensive
      • Combine Generational and Incremental
      • Frequent young cleanup, occasional old cleanup
    • Changes due to ECMA.next
      • Block Scope reduces variable lookups (let, var)
      • “Yeild” may need to save current context
      • Blob Data type – boxing/unboxing issues
      • Classes === Concrete Shapes ?
      • Syntactic sugar, no impact
      • Assignment de-structuring
      • Promises, modules, etc.
    • Conclusions
      • Don’t write any code
      • Practice type safety
      • Leave hot loops alone – don’t create shapes in them
      • Make arrays dense
      • Avoid operations that require different type coercion every time.
    • @nparashuramhttp://nparashuram.com