diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-08-16 22:14:39 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-08-16 22:14:39 -0700 |
commit | 2399bf36c10ec9f7011008a76f96847be7255c9d (patch) | |
tree | c6b08adb149a32adf43e5f8062ca358f046bfd4d /unwind.h | |
parent | e31b1509ebb518548780aa2544459337854af48e (diff) | |
download | txr-2399bf36c10ec9f7011008a76f96847be7255c9d.tar.gz txr-2399bf36c10ec9f7011008a76f96847be7255c9d.tar.bz2 txr-2399bf36c10ec9f7011008a76f96847be7255c9d.zip |
Get continuations working on aarch64.
* unwind.c (UW_CONT_FRAME_BEFORE, UW_CONT_FRAME_AFTER): New
preprocessor symbols.
(revive_cont): The "frame slack" zero-filled padding logic
is replaced by capturing an actual part of the real stack
before the uw_stack unwind frame. On aarch64, there is
content there we must actually capture. Experiment shows
that exactly 128 bytes is enough, and that corresponds to
the frame_slack value.
(capture_cont): Capture UW_CONT_FRAME_BEFORE bytes before
the uw_stack unwind frame location. Also, the "capture_extra"
is replaced by UW_CONT_FRAME_AFTER constant, to harmonize.
* unwind.h (UW_FRAME_ALIGN): New preprocessor symbol.
(union uw_frame): On aarch64, we ask the compiler, via
a GCC-specific attribute syntax, to align the address of
frame objects to a 16 byte boundary. This solves a crash
in the continuation code. Continuation capture is keyed
to unwind frame addresses. When a captured continuation is
revived onto the stack, the delta between its original address
and the revive address must be a multiple of 16. The reason
is that this preserves the stack and frame pointer alignment.
Certain instructions on the aarch64, require the stack pointer
to be 16 byte aligned. There are other ways we could achieve
this, but the easiest is to align the original frames to 16
bytes.
Diffstat (limited to 'unwind.h')
-rw-r--r-- | unwind.h | 8 |
1 files changed, 7 insertions, 1 deletions
@@ -98,6 +98,12 @@ struct uw_debug { val chr; }; +#if __aarch64__ +#define UW_FRAME_ALIGN __attribute__ ((aligned (16))) +#else +#define UW_FRAME_ALIGN +#endif + union uw_frame { struct uw_common uw; struct uw_block bl; @@ -107,7 +113,7 @@ union uw_frame { struct uw_cont_copy cp; struct uw_guard gu; struct uw_debug db; -}; +} UW_FRAME_ALIGN; void uw_push_block(uw_frame_t *, val tag); void uw_push_env(uw_frame_t *); |