summaryrefslogtreecommitdiff
path: root/upb/pb
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2011-08-20 18:01:25 -0700
committerJoshua Haberman <jhaberman@gmail.com>2011-08-20 18:01:25 -0700
commita5e6a7b029850f77059800d6611f406b91f87dfe (patch)
treebbbdc88178472ff464aec9440b92d96f482f9486 /upb/pb
parent8bdc6d233e54b93d19a98b85b2c173c08c13f04a (diff)
Fix stack alignment on OS X.
Diffstat (limited to 'upb/pb')
-rw-r--r--upb/pb/decoder_x86.dasc15
1 files changed, 15 insertions, 0 deletions
diff --git a/upb/pb/decoder_x86.dasc b/upb/pb/decoder_x86.dasc
index b99e745..3028086 100644
--- a/upb/pb/decoder_x86.dasc
+++ b/upb/pb/decoder_x86.dasc
@@ -7,6 +7,10 @@
|// JIT compiler for upb_decoder on x86. Given a upb_handlers object,
|// generates code specialized to parsing the specific message and
|// calling specific handlers.
+|//
+|// Since the JIT can call other functions (the JIT'ted code is not a leaf
+|// function) we must respect alignment rules. On OS X, this means aligning
+|// the stack to 16 bytes.
#define UPB_NONE -1
#define UPB_MULTIPLE -2
@@ -561,6 +565,11 @@ static int upb_compare_uint32(const void *a, const void *b) {
static void upb_decoder_jit_msg(upb_decoder *d, upb_mhandlers *m) {
|=>m->jit_startmsg_pclabel:
+
+ if (m->jit_parent_field_done_pclabel == UPB_MULTIPLE) {
+ // There was a call to get here, so we need to align the stack.
+ | sub rsp, 8
+ }
// Call startmsg handler (if any):
if (m->startmsg) {
// upb_flow_t startmsg(void *closure);
@@ -624,6 +633,8 @@ static void upb_decoder_jit_msg(upb_decoder *d, upb_mhandlers *m) {
}
if (m->jit_parent_field_done_pclabel == UPB_MULTIPLE) {
+ // Counter previous alignment.
+ | add rsp, 8
| ret
} else if (m->jit_parent_field_done_pclabel == UPB_TOPLEVEL_ONE) {
| jmp ->exit_jit
@@ -644,6 +655,8 @@ static void upb_decoder_jit(upb_decoder *d) {
| push r13
| push r12
| push rbx
+ // Align stack.
+ | sub rsp, 8
| mov DECODER, ARG1_64
| mov FRAME, DECODER:ARG1_64->dispatcher.top
| lea STRREF, DECODER:ARG1_64->strref
@@ -661,6 +674,8 @@ static void upb_decoder_jit(upb_decoder *d) {
for (int i = 0; i < h->msgs_len; i++) upb_decoder_jit_msg(d, h->msgs[i]);
|->exit_jit:
+ // Counter previous alignment.
+ | add rsp, 8
| pop rbx
| pop r12
| pop r13
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback