@@ -560,28 +560,33 @@ function tree!(root::StackFrameTree{T}, all::Vector{UInt64}, lidict::Union{LineI
560560 return root
561561end
562562
563- # Print a "branch" starting at a particular level. This gets called recursively.
564- function tree (io:: IO , bt:: StackFrameTree , level:: Int , cols:: Int , fmt:: ProfileFormat , noisefloor:: Int )
565- level > fmt. maxdepth && return
566- isempty (bt. down) && return
567- # Order the line information
568- nexts = collect (values (bt. down))
569- lilist = collect (frame. frame for frame in nexts)
570- counts = collect (frame. count for frame in nexts)
571- # Generate the string for each line
572- strs = tree_format (lilist, counts, level, cols)
573- # Recurse to the next level
574- for i in liperm (lilist)
575- down = nexts[i]
576- count = down. count
577- count < fmt. mincount && continue
578- count < noisefloor && continue
579- str = strs[i]
580- println (io, isempty (str) ? " $count unknown stackframe" : str)
581- noisefloor_down = fmt. noisefloor > 0 ? floor (Int, fmt. noisefloor * sqrt (count)) : 0
582- tree (io, down, level + 1 , cols, fmt, noisefloor_down)
563+ # Print the stack frame tree starting at a particular root. Uses a worklist to
564+ # avoid stack overflows.
565+ function tree (io:: IO , bt:: StackFrameTree , cols:: Int , fmt:: ProfileFormat )
566+ worklist = [(bt, 0 , 0 , " " )]
567+ while ! isempty (worklist)
568+ (bt, level, noisefloor, str) = popfirst! (worklist)
569+ isempty (str) || println (io, str)
570+ level > fmt. maxdepth && continue
571+ isempty (bt. down) && continue
572+ # Order the line information
573+ nexts = collect (values (bt. down))
574+ lilist = collect (frame. frame for frame in nexts)
575+ counts = collect (frame. count for frame in nexts)
576+ # Generate the string for each line
577+ strs = tree_format (lilist, counts, level, cols)
578+ # Recurse to the next level
579+ for i in reverse (liperm (lilist))
580+ down = nexts[i]
581+ count = down. count
582+ count < fmt. mincount && continue
583+ count < noisefloor && continue
584+ str = strs[i]
585+ isempty (str) && (str = " $count unknown stackframe" )
586+ noisefloor_down = fmt. noisefloor > 0 ? floor (Int, fmt. noisefloor * sqrt (count)) : 0
587+ pushfirst! (worklist, (down, level + 1 , noisefloor_down, str))
588+ end
583589 end
584- nothing
585590end
586591
587592function tree (io:: IO , data:: Vector{UInt64} , lidict:: Union{LineInfoFlatDict, LineInfoDict} , cols:: Int , fmt:: ProfileFormat )
@@ -594,8 +599,7 @@ function tree(io::IO, data::Vector{UInt64}, lidict::Union{LineInfoFlatDict, Line
594599 warning_empty ()
595600 return
596601 end
597- level = 0
598- tree (io, root, level, cols, fmt, 0 )
602+ tree (io, root, cols, fmt)
599603 nothing
600604end
601605
0 commit comments