Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Update for Julia 0.7 and 1.0 #96

Closed
wants to merge 10 commits into from
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ language: julia
os:
- linux
julia:
- 0.5
- 0.6
- 0.7
- 1.0
- nightly
notifications:
email: false
Expand Down
2 changes: 1 addition & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
julia 0.5
julia 0.7
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it fine to drop both Julia 0.5 and 0.6 support on master? Otherwise some compatibility additions are needed.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, absolutely!

Gtk
GtkReactive 0.0.3
Cairo 0.5.1
Expand Down
60 changes: 42 additions & 18 deletions src/ProfileView.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ __precompile__()

module ProfileView

using Profile
using Colors

import Base: contains, isequal, show, mimewritable
import Base: isequal, show

include("tree.jl")
include("pvtree.jl")
Expand All @@ -14,13 +15,13 @@ using .PVTree

include("svgwriter.jl")

immutable TagData
struct TagData
ip::UInt
status::Int
end
const TAGNONE = TagData(UInt(0), -1)

type ProfileData
mutable struct ProfileData
img
lidict
imgtags
Expand All @@ -33,32 +34,32 @@ const gccolor = colorant"red"
const colors = distinguishable_colors(13, [bkg,fontcolor,gccolor],
lchoices=Float64[65, 70, 75, 80],
cchoices=Float64[0, 50, 60, 70],
hchoices=linspace(0, 330, 24))[4:end]
hchoices=range(0, stop=330, length=24))[4:end]

function have_display()
!is_unix() && return true
is_apple() && return true
!Sys.isunix() && return true
Sys.isapple() && return true
return haskey(ENV, "DISPLAY")
end

function __init__()
push!(LOAD_PATH, splitdir(@__FILE__)[1])
push!(LOAD_PATH, @__DIR__)
if (isdefined(Main, :IJulia) && !isdefined(Main, :PROFILEVIEW_USEGTK)) || !have_display()
eval(Expr(:import, :ProfileViewSVG))
@eval import ProfileViewSVG
@eval begin
view(data = Profile.fetch(); C = false, lidict = nothing, colorgc = true, fontsize = 12, combine = true, pruned = []) = ProfileViewSVG.view(data; C=C, lidict=lidict, colorgc=colorgc, fontsize=fontsize, combine=combine, pruned=pruned)
end
else
eval(Expr(:import, :ProfileViewGtk))
@eval import ProfileViewGtk
@eval begin
view(data = Profile.fetch(); C = false, lidict = nothing, colorgc = true, fontsize = 12, combine = true, pruned = []) = ProfileViewGtk.view(data; C=C, lidict=lidict, colorgc=colorgc, fontsize=fontsize, combine=combine, pruned=pruned)

closeall() = ProfileViewGtk.closeall()
@doc """
closeall()

Closes all windows opened by ProfileView.
""" -> closeall
"""
closeall() = ProfileViewGtk.closeall()
end
end
pop!(LOAD_PATH)
Expand All @@ -70,7 +71,7 @@ function prepare(data; C = false, lidict = nothing, colorgc = true, combine = tr
end

function prepare_data(data, lidict)
bt, counts = Profile.tree_aggregate(data)
bt, counts = tree_aggregate(data)
if isempty(counts)
Profile.warning_empty()
error("Nothing to view")
Expand All @@ -97,15 +98,15 @@ function prepare_data(data, lidict)
# Do code address lookups on all unique instruction pointers
uip = unique(vcat(bt...))
if lidict == nothing
lkup = Vector{StackFrame}[Profile.lookup(ip) for ip in uip]
lkup = Vector{StackTraces.StackFrame}[Profile.lookup(ip) for ip in uip]
lidict = Dict(zip(uip, lkup))
else
lkup = [lidict[ip] for ip in uip]
end
bt, uip, counts, lidict, lkup
end

prepare_data(::Void, ::Void) = nothing, nothing, nothing, nothing, nothing
prepare_data(::Nothing, ::Nothing) = nothing, nothing, nothing, nothing, nothing

function prepare_image(bt, uip, counts, lidict, lkup, C, colorgc, combine,
pruned)
Expand Down Expand Up @@ -170,7 +171,7 @@ function svgwrite(filename::AbstractString; kwargs...)
end


mimewritable(::MIME"image/svg+xml", pd::ProfileData) = true
Base.showable(::MIME"image/svg+xml", pd::ProfileData) = true

function show(f::IO, ::MIME"image/svg+xml", pd::ProfileData)
img = pd.img
Expand Down Expand Up @@ -267,7 +268,7 @@ function buildtags!(rowtags, parent, level)
end
t = rowtags[level]
for c in parent
t[c.data.hspan] = TagData(c.data.ip, c.data.status)
t[c.data.hspan] .= Ref(TagData(c.data.ip, c.data.status))
buildtags!(rowtags, c, level+1)
end
end
Expand Down Expand Up @@ -318,10 +319,10 @@ end

function fillrow!(img, j, rng::UnitRange{Int}, colorindex, colorlen, regcolor, gccolor, status)
if status > 0
img[rng,j] = gccolor
img[rng,j] .= gccolor
return colorindex
else
img[rng,j] = regcolor
img[rng,j] .= regcolor
return mod1(colorindex+1, colorlen)
end
end
Expand Down Expand Up @@ -407,4 +408,27 @@ function pushpruned!(pruned_ips, pruned, lidict)
end
end

## A tree representation
# Identify and counts repetitions of all unique backtraces
function tree_aggregate(data::Vector{UInt64})
iz = findall(iszero, data) # find the breaks between backtraces
treecount = Dict{Vector{UInt64},Int}()
istart = 1
for iend in iz
tmp = data[iend - 1 : -1 : istart]
treecount[tmp] = get(treecount, tmp, 0) + 1
istart = iend + 1
end
bt = Vector{Vector{UInt64}}(undef, 0)
counts = Vector{Int}(undef, 0)
for (k, v) in treecount
if !isempty(k)
push!(bt, k)
push!(counts, v)
end
end
return (bt, counts)
end


end
18 changes: 9 additions & 9 deletions src/ProfileViewGtk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ using Graphics

using Gtk.GConstants.GdkModifierType: SHIFT, CONTROL, MOD1

type ZoomCanvas
mutable struct ZoomCanvas
bb::BoundingBox # in user-coordinates
c::Canvas
end

function __init__()
eval(Expr(:import, :ProfileView))
@eval import ProfileView
end

function closeall()
Expand All @@ -24,13 +24,13 @@ function closeall()
nothing
end

const window_wrefs = WeakKeyDict{Gtk.GtkWindowLeaf,Void}()
const window_wrefs = WeakKeyDict{Gtk.GtkWindowLeaf,Nothing}()

function view(data = Profile.fetch(); lidict=nothing, kwargs...)
bt, uip, counts, lidict, lkup = ProfileView.prepare_data(data, lidict)
# Display in a window
c = canvas(UserUnit)
setproperty!(widget(c), :expand, true)
set_gtk_property!(widget(c), :expand, true)
f = Frame(c)
tb = Toolbar()
bx = Box(:v)
Expand All @@ -40,8 +40,8 @@ function view(data = Profile.fetch(); lidict=nothing, kwargs...)
tb_save_as = ToolButton("gtk-save-as")
push!(tb, tb_open)
push!(tb, tb_save_as)
signal_connect(open_cb, tb_open, "clicked", Void, (), false, (widget(c),kwargs))
signal_connect(save_as_cb, tb_save_as, "clicked", Void, (), false, (widget(c),data,lidict,kwargs))
signal_connect(open_cb, tb_open, "clicked", Nothing, (), false, (widget(c),kwargs))
signal_connect(save_as_cb, tb_save_as, "clicked", Nothing, (), false, (widget(c),data,lidict,kwargs))
win = Window(bx, "Profile")
GtkReactive.gc_preserve(win, c)
# Register the window with closeall
Expand All @@ -57,17 +57,17 @@ function view(data = Profile.fetch(); lidict=nothing, kwargs...)
# Ctrl-w and Ctrl-q destroy the window
signal_connect(win, "key-press-event") do w, evt
if evt.state == CONTROL && (evt.keyval == UInt('q') || evt.keyval == UInt('w'))
@schedule destroy(w)
@async destroy(w)
nothing
end
end

showall(win)
Gtk.showall(win)
end

function viewprof(c, bt, uip, counts, lidict, lkup; C = false, colorgc = true, fontsize = 12, combine = true, pruned=[])
img, lidict, imgtags = ProfileView.prepare_image(bt, uip, counts, lidict, lkup, C, colorgc, combine, pruned)
img24 = UInt32[reinterpret(UInt32, convert(RGB24, img[i,j])) for i = 1:size(img,1), j = size(img,2):-1:1]'
img24 = Matrix(UInt32[reinterpret(UInt32, convert(RGB24, img[i,j])) for i = 1:size(img,1), j = size(img,2):-1:1]')
fv = XY(0.0..size(img24,2), 0.0..size(img24,1))
zr = Signal(ZoomRegion(fv, fv))
sigrb = init_zoom_rubberband(c, zr)
Expand Down
2 changes: 1 addition & 1 deletion src/ProfileViewSVG.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ __precompile__()
module ProfileViewSVG

function __init__()
eval(Expr(:import, :ProfileView))
@eval import ProfileView
end

function view(data = Profile.fetch(); C = false, lidict = nothing, colorgc = true, fontsize = 12, combine = true, pruned = true)
Expand Down
8 changes: 4 additions & 4 deletions src/pvtree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using ..Tree
export PVData, buildgraph!, prunegraph!

# ProfileView data we need attached to each node of the graph:
type PVData
mutable struct PVData
ip::UInt # the instruction pointer
hspan::UnitRange{Int} # horizontal span (used as the x-axis in display)
status::Int # nonzero for special handling, (e.g., gc events)
Expand Down Expand Up @@ -37,9 +37,9 @@ function buildgraph!(parent::Node, bt::Vector{Vector{UInt}}, counts::Vector{Int}
end
end
ngroups = length(dorder)
group = Vector{Vector{Int}}(ngroups) # indices in bt that have the same sortorder
n = Array{Int}(ngroups) # aggregated counts for this group
order = Array{Int}(ngroups)
group = Vector{Vector{Int}}(undef, ngroups) # indices in bt that have the same sortorder
n = Array{Int}(undef, ngroups) # aggregated counts for this group
order = Array{Int}(undef, ngroups)
i = 1
for (key, v) in dorder
order[i] = key
Expand Down
4 changes: 2 additions & 2 deletions src/svgwriter.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const snapsvgjs = joinpath(dirname(@__FILE__), "..", "templates", "snap.svg-min.js")
const viewerjs = joinpath(dirname(@__FILE__), "viewer.js")
const snapsvgjs = joinpath(@__DIR__, "..", "templates", "snap.svg-min.js")
const viewerjs = joinpath(@__DIR__, "viewer.js")

function escape_script(js::AbstractString)
return replace(js, "]]", "] ]")
Expand Down
23 changes: 12 additions & 11 deletions src/tree.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Tree

import Base: start, done, next, show
import Base: iterate, show

export Node,
addchild,
Expand All @@ -16,30 +16,30 @@ export Node,
# Any missing links (e.g., "c" does not have a sibling) link back to itself (c.sibling == c)
# With this organization, no arrays need to be allocated.

type Node{T}
mutable struct Node{T}
data::T
parent::Node{T}
child::Node{T}
sibling::Node{T}

# Constructor for the root of the tree
function (::Type{Node{T}}){T}(data::T)
function Node{T}(data) where T
n = new{T}(data)
n.parent = n
n.child = n
n.sibling = n
n
end
# Constructor for all others
function (::Type{Node{T}}){T}(data::T, parent::Node)
function Node{T}(data, parent::Node) where T
n = new{T}(data, parent)
n.child = n
n.sibling = n
n
end
end
Node{T}(data::T) = Node{T}(data)
Node{T}(data::T, parent::Node{T}) = Node{T}(data, parent)
Node(data::T) where {T} = Node{T}(data)
Node(data, parent::Node{T}) where {T} = Node{T}(data, parent)

function lastsibling(sib::Node)
newsib = sib.sibling
Expand All @@ -50,7 +50,7 @@ function lastsibling(sib::Node)
sib
end

function addsibling{T}(oldersib::Node{T}, data::T)
function addsibling(oldersib::Node{T}, data) where T
if oldersib.sibling != oldersib
error("Truncation of sibling list")
end
Expand All @@ -59,7 +59,7 @@ function addsibling{T}(oldersib::Node{T}, data::T)
youngersib
end

function addchild{T}(parent::Node{T}, data::T)
function addchild(parent::Node{T}, data) where T
newc = Node(data, parent)
prevc = parent.child
if prevc == parent
Expand All @@ -80,9 +80,10 @@ show(io::IO, n::Node) = print(io, n.data)
# for c in parent
# # do something
# end
start(n::Node) = n.child
done(n::Node, state::Node) = n == state
next(n::Node, state::Node) = state, state == state.sibling ? n : state.sibling
function iterate(n::Node, state = n.child)
n == state && return nothing
return state, state == state.sibling ? n : state.sibling
end

function showedges(io::IO, parent::Node, printfunc = identity)
str = printfunc(parent.data)
Expand Down
6 changes: 3 additions & 3 deletions test/test.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using Profile
using ProfileView

function profile_test(n)
for i = 1:n
A = randn(100,100,20)
m = maximum(A)
Afft = fft(A)
Am = mapslices(sum, A, 2)
Am = mapslices(sum, A, dims = 2)
B = A[:,:,5]
Bsort = mapslices(sort, B, 1)
Bsort = mapslices(sort, B, dims = 1)
b = rand(100)
C = B.*b
end
Expand Down
5 changes: 3 additions & 2 deletions test/tree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ root = Tree.Node(0)
@assert Tree.isleaf(root)
nchildren = 0
for c in root
nchildren += 1
global nchildren += 1
end
@assert nchildren == 0
c1 = Tree.addchild(root, 1)
Expand All @@ -17,7 +17,7 @@ c22 = Tree.addchild(c2, 5)
nchildren = 0
for c in root
@assert !Tree.isroot(c)
nchildren += 1
global nchildren += 1
end
@assert nchildren == 3
@assert Tree.isleaf(c1)
Expand All @@ -30,5 +30,6 @@ end
children2 = [c21,c22]
i = 0
for c in c2
global i
@assert c == children2[i+=1]
end