Description
This issue stems from a discussion I started on the Julia Discourse forum.
In short, the code_native()
introspection function seems to work inconsistently (and sometimes break completely) on both Linux and macOS, based on results from several macOS and Linux setups with several Julia versions. I'll be giving the versioninfo()
for the two setups I used (macOS 10.13.5 on Apple hardware, Fedora 28 inside a Docker container), along with the results of several code_native()
calls to demonstrate the issue. My macOS setup is running the just-released Julia 0.6.4 as of writing this issue, but I experienced the exact same behavior on macOS with Julia 0.6.3.
macOS versioninfo()
Julia Version 0.6.4
Commit 9d11f62bcb (2018-07-09 19:09 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin14.5.0)
CPU: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
WORD_SIZE: 64
BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell MAX_THREADS=16)
LAPACK: libopenblas64_
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, haswell)
Fedora versioninfo()
Julia Version 0.6.3
Commit d55cadc (2018-05-28 20:20 UTC)
Platform Info:
OS: Linux (x86_64-redhat-linux)
CPU: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
WORD_SIZE: 64
BLAS: libopenblas (DYNAMIC_ARCH NO_AFFINITY Haswell MAX_THREADS=128)
LAPACK: libopenblasp.so.0
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, haswell)
Fedora Behavior
As a very simple test case, let's dump the assembly for +(::Int, ::Int)
:
julia> code_native(+, (Int, Int), :intel)
WARNING: Could not determine size of symbol
That's strange. If we try wrapping it in another function:
julia> f(a, b) = a + b
f (generic function with 1 method)
julia> code_native(f, (Int, Int), :intel)
.text
Filename: REPL[3]
push rbp
mov rbp, rsp
Source line: 1
lea rax, [rdi + rsi]
pop rbp
ret
nop word ptr [rax + rax]
That works, but I see no reason why dumping code for +
should fail. I also wonder if the WARNING
being displayed in place of an assembly printout is text emitted from external code (i.e. not Julia), since I can't think of what the "Could not determine size of symbol" would mean in Julia.
macOS Behavior
Repeating the same initial test as before:
julia> code_native(+, (Int, Int), :intel)
.section __TEXT,__text,regular,pure_instructions
Filename: int.jl
push ebp
dec eax
mov ebp, esp
Source line: 32
dec eax
lea eax, [edi + esi]
pop ebp
ret
Source line: 32
nop
nop
nop
nop
nop
nop
This time we get an assembly printout, but it's completely wrong. We're seeing only 32-bit instructions, though the actual code is of course 64-bit. Additionally, we've got needless dec eax
instructions interspersed, which I suspect aren't actually in the generated code. We can try wrapping +
in a function again, but we still get the broken ASM.
To show that this problem is limited to code_native
, we can try code_llvm
, which always gives identical (and correct) output:
julia> code_llvm(+, (Int, Int))
define i64 @"jlsys_+_60291"(i64, i64) #0 !dbg !5 {
top:
%2 = add i64 %1, %0
ret i64 %2
}
While I used the +
case as a minimal example, no code_native
call I've tried has produced correct (i.e. 64-bit) assembly on my macOS setup. Another user (by the username Per in the discussion linked above) was able to get code_native
working correctly with a source-built Julia 0.7.0-beta.214 on macOS High Sierra (10.13.x), but experienced the same macOS behavior I did with a downloaded 0.7.0-beta.0 and a downloaded 0.6.3 on macOS Sierra (10.12.x). Finally, with a locally-rebuilt system image in Julia 0.6.3 and macOS Sierra, Per was able to reproduce the WARNING
output I experienced on Fedora.