[amd64] fix tailcall insn size (#5483)
authorBernhard Urban <bernhard.urban@xamarin.com>
Wed, 6 Sep 2017 12:28:20 +0000 (14:28 +0200)
committerGitHub <noreply@github.com>
Wed, 6 Sep 2017 12:28:20 +0000 (14:28 +0200)
commit79e94c43dcb8576f6e8c817ce13ae7bb2c196538
tree39652c2561f06d35bd561ca11c746dc5deb1a583
parentfc524c47564325aea4780a6a2d765ff40b424b98
[amd64] fix tailcall insn size (#5483)

commit
https://github.com/mono/mono/commit/9a634c1810aad46d30a674f3a97ab263dcd4272e
introduces a regression for
https://github.com/mono/coreclr/blob/mono/tests/src/JIT/Methodical/Invoke/25params/25param1c.il

```
Testing method of 25 parameters, all of int data type, tail.call
mono-sgen(46435,0x7fff9d34b3c0) malloc: *** error for object 0x101045400: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Process 46435 stopped
* thread #1, name = 'tid_307', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00007fff945c915f libsystem_malloc.dylib`malloc_error_break
libsystem_malloc.dylib`malloc_error_break:
->  0x7fff945c915f <+0>: pushq  %rbp
    0x7fff945c9160 <+1>: movq   %rsp, %rbp
    0x7fff945c9163 <+4>: nop
    0x7fff945c9164 <+5>: nopl   (%rax)
(lldb) mbt
* thread #1
  * frame #0: 0x00007fff945c915f libsystem_malloc.dylib`malloc_error_break
    frame #1: 0x00007fff945c5e81 libsystem_malloc.dylib`szone_error + 406
    frame #2: 0x00007fff945c7925 libsystem_malloc.dylib`small_free_list_remove_ptr_no_clear + 766
    frame #3: 0x00007fff945c7cb2 libsystem_malloc.dylib`free_small + 881
    frame #4: 0x00000001004d2110 mono-sgen`monoeg_g_free(ptr=0x0000000101083c00) at gmem.c:66
    frame #5: 0x0000000100007b64 mono-sgen`mono_codegen(cfg=0x000000010108c800) at mini.c:2300
    frame #6: 0x000000010000aedf mono-sgen`mini_method_compile(method=0x0000000100910310, opts=370239999, domain=0x000000010090ebd0, flags=JIT_FLAG_RUN_CCTORS, parts=0, aot_method_index=-1) at mini.c:3829
    frame #7: 0x000000010000edd0 mono-sgen`mono_jit_compile_method_inner(method=0x0000000100910310, target_domain=0x000000010090ebd0, opt=370239999, error=0x00007fff5fbfe048) at mini.c:4156
    frame #8: 0x000000010001459e mono-sgen`mono_jit_compile_method_with_opt(method=0x0000000100910310, opt=370239999, jit_only=0, error=0x00007fff5fbfe048) at mini-runtime.c:2127
    frame #9: 0x0000000100013e6d mono-sgen`mono_jit_compile_method(method=0x0000000100910310, error=0x00007fff5fbfe048) at mini-runtime.c:2173
    frame #10: 0x0000000100131eea mono-sgen`common_call_trampoline(regs=0x00007fff5fbfe128, code="H\x8bй\x01", m=0x0000000100910310, vt=0x0000000000000000, vtable_slot=0x0000000000000000, error=0x00007fff5fbfe048) at mini-trampolines.c:704
    frame #11: 0x00000001001313b7 mono-sgen`mono_magic_trampoline(regs=0x00007fff5fbfe128, code="H\x8bй\x01", arg=0x0000000100910310, tramp="����\b\x10\x03\x91") at mini-trampolines.c:835
```

turns out we smashed our code buffer.

Also, transform this comparison:

```
if (G_UNLIKELY (offset > (cfg->code_size - max_len - EXTRA_CODE_SPACE))) {

if (G_UNLIKELY ((offset + max_len + EXTRA_CODE_SPACE) > cfg->code_size)) {
```

we deal with unsigned values here, and if `max_len` is bigger then
`cfg->code_size`, we won't resize the buffer.
mono/mini/mini-amd64.c