Fix stack alignment when lazily compiling scripted calls (bug 5871, r=ds).
authorDavid Anderson <dvander@alliedmods.net>
Tue Aug 20 23:59:11 2013 -0700 (2013-08-20)
changeset 4026684cf3490051
parent 4025 542dde661d5c
child 4027 d2c15108b468
Fix stack alignment when lazily compiling scripted calls (bug 5871, r=ds).
sourcepawn/jit/x86/jit_x86.cpp
     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);