V8 가비지 컬렉션을 공부하다가, 이게 맞나란 생각을 좀 많이 하면서 V8이 무엇인지 좀 자세히 알아보기 위해 A tour of V8: full compiler를 번역하여서 공부해보고자 한다. 번역하다가 이해하기 쉽게 가감한 면이 있지만 이해가 잘 되었으면 좋겠다.


코드를 JavaScript 가상 머신에서 해석하다 JIT(Just-In-Time) 컴파일로 전환되면서 성능이 엄청나게 빠르게 증가했다. 이로 인해 JavaScript와 웹 앱의 유용성이 크게 증가했다. 그 결과, JavaScript는 이제 HTML5, 즉 웹 기술의 다음 세대를 이끄는 메인이 되었다. 네이티브 코드를 생성하고 실행하는 최초의 자바스크립트 엔진 중 하나인 V8 엔진은 구글 크롬, 안드로이드 브라우저, WebOS 및 Node.js와 같은 다른 프로젝트에서 사용된다.

글쓴이는 ARM 마이크로아키텍처에 맞게 V8 최적화하는 팀에 참여하여 SunSpider 성능은 두 배가 되었고, V8 벤치마크 성능은 하드웨어와 소프트웨어의 기여로 인해 약 50% 증가했다.

하지만, V8은 공개적으로 문서가 다소 부족하다. 다음 몇 가지 글에서 높은 수준의 개요를 제공할 것이며, 이는 가상 머신이나 컴파일러의 내부에 대해 궁금해하는 모든 이들에게 흥미로운 내용이 될 것이다.


High level architecture (고급 아키텍처)

V8은 실행하기 전에 모든 자바스크립트를 네이티브 코드로 컴파일한다. 해석이나 바이트코드가 없다. 컴파일은 한 번에 하나의 함수씩 수행된다(예전의 파이어폭스 VM인 TraceMonkey에서 사용되는 트레이스 기반 파일과는 달리). 대개 함수는 처음 호출될 때까지 실제로 컴파일되지 않으므로, 큰 라이브러리 스크립트를 포함하더라도 VM은 사용되지 않는 부분을 컴파일하는데 시간을 낭비하지 않는다.

V8은 실제로 두 가지 다른 자바스크립트 컴파일러를 사용한다. 그것들은 간단한 컴파일러와 보조 컴파일러라고 생각한다. 전체 컴파일러는 최적화되지 않은 컴파일러이다. 네이티브 코드를 최대한 빨리 생성하는 것이 이 작업의 목적이며, 이는 페이지 로드 시간을 빠르게 유지(사용자가 방문했을 때 웹페이지가 빠르게 열리고 화면에 나타나는 시간)하는데 중요하다. Crankshaft는 최적화 컴파일러이다. V8은 먼저 전체 컴파일러로 모든 것을 컴파일한 다음 내장 프로파일러를 사용하여 Crankshaft에 의해 최적화될 'hot' 함수(자주 호출되는 함수)를 선택한다. V8은 대부분 단일 스레드(버전 3.14 기준)이기 때문에 컴파일러가 실행되는 동안 실행이 일시 중지된다. 따라서 두 컴파일러 모두 매우 효율적인 코드를 생성하는데 많은 시간을 소비하는 대신 코드를 빠르게 생성하도록 설계되었다. 향후 V8 버전에서는 자바스크립트 실행과 동시에 별도의 스레드에서 Crankshaft(또는 적어도 그 일부)가 실행되어 더 비싼 최적화가 가능하다.


Why no bytecode? (왜 바이트코드가 없습니까?)

대부분의 VM에는 바이트 코드 인터프리터가 포함되어 있지만 V8에는 없다. 바이트코드로 컴파일하고 실행하는 것이 더 쉬울 수 있는데 왜 전체 컴파일러를 쓰는지 궁금할 수 있다. 최적화되지 않은 네이티브 코드로 컴파일하는 것이 실제로 바이트 코드로 컴파일하는 것보다 훨씬 더 비싸지 않다(성능이 좋다)는 것이 밝혀졌다. 다음 두 가지의 대한 컴파일 프로세스 과정을 살펴보자.

바이트 코드 컴파일