JIT bugfix: align stack properly on getbytes_slow.

pull/13171/head
Josh Haberman 10 years ago
parent 00c36ece20
commit 0c7eb664fc
  1. 32
      upb/pb/compile_decoder_x64.dasc
  2. 596
      upb/pb/compile_decoder_x64.h

@ -327,29 +327,29 @@ static void emit_static_asm(jitcompiler *jc) {
| jmp <1 | jmp <1
| |
| // For getting a value that spans a buffer seam. Falls back to C. | // For getting a value that spans a buffer seam. Falls back to C.
| // Args: rdi=C decoding function (prototype: int f(upb_pbdecoder*, void*)) |.macro getvalue_slow, func, bytes
asmlabel(jc, "getvalue_slow"); | sub rsp, 8 // Need stack space for func to write value to.
|->getvalue_slow:
| sub rsp, 16 // Stack is [8-byte value, 8-byte func pointer]
| mov [rsp + 8], rdi // Need to preserve fptr across suspends.
|1: |1:
| mov qword [rsp], 0 // For parsing routines that only parse 32 bits. | mov qword [rsp], 0 // For parsing routines that only parse 32 bits.
| mov ARG1_64, DECODER | mov ARG1_64, DECODER
| mov ARG2_64, rsp | mov ARG2_64, rsp
| mov DECODER->checkpoint, PTR | mov DECODER->checkpoint, PTR
| commit_regs | commit_regs
| call aword [rsp + 8] | callp func
| load_regs | load_regs
| test eax, eax | test eax, eax
| jns >2 | jns >2
| // Success; return parsed data (in rdx AND xmm0). | // Success; return parsed data (in rdx AND xmm0).
| mov rdx, [rsp] | mov rdx, [rsp]
| movsd xmm0, qword [rsp] | movsd xmm0, qword [rsp]
| add rsp, 16 | add rsp, 8
| sub PTR, bytes // Bias our buffer pointer to rejoin the fast-path.
| mov DECODER->ptr, PTR
| ret | ret
|2: |2:
| call ->exitjit // Return eax from decode function. | call ->exitjit // Return eax from decode function.
| jmp <1 | jmp <1
|.endmacro
| |
asmlabel(jc, "parse_unknown"); asmlabel(jc, "parse_unknown");
| // Args: edx=fieldnum, cl=wire type | // Args: edx=fieldnum, cl=wire type
@ -385,20 +385,12 @@ static void emit_static_asm(jitcompiler *jc) {
asmlabel(jc, "skip_decode_f32_fallback"); asmlabel(jc, "skip_decode_f32_fallback");
|->skipf32_fallback: |->skipf32_fallback:
|->decodef32_fallback: |->decodef32_fallback:
| mov64 rdi, (uintptr_t)upb_pbdecoder_decode_f32 | getvalue_slow upb_pbdecoder_decode_f32, 4
| call ->getvalue_slow
| sub PTR, 4
| mov DECODER->ptr, PTR
| ret
| |
asmlabel(jc, "skip_decode_f64_fallback"); asmlabel(jc, "skip_decode_f64_fallback");
|->skipf64_fallback: |->skipf64_fallback:
|->decodef64_fallback: |->decodef64_fallback:
| mov64 rdi, (uintptr_t)upb_pbdecoder_decode_f64 | getvalue_slow upb_pbdecoder_decode_f64, 8
| call ->getvalue_slow
| sub PTR, 8
| mov DECODER->ptr, PTR
| ret
| |
| // Called for varint >= 1 byte. | // Called for varint >= 1 byte.
asmlabel(jc, "skip_decode_v32_fallback"); asmlabel(jc, "skip_decode_v32_fallback");
@ -476,11 +468,7 @@ static void emit_static_asm(jitcompiler *jc) {
asmlabel(jc, "decode_varint_slow"); asmlabel(jc, "decode_varint_slow");
|->decode_varint_slow: |->decode_varint_slow:
| // Slow path: end of buffer or error (varint length >= 10). | // Slow path: end of buffer or error (varint length >= 10).
| mov64 rdi, (uintptr_t)upb_pbdecoder_decode_varint_slow | getvalue_slow upb_pbdecoder_decode_varint_slow, 1
| call ->getvalue_slow
| sub PTR, 1
| mov DECODER->ptr, PTR
| ret
| |
| // Args: rsi=expected tag, return=rax (DECODE_{OK,MISMATCH}) | // Args: rsi=expected tag, return=rax (DECODE_{OK,MISMATCH})
asmlabel(jc, "checktag_fallback"); asmlabel(jc, "checktag_fallback");

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save