$30 off During Our Annual Pro Sale. View Details »

Dissecting Node.js – Understanding the most famous JS runtime to the bare bone

Dissecting Node.js – Understanding the most famous JS runtime to the bare bone

Lucas Santos

April 04, 2020
Tweet

More Decks by Lucas Santos

Other Decks in Technology

Transcript

  1. Dissecting Node.js
    Understanding the most popular JS runtime...
    To the bone

    View Slide

  2. whoami
    /khaosdoctor @_staticvoid
    lsantos.dev
    /khaosdoctor
    cloud advocate_
    [email protected]

    View Slide

  3. obarra.co
    trainingcenter.io

    View Slide

  4. abcdevelopers.org

    View Slide

  5. agenda_
    - What is JavaScript
    - What is Node.js
    - Our little function
    - How JavaScript works
    - V8 and its sorceries
    - V8 compiling pipelines
    - Putting it all together

    View Slide

  6. what is JavaScript?

    View Slide

  7. JavaScript
    The language everyone loves to
    hate
    - Prototype-based
    - Dynamically-typed
    - Interpreted language
    - Created in 1995 as a
    scripting language for
    Netscape
    - Created by Brendan Eich
    - Conforms with ECMA262
    (ECMAScript)
    - Defined/Maintained by
    TC39

    View Slide

  8. what is Node.js?

    View Slide

  9. Node.js
    The angel that brought JS to
    the world again
    - JavaScript server-side
    runtime
    - Created in 2009 by Ryan
    Dahl
    - Later sponsored by Joyent
    - Event loop
    - Non blocking I/O
    - Uses V8

    View Slide

  10. View Slide

  11. elements of Node.js_

    View Slide

  12. our little function_

    View Slide

  13. View Slide

  14. fs is a C++ binding_

    View Slide

  15. View Slide

  16. View Slide

  17. the real Node.js_

    View Slide

  18. View Slide

  19. View Slide

  20. how JavaScript works?

    View Slide

  21. the JS engine_

    View Slide

  22. What is an
    engine?
    - Runs all JS code we write
    - Responsible for
    - parsing and interpreting
    - memory allocation
    - the call stack
    - garbage collection
    - code optimizations

    View Slide

  23. There are many
    - V8 -> made by Google for Chrome and some Chromium-based
    browsers
    - Chakra -> made by Microsoft for Microsoft Edge
    - SpiderMonkey -> made by Netscape, now runs on Firefox
    - Rhino -> made by Mozilla, in Java
    - Nitro -> made by Apple for Safari
    - JerryScript, Espruino -> IoT
    - And many others...

    View Slide

  24. Simplified diagram of an engine

    View Slide

  25. JavaScript is single-threaded_

    View Slide

  26. what means to
    be
    single-threaded?
    - We only have one call stack
    - We can only run one thing
    at a time

    View Slide

  27. call stack?

    View Slide

  28. call stack
    - Not part of JS
    - Provided by V8
    - Data structure
    - Ordered as LIFO
    - Keeps track of function
    calls
    - Made of stack frames

    View Slide

  29. View Slide

  30. Call Stack
    Step 0

    View Slide

  31. Call Stack
    Step 1
    printSquare(5)

    View Slide

  32. Call Stack
    Step 2
    printSquare(5)
    multiply(x, x)

    View Slide

  33. Call Stack
    Step 2
    printSquare(5)

    View Slide

  34. Call Stack
    Step 3
    printSquare(5)
    console.log(s)

    View Slide

  35. Call Stack
    Step 4
    printSquare(5)

    View Slide

  36. Call Stack
    Step 5

    View Slide

  37. stack overflow

    View Slide

  38. Call Stack
    f()
    f()
    f()
    f()
    f()
    f()
    f()
    f()
    f()

    View Slide

  39. the hosting environment_

    View Slide

  40. hosting
    environment - Wherever place the code is
    running on
    - Provides external APIs
    - Handles async queues

    View Slide

  41. the real diagram

    View Slide

  42. event loop

    View Slide

  43. callbacks

    View Slide

  44. event loop
    - Handle async code
    - Puts queued callbacks onto
    the call stack
    - In Node, provided by libuv
    - Not part of V8
    - Not part of JS

    View Slide

  45. libuv

    View Slide

  46. libuv
    more than an event loop
    - Open source
    - Created for node
    - Wrapper around libev
    - Provides
    - Event loop
    - TCP & UDP
    - DNS Resolution
    - FS Events
    - IPC and Child processes
    - Thread pool
    - More...

    View Slide

  47. View Slide

  48. callback queues_

    View Slide

  49. View Slide

  50. async callback function

    View Slide

  51. Call Stack Ext. APIs
    CB queue

    View Slide

  52. Call Stack Ext. APIs
    CB queue
    console.log('Starting')

    View Slide

  53. Call Stack Ext. APIs
    CB queue
    console.log('Starting')
    Starting

    View Slide

  54. Call Stack Ext. APIs
    CB queue

    View Slide

  55. Call Stack Ext. APIs
    CB queue
    fs.readFile(fp, cb)

    View Slide

  56. Call Stack Ext. APIs
    CB queue
    fs.readFile(fp, cb)
    file cb

    View Slide

  57. Call Stack Ext. APIs
    CB queue
    file cb

    View Slide

  58. Call Stack Ext. APIs
    CB queue
    file cb
    console.log('Ending')

    View Slide

  59. Call Stack Ext. APIs
    CB queue
    console.log('Ending')
    Starting
    Ending
    cb

    View Slide

  60. later does not mean "later"

    View Slide

  61. Call Stack Ext. APIs
    CB queue
    cb

    View Slide

  62. Call Stack Ext. APIs
    CB queue
    cb(err, data)

    View Slide

  63. Call Stack Ext. APIs
    CB queue
    cb(err, data)
    console.log(data.toS())

    View Slide

  64. Call Stack Ext. APIs
    CB queue
    Starting
    Ending
    The file contents
    cb(err, data)
    console.log(data.toS())

    View Slide

  65. Call Stack Ext. APIs
    CB queue
    cb(err, data)

    View Slide

  66. Call Stack Ext. APIs
    CB queue

    View Slide

  67. microtasks and macrotasks_

    View Slide

  68. microtask queue

    View Slide

  69. microtasks
    - process.nextTick
    - Promises
    - Object.observe

    View Slide

  70. macrotask queue

    View Slide

  71. macrotasks
    - setTimeout
    - setInterval
    - setImmediate
    - any I/O operation

    View Slide

  72. what would happen?

    View Slide

  73. Call Stack Ext. APIs
    CB queue
    Job queue
    console.log('start')

    View Slide

  74. Call Stack Ext. APIs
    CB queue
    Job queue
    console.log('start')
    start

    View Slide

  75. Call Stack Ext. APIs
    CB queue
    Job queue

    View Slide

  76. Call Stack Ext. APIs
    CB queue
    Job queue
    setTimeout('t1',0)

    View Slide

  77. Call Stack Ext. APIs
    CB queue
    Job queue
    setTimeout('t1',0)
    timer cb1

    View Slide

  78. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb1

    View Slide

  79. Call Stack Ext. APIs
    CB queue
    Job queue
    setTimeout('t2',0)
    timer cb1

    View Slide

  80. Call Stack Ext. APIs
    CB queue
    Job queue
    setTimeout('t2',0)
    timer cb1
    timer cb2

    View Slide

  81. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb1
    timer cb2

    View Slide

  82. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb2
    .then(console.log)
    cb1

    View Slide

  83. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    setTimeout('t3',0)
    cb1 cb2

    View Slide

  84. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb3
    handle
    setTimeout('t3',0)
    cb1 cb2

    View Slide

  85. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    .then(fn)
    cb1 cb2 cb3

    View Slide

  86. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    .then(fn)
    fn cb1 cb2 cb3

    View Slide

  87. Call Stack Ext. APIs
    CB queue
    Job queue
    handle fn cb1 cb2 cb3

    View Slide

  88. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    fn cb1 cb2 cb3

    View Slide

  89. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    fn
    setTimeout('tp',0)
    cb1 cb2 cb3

    View Slide

  90. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb4
    handle
    fn
    setTimeout('tp',0)
    cb1 cb2 cb3

    View Slide

  91. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb4
    handle
    fn cb1 cb2 cb3

    View Slide

  92. Call Stack Ext. APIs
    CB queue
    Job queue
    timer cb4
    fn cb1 cb2 cb3

    View Slide

  93. Call Stack Ext. APIs
    CB queue
    Job queue
    fn
    cb1 cb2 cb3
    cb4

    View Slide

  94. Call Stack Ext. APIs
    CB queue
    Job queue
    fn
    console.log('promise')
    cb1 cb2 cb3
    cb4

    View Slide

  95. Call Stack Ext. APIs
    CB queue
    Job queue
    fn
    console.log('promise')
    start
    promise
    cb1 cb2 cb3
    cb4

    View Slide

  96. Call Stack Ext. APIs
    CB queue
    Job queue
    fn
    cb1 cb2 cb3
    cb4

    View Slide

  97. Call Stack Ext. APIs
    CB queue
    Job queue
    cb1 cb2 cb3
    cb4

    View Slide

  98. Call Stack Ext. APIs
    CB queue
    Job queue
    cb2 cb3
    cb4
    cb1

    View Slide

  99. Call Stack Ext. APIs
    CB queue
    Job queue
    cb2 cb3
    cb4
    cb1
    console.log('timeout')

    View Slide

  100. Call Stack Ext. APIs
    CB queue
    Job queue
    cb2 cb3
    cb4
    cb1
    console.log('timeout')
    start
    promise
    timeout

    View Slide

  101. Call Stack Ext. APIs
    CB queue
    Job queue
    cb2 cb3
    cb4
    cb1

    View Slide

  102. Call Stack Ext. APIs
    CB queue
    Job queue
    cb2 cb3
    cb4

    View Slide

  103. Call Stack Ext. APIs
    CB queue
    Job queue
    cb3
    cb4
    cb2

    View Slide

  104. Call Stack Ext. APIs
    CB queue
    Job queue
    cb3
    cb4
    cb2
    console.log('timeout2')

    View Slide

  105. Call Stack Ext. APIs
    CB queue
    Job queue
    cb3
    cb4
    cb2
    console.log('timeout2')
    start
    promise
    timeout
    timeout2

    View Slide

  106. Call Stack Ext. APIs
    CB queue
    Job queue
    cb3
    cb4
    cb2

    View Slide

  107. Call Stack Ext. APIs
    CB queue
    Job queue
    cb3
    cb4

    View Slide

  108. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4
    cb3

    View Slide

  109. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4
    cb3
    console.log('timeout3')

    View Slide

  110. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4
    cb3
    console.log('timeout3')
    start
    promise
    timeout
    timeout2
    timeout3

    View Slide

  111. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4
    cb3

    View Slide

  112. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4

    View Slide

  113. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4

    View Slide

  114. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4
    console.log('p timeout')

    View Slide

  115. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4
    console.log('p timeout')
    start
    promise
    timeout
    timeout2
    timeout3
    promise timeout

    View Slide

  116. Call Stack Ext. APIs
    CB queue
    Job queue
    cb4

    View Slide

  117. Call Stack Ext. APIs
    CB queue
    Job queue

    View Slide

  118. V8

    View Slide

  119. V8
    the golden compiler
    - Made by Google
    - open source
    high-performance
    - JS and WebAsm engine
    - Written in C++
    - Implements ES fully
    - Can be standalone

    View Slide

  120. abstract syntax tree_

    View Slide

  121. AST of readFile (part)

    View Slide

  122. hidden classes_

    View Slide

  123. View Slide

  124. View Slide

  125. View Slide

  126. C2

    View Slide

  127. property order matters_

    View Slide

  128. V8 pipelines_

    View Slide

  129. AoT vs JiT

    View Slide

  130. old compiler pipeline_

    View Slide

  131. Full-Codegen

    View Slide

  132. FCG compiler
    fast, but not that good
    - First step of the pipeline
    - Simple and fast
    - Not-optimised, relatively
    slow
    - Handles type-feedback,
    finds hot functions
    - Takes the AST and generate
    generic native code

    View Slide

  133. Crankshaft

    View Slide

  134. Crankshaft
    compiler
    good, but not that fast
    - Takes type-feedback from
    FCG
    - Optimises code accordingly
    - Replaces not-opt code with
    optimised code using OSR
    - Does not implement all ES
    - Made of two components
    - Hydrogen
    - Lithium

    View Slide

  135. new compiler pipeline_

    View Slide

  136. new compiler pipeline

    View Slide

  137. TurboFan

    View Slide

  138. TurboFan
    Crankshaft, the right way
    - Started as a secondary
    compiler for ES6
    - Designed to be a webasm
    compiler
    - Uses a sea of nodes
    - Receives bytecodes directly
    - Divided in layers
    - Frontend
    - Optimising Layer
    - Backend
    - Fixed deoptimisation cliffs

    View Slide

  139. mixed old pipeline

    View Slide

  140. current pipeline

    View Slide

  141. Ignition

    View Slide

  142. Ignition
    an interpreter to rule them all
    - JS Interpreter
    - Generates optimised
    bytecode
    - Created to reduce memory
    usage
    - Focused on low memory
    devices (cell phones)
    - NOT a parser
    - AST not source of truth
    anymore
    - Uses Turbofan's backend

    View Slide

  143. ignition pipeline_

    View Slide

  144. View Slide

  145. bytecodes

    View Slide

  146. bytecodes are middle-class representations

    View Slide

  147. node --print-bytecode --print-bytecode-filter=f index.js

    View Slide

  148. putting it all together_

    View Slide

  149. View Slide

  150. generated bytecode for readFileAsync

    View Slide

  151. Goes through this pipeline

    View Slide

  152. Call Stack Ext. APIs
    CB queue
    Job queue

    View Slide

  153. Call Stack Ext. APIs
    CB queue
    Job queue
    path.resolve

    View Slide

  154. Call Stack Ext. APIs
    CB queue
    Job queue

    View Slide

  155. Call Stack Ext. APIs
    CB queue
    Job queue
    IIFE

    View Slide

  156. Call Stack Ext. APIs
    CB queue
    Job queue
    IIFE
    readFileAsync

    View Slide

  157. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    IIFE

    View Slide

  158. Call Stack Ext. APIs
    CB queue
    Job queue
    handle

    View Slide

  159. Call Stack Ext. APIs
    CB queue
    Job queue
    handle

    View Slide

  160. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    readFile

    View Slide

  161. Call Stack Ext. APIs
    CB queue
    Job queue
    handle
    file cb

    View Slide

  162. Call Stack Ext. APIs
    CB queue
    Job queue
    cb

    View Slide

  163. Call Stack Ext. APIs
    CB queue
    Job queue
    cb

    View Slide

  164. Call Stack Ext. APIs
    CB queue
    Job queue
    cb
    resolve

    View Slide

  165. Call Stack Ext. APIs
    CB queue
    Job queue
    cb
    resolve
    callback

    View Slide

  166. Call Stack Ext. APIs
    CB queue
    Job queue
    cb
    resolve
    callback
    toString()

    View Slide

  167. Call Stack Ext. APIs
    CB queue
    Job queue
    cb
    resolve
    callback

    View Slide

  168. Call Stack Ext. APIs
    CB queue
    Job queue
    cb
    resolve

    View Slide

  169. Call Stack Ext. APIs
    CB queue
    Job queue
    cb

    View Slide

  170. Call Stack Ext. APIs
    CB queue
    Job queue
    cb
    console.log

    View Slide

  171. Call Stack Ext. APIs
    CB queue
    Job queue
    cb

    View Slide

  172. Call Stack Ext. APIs
    CB queue
    Job queue

    View Slide

  173. references_
    - All references are in this guide: bit.ly/node-under-the-hood

    View Slide

  174. references_
    - https://dev.to/khaosdoctor/node-js-under-the-hood-1-getting-to-know-our-tools-1465
    - https://dev.to/khaosdoctor/node-js-under-the-hood-2-understanding-javascript-48cn
    - https://dev.to/khaosdoctor/node-js-under-the-hood-3-deep-dive-into-the-event-loop-135d
    - https://dev.to/khaosdoctor/node-js-under-the-hood-4-let-s-talk-about-v8-1eol
    - https://dev.to/khaosdoctor/node-js-under-the-hood-5-hidden-classes-variable-allocations-1244
    - https://dev.to/khaosdoctor/node-js-under-the-hood-6-the-old-v8-34hm
    - https://dev.to/khaosdoctor/node-js-under-the-hood-7-the-new-v8-4gd6
    - https://dev.to/khaosdoctor/node-js-under-the-hood-8-oh-the-bytecodes-1p6p
    - https://dev.to/khaosdoctor/node-js-under-the-hood-9-collecting-the-garbage-772

    View Slide

  175. thank you :D
    /khaosdoctor @_staticvoid
    lsantos.dev
    /khaosdoctor

    View Slide