점화를 점화 해석기로 시작하기
V8 및 기타 현대 자바스크립트 엔진들은 스크립트를 실행 직전에 네이티브 머신 코드로 즉시(JIT) 컴파일하여 속도를 얻습니다. 코드가 처음에는 기본 컴파일러에 의해 컴파일되며, 이는 최적화되지 않은 머신 코드를 빠르게 생성할 수 있습니다. 컴파일된 코드는 실행 중 분석되며, 필요에 따라 더 고급의 최적화 컴파일러로 동적으로 다시 컴파일되어 최상의 성능을 제공합니다. V8에서는 이러한 스크립트 실행 파이프라인이 다양한 특수 사례와 조건을 포함하고 있어 기본 컴파일러와 Crankshaft 및 TurboFan이라는 두 개의 최적화 컴파일러 사이를 전환하기 위한 복잡한 메커니즘이 필요합니다.
이 접근법의 문제점 중 하나는 (아키텍처 복잡성 외에도) JIT된 머신 코드가 상당한 메모리를 소비할 수 있다는 점입니다. 심지어 코드가 단 한 번만 실행되더라도 그렇습니다. 이 오버헤드를 줄이기 위해, V8 팀은 Ignition이라는 새로운 자바스크립트 해석기를 개발했으며, 이를 통해 V8의 기본 컴파일러를 대체하고 메모리 오버헤드를 줄이며 간단한 스크립트 실행 파이프라인을 제공합니다.
Ignition을 통해, V8은 JavaScript 함수들을 간결한 바이트코드로 컴파일하며, 이는 동등한 기본 머신 코드의 크기 대비 50%에서 25% 정도입니다. 그 후 이 바이트코드는 고성능 해석기에 의해 실행되며, 실제 웹사이트에서 V8의 기존 기본 컴파일러로 생성된 코드와 거의 동일한 실행 속도를 제공합니다.
Chrome 53에서는 제한된 RAM(512MB 이하)을 가진 안드로이드 기기에서 Ignition이 활성화될 것입니다. 이는 메모리 절약이 가장 필요한 곳입니다. 초기 실험 결과에 따르면, Ignition은 Chrome 탭의 메모리를 탭당 약 5% 절약할 수 있음을 보여줍니다.
세부사항
Ignition의 바이트코드 해석기를 개발하는 과정에서, 팀은 여러 잠재적인 구현 방식을 검토했습니다. C++로 작성된 전통적인 해석기는 V8의 다른 생성된 코드와 효율적으로 상호작용할 수 없을 것입니다. 대안으로 어셈블리 코드로 해석기를 직접 코딩하는 방법이 있었지만, V8이 아홉 개의 아키텍처 포트를 지원하기 때문에 이는 상당한 엔지니어링 오버헤드를 야기했을 것입니다.
대신, 우리는 TurboFan의 강점을 활용하는 접근법을 선택했습니다. TurboFan은 V8 런타임 및 다른 생성된 코드와 최적으로 상호작용하도록 이미 조정된 새로운 최적화 컴파일러입니다. Ignition 해석기는 TurboFan의 저수준 아키텍처 비독립 매크로 어셈블리 명령을 사용하여 각 오프코드에 대한 바이트코드 핸들러를 생성합니다. TurboFan은 이러한 명령을 대상 아키텍처로 컴파일하며, 이 과정에서 저수준 명령 선택 및 머신 레지스터 할당을 수행합니다. 이로 인해 바이트코드 명령을 실행하고 V8 가상 머신의 다른 부분과 낮은 오버헤드로 상호작용할 수 있는 고도로 최적화된 해석기 코드가 생성되며, 코드베이스에 새로 추가되는 메커니즘의 양은 최소화됩니다.
Ignition은 각 바이트코드가 입력 및 출력을 명시적인 레지스터 피연산자로 지정하는 레지스터 머신이며, 스택 머신에서는 각 바이트코드가 입력을 사용하고 출력이 암시적인 스택에 푸시됩니다. 특별한 누적기 레지스터는 많은 바이트코드들에서 암시적인 입력 및 출력 레지스터로 동작합니다. 이는 특정 레지스터 피연산자를 지정할 필요를 피함으로써 바이트코드의 크기를 줄입니다. 많은 JavaScript 표현식이 좌에서 우로 평가되는 연산 체인을 포함하기 때문에, 이러한 연산의 임시 결과는 종종 표현식 평가 동안 누적기에 유지될 수 있으며, 이를 통해 명시적인 레지스터에 데이터를 로드하거나 저장하는 작업을 최소화할 수 있습니다.
바이트코드가 생성됨에 따라, 여러 인라인 최적화 단계를 거칩니다. 이러한 단계들은 바이트코드 스트림에 대해 간단한 분석을 수행하여 일반적인 패턴을 더 빠른 시퀀스로 대체하고, 일부 중복 작업을 제거하며, 불필요한 레지스터 로드 및 전송의 수를 최소화합니다. 이러한 최적화들은 바이트코드의 크기를 추가로 줄이고 성능을 향상시킵니다.
Ignition의 구현에 대한 추가 세부사항은 우리의 BlinkOn 발표를 참조하세요:
미래
지금까지 Ignition에 대한 우리의 초점은 V8의 메모리 오버헤드를 줄이는 데 있었습니다. 그러나 Ignition을 스크립트 실행 파이프라인에 추가함으로써 향후 여러 가능성이 열립니다. Ignition 파이프라인은 웹 페이지 로딩을 가속화하고 끊김 현상을 줄이며 V8의 다양한 구성 요소 간 상호 작용을 더욱 효율적으로 만드는 데 있어 언제 코드를 실행하고 최적화할지를 더 스마트하게 결정할 수 있도록 설계되었습니다.
Ignition과 V8의 향후 개발을 기대해 주세요.