상세 컨텐츠

본문 제목

자바스크립트 interpreter/compiler pipeline

Front-End/Javascript

by devloper-jun 2024. 9. 25. 16:09

본문

- 자바스크립트의 컴파일 과정을 살펴보기 전에 컴파일 언어인 C 언어의 컴파일 과정을 알아봄.

1. compile 언어의 compile 과정 (EX. C 언어)

 1-1. preprocessor (전처리기)

  : # 이 앞에오는 소스 코드를 처리하며(preprocessing directives) 주석제거, stdio.h 같은 헤더 파일을 코드 상으로 필요한 내용으로 채워주고 define으로 먼저 정의된 상수를 symbol table에 저장 등 매크로를 확장 및 치환하며 전처리된 코드로 변환. (*.c -> *.i)

 

 1-2. compile

  : 전처리된 소스 코드를 어셈블리어 코드로 변환하며 언어의 문법 검사, static 영역의 메모리 할당하며 front-end -> middle-end -> back-end(compiler 마다 차이가 있으며, gcc는 명확한 구분이 아닌 의존성 존재, Clang(front) + LLVM(middle, back)는 구분이 명확)로 구성되며 해당 과정을 거쳐 사람이 이해할 수 있게 부호화된 언어인 assembly code(CPU 명령어인 기계어와 1:1로 매칭)로 변환.(*.i -> *.s)

  • front-end : 언어의 종속적인 부분을 처리하며 언어의 문법 검사, middle end로 넘겨주기 위한 GIMPLE Tree (소스 코드를 트리 형태로 표현한 자료구조)를 생성. IR(intermediate representation, 공통된 중간 표현)인 GIMPLE Tree 변환 되므로 언어의 종속적인 부분을 처리가능.
  • middle-end: GIMPLE Tree 이용해 아키텍쳐 비종속적인 최적화(CPU 아키텍쳐와 무관하게 할 수 있는 최적화)를 수행 후 RTL(Register Transfer Language, 고급 언어와 어셈블리 언어의 중간형) 을 생성.
  • back-end: 아키텍쳐 종속적인 최적화(CPU 아키텍쳐별 효율적인 명령어로 대체하여 성능 향상)를 수행

 1-3. assembler

 : 사람이 알아볼 수 없는 기계어로 변환. (*.s -> *.o)

  • 오브젝트 파일: object code로 구성된 파일로 window-PE(Portable Executable), Linux-ELF(Executable and Linking Format)로 나눠짐.

  • 링커의 역할: symbol resolution(심볼 해석), Relocation(재배치)로 크게 구분 지을 수 있으며, 심볼 해석은 심볼 참조를 어떤 심볼 정의에 연관시킬지 정하는 과정. 재배치는 오브젝트 파일 안에 있는 데이터의 주소나 코드의 메모리 참조 주소를 알맞게 배치하는 과정이다. 링커가 컴파일러가 생성한 오브젝트 파일을 모아서 하나의 실행가능한 파일을 만들 때, 각 오브젝트 파일에 있는 데이터의 주소나 코드의 메모리 참조 주소가 링커에 의해 합쳐진 실행 파일에서의 주소과 다르기 때문에 올바르게 수정해줘야 하며, 이를 위해서 오브젝트 파일안에는 Relocation information section이 존재.

2. 자바스크립트의 compile 과정

- V8 엔진 이후 profiler의 등장으로 interpreter를 관찰하며 실행되는 코드를 계속해서 모니터링 하며 코드내 반복 실행되는 것이 있다면 컴파일러에게 넘겨 실시간으로 컴파일을 수행하며 바이트 코드를 생성해 낸다. 이를 JITC(just-in-time compilation) 라고 한다. 필요한 경우 decompile 과정을 통해 컴파일러가 컴파일하려고 했던 판단을 되돌려 컴파일 비용을 줄임.

 

2024.09.25 - [Front-End/Javascript] - AST(Abstract Syntax Tree, 추상 구문 트리)

관련글 더보기