TIL

Chapter 9. JVM의 코드 실행

VMSpec - 표준 자바 구현체가 코드를 실행하는 방법을 기술한 자바 가상 머신 명세

9.1 바이트코드 해석

9.1.1 JVM 바이트코드 개요

바이트코드 명령어는 대부분 한쪽은 각 기본형, 다른 한 쪽은 참조형으로 쓸 수 있게 ‘패밀리’ 단위로 구성

주요 바이트코드 명령어

패밀리 명 인수 설명
load (i1) 지역 변수 i1 값을 스택에 로드
store (i1) 스택 상단을 지역 변수 i1에 저장
ldc c1 CP#c1이 가리키는 값을 스택에 로드
const   단순 상숫값을 스택에 로드
pop   스택 상단에서 값을 제거
dup   스택 상단에 있는 값을 복제
getField c1 스택 상단에 위치한 객체에서 CP#c1이 가리키는 필드명을 찾아 스택에 로드
putField c1 스택 상단 값을 CP#c1이 가리키는 필드에 저장
getstatic c1 CP#c1이 가리키는 정적 필드값을 스택에 로드
putstatic c1 스택 상단 값을 CP#c1이 가리키는 정적 필드에 저장
페밀리 명 설명
add 스택 상단의 두 값을 더한다
sub 스택 상단의 두 값을 뺀다
div 스택 상단 두 값을 나눈다
mul 스택 상단 두 값을 곱한다
(cast) 스택 상단 값을 다른 기본형으로 캐스팅
neg 스택 상단 값을 부정
rem 스택 상단 두 값을 나눈 나머지를 구한다
페밀리 명 인수 설명
if (i1) 조건이 참일 경우 인수가 가리키는 위치로 분기
goto i1 주어진 오프셋으로 무조건 분기
- 몇 개 없어 보이지만 `if` 옵코드 페밀리에 속한 옵코드가 상당이 많다.
옵코드 명 인수 설명
invokevirtual c1 CP#c1이 가리키는 메서드를 가상 디스패치로 호출
invokespecial c1 CP#c1이 가리키는 메서드를 특별한 디스패치로 호출
invokeinterface c1, count, 0 CP#c1이 가리키는 인터페이스 메서드를 인터페이스 오프셋 룩업으로 호출
invokestatic c1 CP#c1이 가리키는 정적 메서드 호출
invokedynamic c1, 0, 0 호출해서 실행할 메서드를 동적으로 찾는다
옵코드 명 인수 설명
new c1 CP#c1이 가리키는 타입의 객체에 공간을 할당
newarray prim 기본형 배열에 공간 할당
anewarray c1 CP#c1이 가리키는 타입 객체 배열에 공간을 할당
arraylength   스택 상단 객체를 그 길이로 치환
monitorenter   스택 상단 객체 모니터를 잠금
monitorexit   스택 상단 객체 모니터를 잠금 해제

바이트코드 개별 의미와 세이프포인트

9.1.2 단순 인터프리터

9.1.3 핫스팟에 특정한 내용

9.2 AOT와 JIT 컴파일

9.2.1 AOT 컴파일

소스 코드를 AOT 컴파일하면 어떤 식으로든 최적화할 기회는 단 한 번뿐이다.

9.2.2 JIT 컴파일

9.2.3 AOT 컴파일 vs JIT 컴파일

9.3 핫스팟 JIT 기초

9.3.1 klass 워드, vtable, 포인트 스위즐링

image

9.3.2 JIT 컴파일 로깅

9.3.3 핫스팟 내부의 컴파일러

9.3.4 핫스팟의 단계별 컴파일

경로 설명
0-3-4 인터프리터, C1 - 풀 프로파일링, C2
0-2-3-4 인터프리터, C2는 바쁘니까 재빨리 C1 풀 컴파일 후 C1 풀 컴파일, 그 다음 C2
0-3-1 단순 메서드
0-4-1 단계별 컴파일 안 함 (C2로 직행)

9.4 코드 캐시

9.4.1 단편화

9.5 간단한 JIT 튜닝법