2. JavaScript engines how do they even? | Franziska Hinkelmann
수정일: 2025. 6. 6.
hidden class를 아시나요
V8의 Hidden Class 생성과 디버깅
1. 이 글의 전 글
- 본 포스트는 1편 번역본의 내용을 보충 설명합니다.
- 보충 설명은 코드 스니펫을 통해 진행됩니다.
1편을 통해 우리는 자바스크립트가 여러 엔진(V8, SpiderMonkey, Chakra 등)을 통해 실행되고 있으며,
그중 가장 대중적인 V8 엔진의 JIT compile
, hot function
,
인터프리터인 Ignition
, 최적화 컴파일러인 TurboFan
까지 알아보았습니다.
이번 글에서는 위 내용들을 바탕으로 V8이 내 코드를 더 빠르게, 더 효율적으로 hot function으로 인식하게 하려면
코드를 어떻게 작성해야 하는지를 알아보겠습니다.
V8의 Ignition 파이프라인
출처: Firing up the Ignition interpreter, V8 Blog, 2016
최근에는 Full codegen과 Crankshaft가 제거되었습니다.
현재 기준으로:
Ignition
은 JS 코드를 바이트코드로 변환하고 해석하여 실행합니다.TurboFan
은 최적화를 통해 Hot Code를 네이티브 코드(Machine Code) 로 변환합니다.
function add(x, y) {
return x + y;
}
⬆️ 위 코드는 아래와 같은 어셈블리 코드로 변환됩니다. ⬇️
mov eax, edi ; x 값을 eax 레지스터에 저장
add eax, esi ; y 값을 eax에 더함
ret ; 결과를 반환
V8의 Hidden Class
Hidden Class
는 Ignition에 타입 힌트를 제공하여 Hot Function으로 최적화되기 쉽게 도와줍니다.
JS는 인터프리터 언어이기 때문에 기본적으로 느릴 수밖에 없고,
V8은 이런 구조를 최적화하기 위해 Hidden Class
를 사용합니다.
Hidden Class = 보이지 않는 클래스, 객체의 구조(Object Shape)를 담고 있음
Hidden Class 예시
출처: JavaScript engines how do they even? - Franziska Hinkelmann
var obj0 = {};
obj0.x = 1;
obj0.y = 2;
var obj1 = { x: 3, y: 4 };
obj0
은 빈 객체 → x 속성 추가 → y 속성 추가로 shape가 점진적으로 변경됨obj1
은{x, y}
속성을 리터럴로 한 번에 정의하므로 전혀 다른 Hidden Class를 가짐
var obj2 = { x: 1, y: 2 };
var obj3 = { x: 3, y: 4 };
obj2
,obj3
은 같은 속성 순서로 선언되었기 때문에 같은 Hidden Class를 공유함
Hidden Class 디버깅
V8은 --allow-natives-syntax
플래그를 통해 내부 정보를 볼 수 있습니다.
var obj0 = {};
obj0.x = 1;
obj0.y = 2;
var obj1 = { x: 3, y: 4 };
%DebugPrint(obj0);
%DebugPrint(obj1);
예상 출력:
DebugPrint: 0x167bfc5de359: [JS_OBJECT_TYPE]
- map: 0x00cd097de2c1 <Map[56](HOLEY_ELEMENTS)> [FastProperties]
DebugPrint: 0x167bfc5de409: [JS_OBJECT_TYPE]
- map: 0x00cd097de351 <Map[40](HOLEY_ELEMENTS)> [FastProperties]
- 각 객체의
map
은 Hidden Class의 메모리 주소 obj0
과obj1
은 서로 다른 Hidden Class
또 다른 예:
var obj2 = { x: 1, y: 2 };
var obj3 = { x: 3, y: 4 };
%DebugPrint(obj2);
%DebugPrint(obj3);
예상 출력:
DebugPrint: 0x33cbd86de349: [JS_OBJECT_TYPE]
- map: 0x35c0490de301 <Map[40](HOLEY_ELEMENTS)> [FastProperties]
DebugPrint: 0x33cbd86de3e9: [JS_OBJECT_TYPE]
- map: 0x35c0490de301 <Map[40](HOLEY_ELEMENTS)> [FastProperties]
obj2
와obj3
는 같은 Hidden Class를 공유
Hidden Class를 맞추는 예제
function readX(obj) {
return obj.x;
}
var a = { x: 1 };
var t = { o: 2 };
readX(a);
readX(t); // 최적화 깨짐
위 코드는 t
에 x
속성이 없어 Hidden Class가 다르고,
V8 최적화(TurboFan)가 꺼질 수 있음.
개선 예시:
var t = { x: undefined, o: 2 };
- 이렇게 하면 a, t가 같은 Hidden Class를 공유할 수 있음
- 성능 최적화에 도움이 됨.
요약
- V8은 객체의 구조(Shape)를 Hidden Class로 관리함
- 같은 Hidden Class를 유지하면 JIT 최적화(TurboFan) 에 유리함
- 함수에 넘기는 객체는 가능한 한 같은 구조로 생성하는 것이 좋음
- 의도적으로 shape을 맞추는 방식은 성능상 이점이 있음
- 단, 코드의 가독성과 유지보수성이 희생되지 않는 범위에서만 적용해야 함