4 min read

v8 엔진 컴파일러

이글은 http://jayconrod.com/posts/51/a-tour-of-v8–full-compiler 해당 글을 번역한 포스트입니다.

적어도 2010년부터 5년간 자바스크립트는 JIT 컴파일러로 변화자마자 성능이 비약적으로 상승했여 웹에 전형적으로 사용하게 되었다.

그 결과 자바스크립트는 HTML5를 이끌고 있게 되었다. V8엔진은 자바스크립트를 네거티브한 코드로 실행한다.

이를 이용한것이 구글 크롬,node js이다.

V8엔진은 정말 흥미롭지만 아쉽게 문서가 많이 없어 제작하게 되었다.

해당 내용은 가상머신이나 컴파일러에게 관심있는 사람에게 흥미로운 내용을 작성하였다.

고 수준의 아키텍처

v8 컴파일러는 자바스크립트를 실행하기전에 네거티브 코드를 컴파일한다. 컴파일 할때 바이트코드같은 해석은 존재 하지않는다.

컴파일은 단 한번만 실행된다. 일반적으로 코드를 처음 호출 될때까지 컴파일을 하지않아 큰 라이브러리를 추가해도 사용하지않은 부분은 컴파일을 안하기 때문에 빠르게 실행되게 됩니다.

자바스크립트에는 두개의 컴파일러가 있는데, 나는 간단한 컴파일러와 헬퍼(helper) 컴파일러로 생각한다.

Full 컴파일러는 최적화 하지않은 컴파일인데 이는 빠르게 네이티브 코드를 생성하여 페이지 로딩시간을 빠르게 로딩하게 만들어 준다.

Crankshaft  컴파일은 최적화 컴파일이다. v8 엔진은 맨처음에 Full 컴파일은 한뒤에 Crankshaft 은 내장 프로파일러를 활용해 가장 빠르게 실행할수 있도록 컴파일을 한다.

또한 v8은 대부분 싱글 스레드로 구동되어 있어서 컴파일러가 하나가 구동되면 실행을 중지한다.

결과적으로 Crankshaft 과 Full은 최적화된 코드를 생성하는 대신 빠르게 네거티브 코드를 생성하도록 설계되어 있다.

향후 v8엔진은 두가지의 컴파일을 각각의 스레드로 동시에 실행하게 될것이다.

왜 byte 코드는 아닌가?

대부분의 VM에는 바이트 코드 인터럽트가 있지만 V8엔진에는 이 기능이 빠져있다.

읽는 독자분들은 바이트코드로 컴파일하여 실행하는것이 더 쉬운경우가 있는데 왜 full 컴파일을 하는지 궁금해 할수 있다.

최적화 되지않은 네이티브 코드를 컴파일하는 것은 바이트코드로 만드는것보다 작기 때문이다. 두개를 한번 비교해보자.

바이트코드 컴파일

  • Syntax analysis (parsing)
  • Scope analysis
  • Translate syntax tree to bytecode

네거티브 컴파일

  • Syntax analysis (parsing)
  • Scope analysis
  • Translate syntax tree to native

컴파일 방식이 다를뿐이지 두 경우 모두 소스 코드를 분석하고 추상 트리(AST)를 생성해야한다. 또한 각 기호가 로컬 변수인지 글로벌 변수인지 여부도 수행해야한다.

물론 빠르게 실행할수 있을수 있지만 빠르게 실행되기 위해 컴파일라가 직접 컴파일을 해야한다

한번 바이트 코드를 컴파일 할경우를 생각해보자.

예로 바이트코드 인터럽트의 코드를 작성한다고 생각해보자. 내부적으로 그 다음의 바이트코드를 가져오는 반복으로 구현할것이고

많은 조건문과 순서대로 코드를 실행할것이다. http://wingolog.org/archives/2012/06/27/inside-javascriptcores-low-level-interpreter 에 다양한 방법이 있지만

기본적으로 같은 구조이다.

일반적으로 바이트 코드는 컴파일러의 일부 작업을 미리 할수 있는경우 유리하다. 하지만 웹 브라우저가 아니여서 full컴파일러는 v8에 맞다.

인 라인 캐시 : 최적화하지 않은 코드

작성중..