Fix stack alignment when lazily compiling scripted calls (bug 5871, r=ds).
Fix stack alignment when lazily compiling scripted calls (
bug 5871, r=ds).
1.1 --- a/sourcepawn/jit/x86/jit_x86.cpp Mon Aug 19 20:58:02 2013 -0700
1.2 +++ b/sourcepawn/jit/x86/jit_x86.cpp Tue Aug 20 23:59:11 2013 -0700
1.3 @@ -1550,27 +1550,26 @@
1.4 // need to patch.
1.5 __ movl(eax, Operand(esp, 0));
1.6
1.7 - // Align the stack. Unfortunately this is a pretty careful dance based
1.8 - // on the number of words we push (4 args, 1 saved esp), and someday
1.9 - // we should look into automating this.
1.10 - __ movl(edx, esp);
1.11 - __ andl(esp, 0xfffffff0);
1.12 - __ subl(esp, 12);
1.13 - __ push(edx);
1.14 + // We need to push 4 arguments, and one of them will need an extra word
1.15 + // on the stack. Allocate a big block so we're aligned, subtracting
1.16 + // 4 because we got here via a call.
1.17 + static const size_t kStackNeeded = 5 * sizeof(void *);
1.18 + static const size_t kStackReserve = ke::Align(kStackNeeded, 16) - sizeof(void *);
1.19 + __ subl(esp, kStackReserve);
1.20
1.21 - // Push arguments.
1.22 - __ push(eax);
1.23 - __ subl(esp, 4);
1.24 - __ movl(Operand(esp, 0), esp);
1.25 - __ push(thunk->pcode_offset);
1.26 - __ push(intptr_t(rt_));
1.27 + // Set arguments.
1.28 + __ movl(Operand(esp, 3 * sizeof(void *)), eax);
1.29 + __ lea(edx, Operand(esp, 4 * sizeof(void *)));
1.30 + __ movl(Operand(esp, 2 * sizeof(void *)), edx);
1.31 + __ movl(Operand(esp, 1 * sizeof(void *)), intptr_t(thunk->pcode_offset));
1.32 + __ movl(Operand(esp, 0 * sizeof(void *)), intptr_t(rt_));
1.33 +
1.34 __ call(ExternalAddress((void *)CompileFromThunk));
1.35 - __ movl(edx, Operand(esp, 8));
1.36 - __ movl(esp, Operand(esp, 16));
1.37 + __ movl(edx, Operand(esp, 4 * sizeof(void *)));
1.38 + __ addl(esp, kStackReserve);
1.39 __ testl(eax, eax);
1.40 __ j(not_zero, &error);
1.41 - __ call(edx);
1.42 - __ ret();
1.43 + __ jmp(edx);
1.44
1.45 __ bind(&error);
1.46 __ movl(Operand(cipAddr()), thunk->pcode_offset);