Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Catch a spider monkey

418 views

Published on

In the recent Functional Thursday meetup, I gave this talk about SpiderMonkey: Mozilla's JavaScript engine used in Firefox. The content covers the architecture and some interesting internal implementations.

  • Login to see the comments

  • Be the first to like this

Catch a spider monkey

  1. 1. Catch a SpiderMonkey 抓猴去 @GregWeng 2016/04/07 Functional Thursday
  2. 2. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  3. 3. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  4. 4. https://blog.mozilla.org/luke/
  5. 5. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  6. 6. https://dxr.mozilla.org/mozilla-central/source/js/src/vm/ForOfIterator.cpp
  7. 7. https://dxr.mozilla.org/mozilla-central/source/js/
  8. 8. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  9. 9. ../configure --enable-debug --disable-optimize --without-intl-api
  10. 10. pref("javascript.options.baselinejit", true → false); pref("javascript.options.ion", true → false); https://dxr.mozilla.org/mozilla-central/source/modules/libpref/init/all.js#1149-1150
  11. 11. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  12. 12. mozilla-central/js/src/build_DBG.OBJ/dist/bin/js js>
  13. 13. JS Shell ● No DOM (ex: document.all) ● No Jit (debug build) ● With some debug functions
  14. 14. js> dis(function() { a + b }) flags: LAMBDA CONSTRUCTOR loc op ----- -- main: 00000: getgname "a" 00005: getgname "b" 00010: add 00011: pop 00012: retrval Source notes: ofs line pc delta desc args ---- ---- ----- ------ -------- ------ 0: 1 0 [ 0] colspan 17 2: 1 12 [ 12] xdelta 3: 1 12 [ 0] colspan 5
  15. 15. From JS to C++ dis() JS_FN_HELP( macro "dis", name in JS Disassemble, implementation 1, nargs 0, flags "dis([fun/code])", usage "Disassemble functions...") help https://dxr.mozilla.org/mozilla-central/source/js/src/shell/js.cpp#5341 https://dxr.mozilla.org/mozilla-central/source/js/src/jsfriendapi.h#304
  16. 16. From JS to C++ https://dxr.mozilla.org/mozilla-central/source/js/src/shell/js.cpp#2427 static bool Disassemble(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); if (!gOutFile->isOpen()) { JS_ReportError(cx, "output file is closed"); return false; } ... } JS_FN_HELP("dis", Disassemble
  17. 17. From JS to JS ● Some parts are implemented in JS ● Especially for what spec described ● Need the SelfHosting helpers
  18. 18. js> [2,4,7].find((e) => 0 !== e % 2)
  19. 19. From JS to JS [...].find() JS_SELF_HOSTED_FN( macro "find", name in JS "ArrayFind", implementation 1, nargs 0 flag ) https://dxr.mozilla.org/mozilla-central/source/js/src/jsarray.cpp#3114 https://dxr.mozilla.org/mozilla-central/source/js/src/jsapi.h#2124
  20. 20. From JS to JS https://dxr.mozilla.org/mozilla-central/source/js/src/builtin/Array.js#495 /* ES6 draft 2013-05-14 15.4.3.23. */ function ArrayFind(predicate/*, thisArg*/) { /* Steps 1-2. */ var O = ToObject(this); /* Steps 3-5. */ var len = ToInteger(O.length); /* Step 6. */ if (arguments.length === 0) ThrowTypeError(... } JS_SELF_HOSTED_FN("find", "ArrayFind"
  21. 21. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  22. 22. Self Hosting Functions https://dxr.mozilla.org/mozilla-central/source/js/src/builtin/Array.js#495 /* ES6 draft 2013-05-14 15.4.3.23. */ function ArrayFind(predicate/*, thisArg*/) { /* Steps 1-2. */ var O = ToObject(this); /* Steps 3-5. */ var len = ToInteger(O.length); /* Step 6. */ if (arguments.length === 0) ThrowTypeError(... } JS_SELF_HOSTED_FN("find", "ArrayFind"
  23. 23. Self Hosting Functions ● Defined in C++ ● Allow you access C++ helper in JS helper ● Prefix with intrinsic_ ● Most of them are in js/src/vm/SelfHosting.cpp
  24. 24. Self Hosting Functions [...].find() JS_SELF_HOSTED_FN("find", "ArrayFind" function ArrayFind(predicate... var O = ToObject(this); JS_INLINABLE_FN("ToObject",intrinsic_ToObject https://dxr.mozilla.org/mozilla-central/source/js/src/vm/SelfHosting.cpp#2050
  25. 25. Self Hosting Functions https://dxr.mozilla.org/mozilla-central/source/js/src/vm/SelfHosting.cpp#70 static bool intrinsic_ToObject(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedValue val(cx, args[0]); RootedObject obj(cx, ToObject(cx, val)); if (!obj) return false; args.rval().setObject(*obj); return true; }
  26. 26. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  27. 27. JS in JS Engine ● Trouble ● Convenient trouble
  28. 28. How to follow spec in C++ ?
  29. 29. Using JS to describe it /* ES6 draft 2013-05-14 15.4.3.23. */ function ArrayFind(predicate/*, thisArg*/) { /* Steps 1-2. */ var O = ToObject(this); /* Steps 3-5. */ var len = ToInteger(O.length); /* Step 6. */ if (arguments.length === 0) ThrowTypeError(... }
  30. 30. No need to worry about ● Memory safe ● Performance (Jit + intrinsic helpers)
  31. 31. Trouble: Broken stack
  32. 32. Still have some cure (gdb) call DumpJSStack() debug JS from gdb
  33. 33. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Intepreter.cpp
  34. 34. bugzil.la/ 1232266
  35. 35. Break points ● js/src/jsfriendapi.h ● js/src/vm/TypedArrayObject.cpp ● js/src/vm/TypedArrayCommon.h
  36. 36. Catch a Spider Monkey ● Overview of SpiderMonkey ● DXR: codebase reference ● Little trick to build it faster for debugging ● Drop into the shell ● Self-hosting functions ● JavaScript in JavaScript engine ● Live demo: path tracing for TypedArray ● The beast: Interpreter.cpp
  37. 37. Huge Switch Case (Macro)
  38. 38. Things To watch ● Map JSOP_ to stack operations ● Fetch CallArgs on the stack ● Invoke native functions ● Magic goto and macro for performance

×