-
Notifications
You must be signed in to change notification settings - Fork 10
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
Fast block return #78
Conversation
@@ -1996,7 +1996,7 @@ run2: rounds | mock | | |||
self run: [ mock selfSend ] rounds: rounds text: 'Self dispatch'. | |||
|
|||
self run: [ mock invokeBlock: [nil] ] rounds: rounds text: 'Block invoke'. | |||
self run: [ mock blockReturn ] rounds: rounds text: 'Block return'. | |||
self run: [ 1 to: rounds do: [ :x | mock blockReturn ] ] rounds: 1 text: 'Block return'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference?
81ac69e
to
8d869d8
Compare
8e5a29d
to
8095eaf
Compare
@@ -127,13 +127,16 @@ if (USE_LLVM) | |||
src/llstPass.cpp | |||
src/llstDebuggingPass.cpp | |||
) | |||
|
|||
add_library(trampoline "src/trampoline.cpp") | |||
set_source_files_properties(src/trampoline.cpp PROPERTIES COMPILE_FLAGS "-freg-struct-return") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7caca94
to
50aa7eb
Compare
e189b20
to
a134dc1
Compare
WTF, Дима. Я как бэ комменты оставил |
Изменения по твоим комментариям надо оформить отдельным PR поверх |
Original implementation uses exception API to perform far jump to dispatch
BlockReturn
instruction. This work OK but is terribly slow. I mean REALLY slow, 10 times slower than the software implementation and 40 times slower than implementation proposed here.Current pull request implements
BlockReturn
using MRV technique to return several values in registers instead of stack. In our case result object is returned ineax
whereas target context inedx
(on x86 of course). Cascade block return is handled by simply propagating these two registers unchanged from inner stack frame to outer and so on. Typical overhead is onecmp
ortest
instruction per message send and oneret
instruction per frame.We use use
-freg-struct-return
technique which is uncommon in UNIX world and it's calling conventions, but is fully supported in GCC and clang depending on a compiler version.More portable implementation should pass return value using the stack (
sret
in terms of LLVM) but this will be slower and will not handle cascade return in a straightforward way.