developer tip

스택 맵 프레임이란?

copycodes 2021. 1. 6. 08:30
반응형

스택 맵 프레임이란?


저는 최근에 내 프로그램이 작동하는 이유를 더 잘 이해하기 위해 JVMS ( Java Virtual Machine Specifications )를 살펴 봤지만 잘 이해하지 못하는 섹션을 찾았습니다.

4.7.4StackMapTable 속성을 설명 하고, 해당 섹션에서 문서는 스택 맵 프레임에 대한 세부 사항을 설명합니다. 문제는 약간 장황하고 모범을 통해 가장 잘 배운다는 것입니다. 독서가 아닙니다.

첫 번째 스택 맵 프레임이 메서드 설명자에서 파생된다는 것을 이해하지만 방법을 이해하지 못합니다 ( 여기에 설명되어 있음 ). 또한 스택 맵 프레임이 수행하는 작업을 완전히 이해하지 못합니다. 나는 그것들이 Java의 블록과 유사하다고 가정하지만, 서로 내부에 스택 맵 프레임을 가질 수없는 것처럼 보입니다.

어쨌든 두 가지 구체적인 질문이 있습니다.

  • 스택 맵 프레임은 무엇을합니까?
  • 첫 번째 스택 맵 프레임은 어떻게 생성됩니까?

일반적인 질문 하나 :

  • 누군가가 JVMS에 제공된 것보다 덜 장황하고 이해하기 쉬운 설명을 제공 할 수 있습니까?

Java는 샌드 박스의 보안을 유지하고 코드를 최적화하기에 안전한지 확인하기 위해로드 된 모든 클래스를 확인해야합니다. 이것은 바이트 코드 수준에서 수행되므로 확인은 Java 언어의 불변성을 확인하지 않으며 바이트 코드가 바이트 코드 규칙에 따라 의미가 있는지 확인합니다.

무엇보다도 바이트 코드 검증은 명령어가 잘 구성되어 있는지, 모든 점프가 메서드 내에서 유효한 명령어로 이동하는지, 모든 명령어가 올바른 유형의 값에서 작동하는지 확인합니다. 마지막은 스택 맵이 들어오는 곳입니다.

문제는 바이트 코드 자체에 명시적인 유형 정보가 포함되어 있지 않다는 것입니다. 유형은 데이터 흐름 분석을 통해 암시 적으로 결정됩니다. 예를 들어, iconst 명령어는 정수 값을 생성합니다. 슬롯 1에 저장하면 이제 해당 슬롯에 int가 있습니다. 대신 float를 저장하는 코드에서 제어 흐름이 병합되면 슬롯은 이제 잘못된 유형으로 간주됩니다. 즉, 덮어 쓰기 전까지는 해당 값으로 더 이상 아무것도 할 수 없습니다.

역사적으로 바이트 코드 검증자는 이러한 데이터 흐름 규칙을 사용하여 모든 유형을 유추했습니다. 불행히도, 역방향 점프는 이미 추론 된 유형을 무효화 할 수 있기 때문에 바이트 코드를 통한 단일 선형 패스의 모든 유형을 추론하는 것은 불가능합니다. 클래식 검증기는 모든 것이 변경되지 않을 때까지 코드를 반복하여 여러 번의 패스가 필요할 때까지이를 해결했습니다.

그러나 검증은 Java에서 클래스 로딩을 느리게 만듭니다. Oracle은 단일 패스로 바이트 코드를 확인할 수있는 새롭고 빠른 검증기를 추가하여이 문제를 해결하기로 결정했습니다. 이를 위해 Java 7 (전환 상태의 Java 6 포함)에서 시작하는 모든 새 클래스 가 해당 유형에 대한 메타 데이터를 전달해야하므로 바이트 코드를 단일 패스로 확인할 수 있습니다. 바이트 코드 형식 자체는 변경할 수 없기 때문에이 유형 정보는라는 속성에 별도로 저장됩니다 StackMapTable.

코드의 모든 단일 지점에서 모든 단일 값에 대한 유형을 저장하는 것은 분명히 많은 공간을 차지하고 매우 낭비 적입니다. 메타 데이터를 더 작고 효율적으로 만들기 위해 그들은 점프의 대상 위치에있는 유형 만 나열 하기로 결정했습니다 . 생각해 보면 이것이 단일 패스 인증을 수행하기 위해 추가 정보가 필요한 유일한 시간입니다. 점프 대상 사이에서 모든 제어 흐름은 선형이므로 이전 추론 규칙을 사용하여 위치 사이의 유형을 추론 할 수 있습니다.

유형이 명시 적으로 나열된 각 위치를 스택 맵 프레임이라고합니다. StackMapTable들은 보통 데이터 크기를 줄이기 위해 이전 프레임으로부터의 차이로 표현 되더라도 속성 순서대로 프레임들의리스트를 포함한다. 제어 흐름이 결합되지 않을 때 발생하는 (즉, CFG가 트리) 메서드에 프레임이없는 경우 StackMapTable 속성을 완전히 생략 할 수 있습니다.

이것이 StackMapTable의 작동 방식과 추가 된 이유에 대한 기본 아이디어입니다. 마지막 질문은 암시 적 초기 프레임이 생성되는 방법입니다. 물론 대답은 메서드의 시작 부분에서 피연산자 스택이 비어 있고 지역 변수 슬롯에는 메서드 디스크립터에서 결정된 메서드 매개 변수의 유형에 따라 지정된 유형이 있다는 것입니다.

Java에 익숙하다면 메서드 매개 변수 유형이 바이트 코드 수준에서 작동하는 방식에 약간의 차이가 있습니다. 우선, 가상 메소드는 this첫 번째 매개 변수로 암시 적 입니다. 둘째는, boolean, byte, char, 및 short바이트 코드 수준에서 존재하지 않습니다. 대신, 그들은 모두 뒤에서 int로 구현됩니다.

참조 URL : https://stackoverflow.com/questions/25109942/what-is-a-stack-map-frame

반응형