자 바스 크 립 트 엔진 V8 실행 프로 세 스 상세 설명
V8 의 이름 은 자동차의'V 형 8 기통 엔진'(V8 엔진)에서 유래 했다.V8 엔진 은 주로 미국 에서 발전 하기 시 작 했 는데,마력 이 충분 하기 때문에 널리 알려 져 있다.V8 엔진 의 이름 은 Google 이 사용자 에 게 강력 하고 빠 른 자 바스 크 립 트 엔진 임 을 보 여 주 는 것 입 니 다.
V8 이 탄생 하기 전 까지 초기 주류 인 자 바스 크 립 트 엔진 은 자 바스 크 립 트 코어 엔진 이 었 다.JavaScriptCore 는 주로 Webkit 브 라 우 저 커 널 에 서 비 스 를 제공 하 는데 그들 은 모두 애플 이 개발 하고 개발 한 것 이다.구 글 은 자 바스 크 립 트 코어 와 웹 킷 의 개발 속도 와 실행 속도 에 만족 하지 않 는 다 고 한다.구 글 은 새로운 자 바스 크 립 트 엔진 과 브 라 우 저 커 널 엔진 을 개발 하기 위해 V8 과 크롬 두 개의 엔진 을 탄생 시 켰 으 며,지금까지 가장 인기 있 는 브 라 우 저 관련 소프트웨어 다.
2.V8 의 서비스 대상
V8 은 크롬 을 바탕 으로 발 전 된 것 으로 브 라 우 저 커 널 에 국한 되 지 않 는 다.지금까지 V8 은 유행 하 는 nodejs,weex,빠 른 응용,초기의 RN 등 여러 장면 에 응용 되 었 다.
3.V8 의 초기 구조
V8 엔진 의 탄생 은 속도 와 메모리 회수 에 있어 서 혁명 을 해 야 한 다 는 사명 을 가지 고 왔 다.JavaScriptCore 의 구 조 는 바이트 코드 를 만 드 는 방식 으로 바이트 코드 를 실행 하 는 것 이다.Google 은 JavaScriptCore 라 는 구조 가 안 되 고 바이트 코드 를 만 드 는 데 시간 이 낭비 되 므 로 기계 코드 를 직접 만 드 는 것 이 빠 릅 니 다.그래서 V8 은 초기의 구조 디자인 에 있어 매우 급진 적 이 고 기계 코드 로 직접 컴 파일 하 는 방식 을 채택 했다.후기의 실천 은 구 글 의 이러한 구조 속도 가 개선 되 었 음 을 증명 하 였 으 나 동시에 메모리 소모 문제 도 야기 하 였 다.V8 의 초기 흐름 도 를 볼 수 있 습 니 다.
초기의 V8 에는 Full-Codegen 과 Crankshaft 두 개의 컴 파일 러 가 있 었 다.V8 은 먼저 Full-Codegen 으로 모든 코드 를 한 번 씩 컴 파일 하여 해당 하 는 기계 코드 를 생 성 합 니 다.JS 가 실행 되 는 과정 에서 V8 에 내 장 된 Profiler 는 핫 이 슈 함 수 를 선별 하고 매개 변수의 피드백 유형 을 기록 한 다음 에 Crankshaft 에 맡 겨 최적화 시킨다.그래서 Full-Codegen 은 본질 적 으로 최적화 되 지 않 은 기계 코드 를 생 성 했 고 Crankshaft 는 최 적 화 된 기계 코드 를 생 성 했다.
4.V8 초기 구조의 결함
버 전의 도입 에 따라 웹 페이지 의 복잡 화 에 따라 V8 도 자신의 구조 상의 결함 을 점점 드 러 냈 다.
상기 단점 을 해결 하기 위해 V8 은 JavaScriptCore 의 구 조 를 이용 하여 바이트 코드 를 생 성 한다.여기 구 글 이 다시 돌아 온 것 같 지 않 아 요?V8 은 바이트 코드 를 생 성 하 는 방식 으로 전체 절 차 는 다음 과 같다.
Ignition 은 V8 의 해석 기 이 며,배후 의 원시 동 기 는 모 바 일 장치 의 메모리 소 모 를 줄 이 는 것 이다.Ignition 이전에 V8 의 Full-codegen 기선 컴 파일 러 가 생 성 한 코드 는 보통 크롬 전체 자 바스 크 립 트 더미 의 3 분 의 1 을 차지한다.이것 은 웹 프로그램의 실제 데이터 에 더 적은 공간 을 남 겼 다.
Ignition 의 바이트 코드 는 Crankshaft 처럼 원본 코드 에서 다시 컴 파일 하지 않 고 TurboFan 으로 최 적 화 된 기계 코드 를 직접 생 성 할 수 있 습 니 다.Ignition 의 바이트 코드 는 V8 에서 더욱 뚜렷 하고 실수 하기 쉬 운 기선 집행 모델 을 제공 하여 최적화 체 제 를 간소화 했다.이것 은 V8 자가 적응 최적화 의 관건 적 인 특성 이다.마지막 으로,Full-codegen 을 생 성 하 는 기선 컴 파일 코드 보다 바이트 코드 생 성 이 빠 르 기 때문에 Ignition 을 활성화 하면 스 크 립 트 시작 시간 을 개선 하여 웹 페이지 로 딩 을 개선 합 니 다.
터 보 팬 은 V8 의 최적화 컴 파 일 러 로,터 보 팬 프로젝트 는 크 랭크 샤프트 의 단점 을 해결 하기 위해 2013 년 말 시작 됐다.Crankshaft 는 JavaScript 언어의 부분 집합 만 최적화 할 수 있 습 니 다.예 를 들 어 구조 화 이상 처 리 를 사용 하여 자바 스 크 립 트 코드 를 최적화 시 키 는 디자인 이 아 닙 니 다.즉,자바 스 크 립 트 의 try,catch 와 finally 키워드 로 구 분 된 코드 블록 입 니 다.Crankshaft 에 새로운 언어 기능 에 대한 지원 을 추가 하기 가 쉽 지 않 습 니 다.이 기능 들 은 9 개의 지원 하 는 플랫폼 을 위해 시스템 구조 에 특 정 된 코드 를 만들어 야 하기 때 문 입 니 다.
새로운 구 조 를 채택 한 후의 우세
서로 다른 구조 에서 V8 의 메모리 대 비 는 그림 과 같다.
결론:Ignition+TurboFan 구조 가 Full-codegen+Crankshaft 구조 메모리 보다 절반 이상 낮 아진 것 을 알 수 있다.
서로 다른 구조 웹 페이지 의 속도 향상 대비,그림 참조:
결론:Ignition+TurboFan 구조 가 Full-codegen+Crankshaft 구조 보다 70%빠 른 속도 로 향상 되 었 음 을 알 수 있다.
다음 에 우 리 는 기 존 구조의 모든 절 차 를 대체적으로 설명 한다.
6.V8 의 품사 분석 과 문법 분석
컴 파일 원 리 를 배 운 학생 들 은 JS 파일 은 하나의 소스 코드 일 뿐 기 계 는 실행 할 수 없다 는 것 을 알 수 있다.품사 분석 은 소스 코드 의 문자열 을 분리 하여 일련의 token 을 생 성 하 는 것 이다.아래 그림 에서 서로 다른 문자열 이 서로 다른 token 유형 에 대응 하 는 것 을 알 수 있다.
품사 분석 이 끝 난 후에 다음 단 계 는 바로 문법 분석 을 하 는 것 이다.문법 분석 문법 분석의 입력 은 바로 문법 분석의 출력 이 고 출력 은 AST 추상 문법 트 리 이다.프로그램 에 문법 오류 가 발생 했 을 때 V8 은 문법 분석 단계 에서 이상 을 던 졌 다.
7.V8 AST 추상 문법 트 리
다음 그림 은 add 함수 의 추상 문법 트 리 데이터 구조 입 니 다.
V8 Parse 단계 이후 추상 문법 트 리 에 따라 바이트 코드 를 생 성 한다.다음 그림 에서 보 듯 이 add 함수 가 대응 하 는 바이트 코드 를 생 성 합 니 다.
BytecodeGenerator 류 의 역할 은 추상 문법 트 리 에 따라 대응 하 는 바이트 코드 를 생 성 하 는 것 입 니 다.서로 다른 node 는 하나의 바이트 코드 생 성 함수 에 대응 하고 함수 의 시작 은 Visit***입 니 다.다음 그림+번호 에 대응 하 는 함수 바이트 코드 생 성:
void BytecodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
FeedbackSlot slot = feedback_spec()->AddBinaryOpICSlot();
Expression* subexpr;
Smi* literal;
if (expr->IsSmiLiteralOperation(&subexpr, &literal)) {
VisitForAccumulatorValue(subexpr);
builder()->SetExpressionPosition(expr);
builder()->BinaryOperationSmiLiteral(expr->op(), literal,
feedback_index(slot));
} else {
Register lhs = VisitForRegisterValue(expr->left());
VisitForAccumulatorValue(expr->right());
builder()->SetExpressionPosition(expr); //
builder()->BinaryOperation(expr->op(), lhs, feedback_index(slot)); // Add
}
}
상기 에서 알 수 있 듯 이 소스 코드 위치 기록 이 있 고 다음 그림 에서 소스 코드 와 바이트 코드 위치의 대응 관 계 를 알 수 있다.바이트 코드 를 만 듭 니 다.그 바이트 코드 는 어떻게 실 행 됩 니까?다음은 설명 하 겠 습 니 다.
바이트
우선 V8 바이트 코드 를 말씀 드 리 겠 습 니 다.
모든 바이트 코드 는 입력 과 출력 을 레지스터 로 지정 합 니 다.
Ignition 은 registers 레지스터 r0,r1,r2...과 누적 레지스터 레지스터(accumulator register)를 사용 합 니 다.
registers 레지스터:함수 파라미터 와 부분 변 수 는 사용자 가 볼 수 있 는 레지스터 에 저 장 됩 니 다.
누적 기:사용자 가 볼 수 없 는 레지스터 입 니 다.중간 결 과 를 저장 하 는 데 사 용 됩 니 다.
다음 그림 에서 ADD 바이트 코드:
바이트 코드 실행
다음 일련의 그림 은 모든 바이트 코드 가 실 행 될 때 레지스터 와 누산기 의 변화 에 대응 하고 add 함수 가 10,20 의 매개 변 수 를 전달 하 며 최종 누산기 가 돌아 온 결 과 는 50 임 을 나타 낸다.
각 바이트 코드 는 하나의 처리 함수 에 대응 하고 바이트 코드 처리 프로그램 이 저장 한 주 소 는 dispatch 에 있 습 니 다.table_맞다바이트 코드 를 실행 할 때 해당 하 는 바이트 코드 처리 프로그램 으로 호출 하여 실행 합 니 다.Interpreter 클래스 구성원 dispatchtable_모든 바이트 코드 의 처리 프로그램 주 소 를 저장 하 였 습 니 다.
예 를 들 어 ADD 바이트 코드 에 대응 하 는 처리 함 수 는(ADD 바이트 코드 를 실행 할 때 InterpreterBinary OpAssembler 클래스 를 호출 합 니 다):
IGNITION_HANDLER(Add, InterpreterBinaryOpAssembler) {
BinaryOpWithFeedback(&BinaryOpAssembler::Generate_AddWithFeedback);
}
void BinaryOpWithFeedback(BinaryOpGenerator generator) {
Node* reg_index = BytecodeOperandReg(0);
Node* lhs = LoadRegister(reg_index);
Node* rhs = GetAccumulator();
Node* context = GetContext();
Node* slot_index = BytecodeOperandIdx(1);
Node* feedback_vector = LoadFeedbackVector();
BinaryOpAssembler binop_asm(state());
Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index,
feedback_vector, false);
SetAccumulator(result); // ADD
Dispatch(); //
}
사실 이 JS 코드 는 이미 실행 되 었 습 니 다.실행 과정 에서 핫 이 슈 함수 가 발견 되 었 습 니 다.V8 은 Turbofan 을 사용 하여 최적화 컴 파일 을 하고 기계 코드 를 직접 생 성 합 니 다.그래서 다음 에 Turbofan 최적화 컴 파일 러 를 설명 하 겠 습 니 다.9.Turbofan
Turbofan 은 바이트 코드 와 핫 이 슈 함수 피드백 유형 에 따라 최 적 화 된 기계 코드 를 생 성 합 니 다.Turbofan 은 최적화 과정 이 많 고 기본 과 컴 파일 원리 의 백 엔 드 최적화 차이 가 많 지 않 으 며 sea-of-node 를 사용 합 니 다.
add 함수 최적화:
function add(x, y) {
return x+y;
}
add(1, 2);
%OptimizeFunctionOnNextCall(add);
add(1, 2);
V8 은 어떤 함 수 를 직접 호출 할 수 있 는 함수 가 있 습 니 다.%OptimizeFunction OnNextCall 을 실행 하여 Turbofan 최적화 add 함 수 를 주동 적 으로 호출 할 수 있 습 니 다.지난번 에 호출 된 매개 변수 피드백 에 따라 add 함 수 를 최적화 시 킬 수 있 습 니 다.이번 피드백 은 정형 수 임 이 분명 합 니 다.그래서 turbofan 은 매개 변수 가 정형 수 임 에 따라 최적화 하여 기계 코드 를 직접 생 성 합 니 다.다음 함수 호출 은 최 적 화 된 기계 코드 를 직접 호출 합 니 다.(V8 을 실행 하려 면--allow-natives-syntax 를 추가 해 야 합 니 다.OptimizeFunction OnNextCall 은 내장 함수 입 니 다.-allow-natives-syntax 를 더 해 야 내장 함 수 를 호출 할 수 있 습 니 다.그렇지 않 으 면 실행 이 잘못 될 수 있 습 니 다).JS 의 add 함수 생 성 에 대응 하 는 기계 코드 는 다음 과 같 습 니 다.
여기에 small interger 소정 수 개념 이 언급 되 어 있 으 니 이 글 을 볼 수 있 습 니 다.https://zhuanlan.zhihu.com/p/82854566
add 함수 의 입력 매개 변 수 를 문자 로 바 꾸 면
function add(x, y) {
return x+y;
}
add(1, 2);
%OptimizeFunctionOnNextCall(add);
add(1, 2);
최적화 후의 add 함수 생 성 에 대응 하 는 기계 코드 는 다음 과 같다.위의 두 그림 을 비교 하면 add 함수 가 서로 다른 매개 변 수 를 전달 하고 최적화 되 어 서로 다른 기계 코드 를 생 성 합 니 다.
만약 들 어 오 는 것 이 정형 이 라면,본질 적 으로 add 어 셈 블 리 명령 을 직접 호출 하 는 것 이다.
문자열 이 들 어 오 면 본질 적 으로 V8 의 내장 Add 함 수 를 호출 합 니 다.
여기 서 V8 의 전체 실행 절차 가 끝 났 습 니 다.
이상 은 자 바스 크 립 트 엔진 V8 의 실행 절차 에 대한 상세 한 내용 입 니 다.자 바스 크 립 트 엔진 V8 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JS 판단 수조 네 가지 실현 방법 상세그러면 본고는 주로 몇 가지 판단 방식과 방식 판단의 원리를 바탕으로 문제가 있는지 토론하고자 한다. 예를 들어 html에 여러 개의 iframe 대상이 있으면 instanceof의 검증 결과가 기대에 부합되지 않을...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.