Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack-consuming ArrayVec #50

Open
efenniht opened this issue Sep 11, 2019 · 4 comments
Open

Stack-consuming ArrayVec #50

efenniht opened this issue Sep 11, 2019 · 4 comments

Comments

@efenniht
Copy link
Collaborator

ArrayVec 의 몇몇 메서드 (e.g. new, push) 는 #[inline]으로 선언되어 있지 않고, 따라서 inter-crate optimization이 잘 안됩니다. 그래서 스택이 터질 수 있습니다. 으악!

이건 ArrayVec의 문제이면서, Rust의 문제기도 합니다.

  • Rust는 거대한 값을 포인터로 간접 전달하지 말고 직접 리턴하는 것을 권장합니다.
  • Rust는 그렇게 하면 최적화가 잘 일어나서 typical C/C++처럼 될거라고 광고합니다.
  • 그런데 inter-crate 최적화에 실패해서 스택에 너무 큰 메모리를 할당하게 될 수 있습니다.
  • Safe Rust의 메모리 안전성이 위반되는 몇 안되는 경우가 스택이 깨지는 것입니다.
  • 그런데 safe Rust에는 스택을 보호하는 기능이 거의 없습니다. (https://twitter.com/CopperheadOS/status/876835207701200896)
  • Rust가 memory safety를 sound하게 보장하려면 RVO같은 것을 스펙으로 만들어야 하지 않을까요?

아무튼 이 9d61512 커밋에서 두 개의 위험한 스택 할당을 수정했습니다.

  • self.vcpus = ArrayVec::new()
  • self.vcpus.push(VCpu::new(self_ptr))

그런데 후자는 push가 어떤 일을 하는 지 모르므로 최적화가 불가능하지만, 전자는 (inter-crate optimization 이 막혀 있는 지금도) 최적화가 가능하지 않을까요?

@efenniht
Copy link
Collaborator Author

그래서 이 문제가 해결되는 방법이 두 가지가 있는데,

둘 다 언제 될지 모르므로, Hafnium의 초기화 과정을 HAFNIUM = MaybeUninit::new(Hypervisor::new(...)); 로 간단하게 만드는 것은 요원해 보입니다.

@jeehoonkang
Copy link
Member

헐.. 정말 놀랍다고밖에 할말이 없네요...

@jeehoonkang
Copy link
Member

반면 행복회로를 돌려보면 이런 것도 논문에 쓸 재밌는 스토리가 되겠습니다..

@efenniht
Copy link
Collaborator Author

efenniht commented Sep 11, 2019

추가적으로 ArchRegs를 수정하여 스택에 과도한 할당이 일어나는 경우를 모두 고쳤습니다. Hafnium binary의 디스어셈블해서 sub sp, 로 검색한 결과 한 함수마다 평균적으로 256바이트, 아무리 많아도 512바이트 이하를 사용하는 것을 확인했습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants