From a5e6a7b029850f77059800d6611f406b91f87dfe Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 20 Aug 2011 18:01:25 -0700 Subject: [PATCH] Fix stack alignment on OS X. --- Makefile | 4 ++-- upb/pb/decoder_x86.dasc | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c7befe5979..f929caf5e9 100644 --- a/Makefile +++ b/Makefile @@ -364,7 +364,7 @@ benchmarks/b.parsestream_googlemessage2.upb_jit: \ benchmarks/b.parsetoproto2_googlemessage1.upb_jit \ benchmarks/b.parsetoproto2_googlemessage2.upb_jit: \ - benchmarks/parsetoproto2.upb.cc benchmarks/google_messages.pb.cc + benchmarks/parsetoproto2.upb.cc benchmarks/google_messages.pb.cc $(LIBUPB) benchmarks/google_messages.proto.pb $(E) 'CXX benchmarks/parsetoproto2.upb.cc (benchmarks.SpeedMessage1, jit)' $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetoproto2_googlemessage1.upb_jit $< \ -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ @@ -417,7 +417,7 @@ benchmarks/b.parsetostruct_googlemessage2.proto2_compiled: \ benchmarks/b.parsetoproto2_googlemessage1.upb \ benchmarks/b.parsetoproto2_googlemessage2.upb: \ - benchmarks/parsetoproto2.upb.cc benchmarks/google_messages.pb.cc + benchmarks/parsetoproto2.upb.cc benchmarks/google_messages.pb.cc $(LIBUPB) benchmarks/google_messages.proto.pb $(E) 'CXX benchmarks/parsetoproto2.upb.cc (benchmarks.SpeedMessage1, nojit)' $(Q) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o benchmarks/b.parsetoproto2_googlemessage1.upb $< \ -DMESSAGE_CIDENT="benchmarks::SpeedMessage1" \ diff --git a/upb/pb/decoder_x86.dasc b/upb/pb/decoder_x86.dasc index b99e7454dd..30280863a6 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