V8 Engine

About

V8 ์—”์ง„์€ ๊ตฌ๊ธ€์—์„œ ๊ฐœ๋ฐœํ•œ ๊ณ ์„ฑ๋Šฅ ์˜คํ”ˆ์†Œ์Šค C++๋กœ ์ž‘์„ฑ๋œ JavaScript ๋ฐ WebAssembly ์—”์ง„์ด๋‹ค.

  • Chrome ๋ฐ Node.js์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

  • ECMAScript์™€ WebAssembly๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

์žฌ๋ฐŒ๋Š” ์ ์€ V8์€ ์›๋ž˜ 8๊ธฐํ†ต ์—”์ง„์˜ ์ข…๋ฅ˜๋ฅผ ์˜๋ฏธํ•˜๋Š” ๋‹จ์–ด์ด๊ธฐ๋„ ํ•˜๋‹ค. ๋˜ํ•œ, ๋‚ด๋ถ€์ ์œผ๋กœ ์—”์ง„ ๊ด€๋ จ ์šฉ์–ด๋“ค(Ignition ๋“ฑ)์ด ์‚ฌ์šฉ๋œ๋‹ค.

Flow

  1. ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ JavaScript ์ฝ”๋“œ๋กœ๋ถ€ํ„ฐ ํŒŒ์„œ(Parser)๋ฅผ ํ†ตํ•ด ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ(AST; Abstract Syntax Tree)๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.

  2. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ์ธ Ignition์— AST๋ฅผ ๋„˜๊ธฐ๊ฒŒ ๋œ๋‹ค.

    ์ปดํ“จํ„ฐ๊ฐ€ ํ•ด์„ํ•˜๊ธฐ ์‰ฌ์šด ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•จ์œผ๋กœ์จ ์›๋ณธ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํŒŒ์‹ฑ(Parsing)ํ•ด์•ผ๋˜๋Š” ์ˆ˜๊ณ ๋ฅผ ๋œ๊ณ , ์ฝ”๋“œ์˜ ์–‘๋„ ์ค„์ด๋ฉด์„œ ์ฝ”๋“œ ์‹คํ–‰ ๋•Œ ์ฐจ์ง€ํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์•„๋‚„ ์ˆ˜ ์žˆ๋‹ค.

  3. ์ดํ›„ ์ด ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ V8 ์—”์ง„์ด ์‹คํ–‰ํ•˜๋ฉด์„œ ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋œ๋‹ค. ๊ทธ ์ค‘์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ๋Š” TurboFan์œผ๋กœ ๋ณด๋‚ด์ ธ์„œ ์ตœ์ ํ™”๋œ ์ฝ”๋“œ(Optimized Machine Code)๋กœ ๋‹ค์‹œ ์ปดํŒŒ์ผ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ์‚ฌ์šฉ์ด ๋œ ๋œ๋‹ค ์‹ถ์œผ๋ฉด ๋‹ค์‹œ Deoptimizingํ•˜๊ฒŒ ๋œ๋‹ค.

Parsing (AST Generation)

์œ„์—์„œ ๋งํ–ˆ๋‹ค์‹œํ”ผ ํŒŒ์‹ฑ(Parsing)์ด๋ž€ ์†Œ์Šค์ฝ”๋“œ๋กœ๋ถ€ํ„ฐ ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ(AST; Abstract Syntax Tree)๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.

  • ํ‘œํ˜„์‹ ๋“ฑ์—์„œ ํ† ํฐ์„ ์ถ”์ถœํ•ด + ์—ฐ์‚ฐ์ž ๊ฐ™์€ ๊ฒƒ์„ ๋งŒ๋‚˜๋ฉด Token::ADD ๋“ฑ์œผ๋กœ ๊ฒ€์‚ฌํ•ด ์กฐ๊ฑด์— ๋งž๊ฒŒ ํŒŒ์‹ฑํ•œ๋‹ค.

  • ์ด ๊ณผ์ •์—์„œ ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ์กฐ๊ฑด๋ฌธ ๋“ฑ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ์˜ ์˜๋ฏธ๋ฅผ ํŒŒ์•…ํ•˜๊ณ , ๋ฒ”์œ„(Scope)๋ฅผ ์„ค์ •ํ•œ๋‹ค.

  • ์ด ๊ณผ์ •์„ C++๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค.

Ignition (Byte Code Generation)

๋ฐ”์ดํŠธ ์ฝ”๋“œ๋Š” ๊ธฐ๊ณ„์–ด(0101010...)์ด ์•„๋‹ˆ๋ผ, ๊ณ ๊ธ‰ ์–ธ์–ด(JavaScript)๋กœ ์ž‘์„ฑ๋œ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๊ธฐ๊ณ„์–ด๋กœ ๋ฐ”๊พธ๊ธฐ ์ „์— ์ค‘๊ฐ„ ์ฝ”๋“œ๋กœ ํ•œ๋ฒˆ ์ปดํŒŒ์ผํ•œ ๊ฒฐ๊ณผ๋ฌผ์ด๋‹ค.

V8 ์—”์ง„์—์„œ๋Š” Ignition์„ ํ†ตํ•ด JavaScript ์ฝ”๋“œ๊ฐ€ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

Ignition์ด๋ž€ ๊ธฐ์กด V8 ์—”์ง„์˜ Full-codegen์„ ๋Œ€์ฒดํ•˜๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ์ด๋‹ค.

Full-codegen์€ ์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ์— ์ปดํŒŒ์ผํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ ์ ์œ ์œจ์ด ๋†’์•˜๋‹ค. ๋˜ํ•œ JavaScript๋Š” C++๊ณผ ๊ฐ™์€ ์ •์  ํƒ€์ดํ•‘ ์–ธ์–ด๊ฐ€ ์•„๋‹Œ ๋™์  ํƒ€์ดํ•‘ ์–ธ์–ด๋ผ์„œ ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „๊นŒ์ง€ ์•Œ ์ˆ˜ ์—†๋Š” ๊ฐ’๋“ค์ด ๋„ˆ๋ฌด ๋งŽ์•„์„œ ์ตœ์ ํ™”ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ๋‹ค๊ณ  ํ•œ๋‹ค.

Ignition์€ ์ฝ”๋“œ ํ•œ์ค„ ํ•œ์ค„์ด ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ํ•ด์„ํ•˜๋Š” "์ธํ„ฐํ”„๋ฆฌํ„ฐ" ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜์—ฌ ์„ธ ๊ฐ€์ง€ ์ด์ ์„ ๊ฐ€์ ธ๊ฐ€๊ณ ์ž ํ–ˆ๋‹ค.

  1. ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๊ฐ์†Œ - JS -> ๊ธฐ๊ณ„์–ด๋ณด๋‹ค ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒƒ์ด ๋” ํŽธํ•˜๋‹ค.

  2. Parsing ๊ฐ„ ์˜ค๋ฒ„ํ—ค๋“œ ๊ฐ์†Œ - ๋ฐ”์ดํŠธ์ฝ”๋“œ๋Š” ๊ฐ„๊ฒฐํ•˜๋ฏ€๋กœ ๋‹ค์‹œ ํŒŒ์‹ฑํ•˜๊ธฐ ํŽธํ•˜๋‹ค.

  3. ์ปดํŒŒ์ผ Pipeline ๋ณต์žก์„ฑ ๊ฐ์†Œ - Optimizing / Deoptimizing ๋‘˜ ๋‹ค ๋ฐ”์ดํŠธ์ฝ”๋“œ๋งŒ ์‹ ๊ฒฝ์“ฐ๋ฉด ๋˜๋ฏ€๋กœ ํŽธํ•˜๋‹ค.

node ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ --print-bytecode ์˜ต์…˜์„ ๋„˜๊ฒจ์ฃผ๋ฉด ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ์ธํ„ฐํ”„๋ฆฌํŒ… ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

$ node --print-bytecode some-file.js

V8 ์—”์ง„์€ ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ JavaScript ์ฝ”๋“œ๋ฅผ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ์ „๋ถ€ ๋ณ€ํ™˜ํ•ด ๋†“๊ธฐ ๋•Œ๋ฌธ์—, ์ฒ˜์Œ์—๋Š” ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋”๋ผ๋„ ๊ทธ ์ดํ›„์—๋Š” ์ปดํŒŒ์ผ ์–ธ์–ด์™€ ๊ฐ€๊นŒ์šด ์„ฑ๋Šฅ์„ ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค.

TurboFan

TurboFan์€ V8 ์—”์ง„ v5.9๋ถ€ํ„ฐ ๊ธฐ์กด์— ์‚ฌ์šฉ๋˜๋˜ CrankShaft ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ์ตœ์ ํ™” ๋‹ด๋‹น ์ปดํŒŒ์ผ๋Ÿฌ์ด๋‹ค.

์ฒ˜์Œ V8์ด ๋‚˜์˜จ ๋’ค๋กœ ์ƒˆ๋กœ์šด ์ปดํ“จํ„ฐ ์•„ํ‚คํ…์ฒ˜๋„ ๋“ฑ์žฅํ•˜๊ณ  JavaScript๋„ ์ง€์†์ ์œผ๋กœ ๋ฐœ์ „ํ•ด์„œ V8๋„ ์ง€์›์„ ๊ณ„์†ํ–ˆ๋‹ค. V8 ํŒ€์€ ์ƒˆ๋กœ์šด ์‚ฌ์–‘์— ๋งž์ถฐ V8์„ ์ง€์†์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ด์ค˜์•ผ ํ–ˆ๋Š”๋ฐ, ๊ฒฐ๊ตญ Crankshaft์˜ ๊ตฌ์กฐ๋กœ๋Š” ์ง€์†์  ํ™•์žฅ์ด ์–ด๋ ต๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€๊ณ , ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด๋กœ ๊ณ„์ธตํ™”ํ•˜์—ฌ ์ข€ ๋” ํ™•์žฅ์— ์šฉ์ดํ•œ TurboFan์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

  • Crankshaft๋กœ๋Š” 13,000~16,000์ค„์˜ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ–ˆ๋˜ ๊ฑธ TurboFan์œผ๋กœ ์˜ฎ๊ฒผ๋”๋‹ˆ 3,000์ค„ ๋ฏธ๋งŒ์˜ ์ฝ”๋“œ๋กœ ์ปค๋ฒ„๊ฐ€ ๊ฐ€๋Šฅํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

V8 ์—”์ง„์€ ๋Ÿฐํƒ€์ž„์—์„œ Profiler์—๊ฒŒ ํ•จ์ˆ˜๋‚˜ ๋ณ€์ˆ˜์˜ ํ˜ธ์ถœ ๋นˆ๋„ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ์œผ๊ฒŒ ํ•˜๊ณ , ์ด๋ ‡๊ฒŒ ๋ชจ์ธ ๋ฐ์ดํ„ฐ๋ฅผ TurboFan์—๊ฒŒ ๊ฐ€์ ธ๊ฐ€๋ฉด TurboFan์ด ์ตœ์ ํ™”ํ•˜๋„๋ก ํ•œ๋‹ค.

์ตœ์ ํ™” ๊ธฐ๋ฒ•์œผ๋กœ๋Š” ๋น„์Šทํ•œ ๊ฒƒ๋ผ๋ฆฌ ๋ถ„๋ฅ˜ํ•ด ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ํžˆ๋“  ํด๋ž˜์Šค(Hidden Class), ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•จ์ˆ˜์˜ ๋‚ด์šฉ์œผ๋กœ ๋ฐ”๊ฟ”๋ฒ„๋ฆฌ๋Š” ์ธ๋ผ์ธ ์บ์‹ฑ(IC; Inline Caching) ๋“ฑ์ด ์žˆ๋‹ค.

์ตœ์ ํ™” ๊ธฐ์ค€์€ ์ฝ”๋“œ๊ฐ€ ๋œจ๊ฒ๊ณ (์ž์ฃผ ํ˜ธ์ถœ๋˜๊ณ ) ์•ˆ์ •์ (์ฝ”๋“œ๊ฐ€ ์•ˆ ๋ณ€ํ•จ)์ด๊ฑฐ๋‚˜(kHotAndStable), ์ธํ„ฐํ”„๋ฆฌํŒ…๋œ ๋ฐ”์ดํฌ ์ฝ”๋“œ์˜ ๊ธธ์ด๊ฐ€ ํŠน์ • ์ž„๊ณ„์ ์„ ๋„˜์ง€ ์•Š์œผ๋ฉด ์ž‘์€ ํ•จ์ˆ˜(kSmallFunction)๋กœ ํŒ๋‹จํ•ด ์ตœ์ ํ™”๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

์ด ๋ถ€๋ถ„์€ v8/src/execution/runtime-profiler.cc์— ์ •์˜๋˜์–ด ์žˆ์—ˆ๋Š”๋ฐ ์ง€๊ธˆ์€ ํฉ์–ด์ง„ ๋“ฏ ํ•˜๋‹ค.

node๋ฅผ ์‹คํ–‰ํ•  ๋•Œ --trace-opt ์˜ต์…˜์„ ์ฃผ๋ฉด TurboFan์ด ์ตœ์ ํ™” ์ž‘์—… ๋“ฑ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

$ node --trace-opt some-file.js

REF

Last updated