2011-12-18 3 views
4

적어도 Mono's exception handling implementation의 설명에 따르면 예외가 발생하면 모든 x86 레지스터가 저장됩니다. 스택 포인터 (ESP), 프레임 포인터 (EBP), 명령어 포인터 (EIP) 및 예외 객체를 보유하는 레지스터 외에 다른 레지스터도 왜 저장됩니까? 왜 .NET에있을 때 전체 컨텍스트를 저장하면 throw 후에 즉시 실행을 계속할 수있는 메커니즘이 없습니까?.NET 예외 처리 중에 모든 레지스터가 저장되는 이유는 무엇입니까?

UPDATE :

  • 자동 CLI가 생성되어 푸시 예외를 설명하는 예외 객체 계산 스택 상 :

    EMCA는 예외 처리 12.3.2.4 개요 섹션에서는 다음과 같은 상태 필터 또는 catch 절의 입력시 첫 번째 항목으로.

  • 필터 처리기를 제외한 예외 위치에서 실행을 다시 시작할 수 없습니다.

"필터 처리기를 제외하고"는 이전 문에 비추어 수행 할 수있는 방법을 모르겠습니다. 또한 endfilter opcode에 대한 설명에는 "다른 예외 처리기 검색 계속"또는 CIL opcode의 다른 블록을 실행하는 처리기를 실행하는 두 가지 결과 만 있습니다. "다시 시작"옵션이 없습니다. 따라서 사양에서이 불일치를 해석하면 .NET이 던지기 직후 실행을 계속할 수 없다는 것을 기본적으로 의미합니다. 어쩌면 그것은 어떤 시점에서 고려되었지만 완전히 실현되고 구현 된 적이 없을 수도 있습니다.

UPDATE 2 :

누군가가 어떤 필터 핸들러가 예외를 잡으려고의 opts하지 않는 경우 "다시 시작"단순히 일어날 수 있다고 지적했다. 그러나 throw에 대한 사양은 "throw 명령은 예외 객체를 스택에 던져 스택을 비 웁니다." 스택을 비우면 throw 문 바로 다음에 코드를 실행할 수 없으므로 스택에 무언가가 필요할 수 있습니다.

+1

그냥 추측하지만 일부 디버깅 도구는 물건을 가지고? – kenny

+0

아마 첫 번째 기회 대 두 번째 기회 예외 처리 및/또는 예외 필터와 관련이 있습니까? –

답변

3

구현 세부 정보를 살펴 보았습니다. 구현의 용이성, 코드 공유, 추가 의미 부여, 미래 보장, 최적화 등의 이유로 인해 일반적으로 ECMA 사양과 일대일로 일치하지 않습니다. .

이 특별한 경우에는 몇 가지 고려 사항이 있습니다.

Mono는 MonoContext라는 프로세서 상태 뷰를 기반으로 예외 처리를 수행합니다.이 구조는 다른 곳에서도 사용되기 때문에 일부 특정 경우에 일부가 필요하지 않을지라도 모든 관련 레지스터가 포함되어 있습니다. 특히 모든 레지스터를 복원해야하는 CPU 예외에서 예외 처리를 시작할 수 있으므로 모든 레지스터가 수집됩니다.

누군가 이미 컨텍스트가 디버거에도 사용되는 것을 관찰했습니다.

간단한 로컬 var 설정 인 catch를 사용하여 try/catch가있는 메소드의 경우도 고려하십시오. 이제 진보 된 레지스터 할당 기는 throw 이전에 (던지기가 암시적일 수 있음을 주목하고, cpu 예외 경로에 의해 처리되도록), edx와 같은 레지스터에 캐치 한 후에 사용되는 로컬 var을 넣을 수 있습니다. 예외/예외 지점에 모든 레지스터를 저장하지 않으면 edx가 예외 처리 중에 덮어 쓰게되므로 프로그램 상태가 손상되었습니다.

마지막 주석으로 : 몇 가지 여분의 레지스터를 절약하면 CPU주기가 낭비되는 것이 걱정 되십니까? 실제로 소비 된 사이클 수를 계산하면 예외 처리 중에 발생해야하는 모든 작업에 완전히 소음이 들게됩니다.

+0

감사합니다. CPU 생성 예외에 관해서는 예외 처리기가 레지스터의 데이터 (예 : 로컬 변수를 보유하고있는 데이터)를 어떻게 처리해야하는지 알 수 있습니까? 다시 시작할 수 없기 때문에 아무 것도하지 않는다고 생각합니다. – tgiphil

+0

또한 성능에 대해 걱정하지 않습니다. 난 단지 .NET 예외 처리를 이해하려고 노력 중이므로 [Mosa] (http : \\ www.mosa-project.org)라는 다른 .NET 컴파일러에서 구현할 수 있습니다. – tgiphil

+0

정상적인 예외 처리는 동일한 지점에서 재개되지 않을 것이지만, CPU 예외 (또는 비동기 신호 처리기)를 처리하는 다른 사례는 동일한 지점에서 중지 및 재개 될 수 있으며 구현시 처리가 통일되므로 모두 레지스터가 필요합니다. 같은 위치에서 실행을 재개 할 수 없다는 사실은 일반적으로 중요하지 않습니다. edx에 할당 된 loca 변수의 예를 참조하십시오. – lupus

관련 문제