JuliaLang/julia — pull request #7464 by timholy (2014-06-30 11:44:16+00:00)
Title: WIP: More instrumentation (memory allocation, also fixes #7259)

This adds the ability to track the amount of memory allocated by each line of code. It mimics the `--code-coverage` functionality, writing a `filename.jl.mlc` (mlc = `malloc`, perhaps there's a better extension?) listing the number of bytes allocated by each line.

It's already quite useful, but not perfect, and I confess to not really understanding what's wrong. Here's a test script:
```julia
function alloc1()
s = 0
for x = 1:3
s += x
end
A = zeros(4000, 7000)
s2 = sum(A)
nothing
end

function alloc2()
s = 0
for x = 1:3
s += x/2 # deliberately type-unstable
end
s
end

function runner()
alloc1()
alloc2()
end

runner()
println("Something")
println("Clearing allocation data to eliminate memory allocated during JITting")
clear_malloc_data()
runner()
```
which you use like this
```
julia --track-allocation=user logallocation.jl
```
Here's the resulting `.mlc` file:
```
- function alloc1()
0 s = 0
0 for x = 1:3
0 s += x
- end
0 A = zeros(4000, 7000)
224000048 s2 = sum(A)
0 nothing
- end
-
- function alloc2()
0 s = 0
0 for x = 1:3
64 s += x/2 # note: type-unstable
- end
32 s
- end
-
- function runner()
192 alloc1()
0 alloc2()
- end
-
- runner()
- println("Something")
- println("Clearing allocation data to eliminate memory allocated during JITting")
- clear_malloc_data()
- runner()
```

The core algorithm is to look for a change in `jl_gc_total_bytes` since the last line.

Observations:
- There seems to be an off-by-one bug even though I attempted to insert the memory-check instructions after each line had already been built.
- Anything run from the global scope (for example, a test script in a package's `tests/`) shows allocation on the first line of the function.