 
 : flat ( -- tree )
     get-raw-profile-data (flat) ;
+
+: nth-or-last ( n seq -- elt )
+    [ drop f ] [
+        2dup bounds-check? [ nth ] [ nip last ] if
+    ] if-empty ;
+
+:: collect-cross-section ( samples depth -- cross-section )
+    IH{ } clone :> per-word-samples
+    samples [| sample |
+        depth sample sample-callstack [ ignore-word? ] trim-tail nth-or-last :> word
+        word [
+            word per-word-samples sample counts+at
+        ] when
+    ] each
+    per-word-samples [ f depth <profile-node> ] assoc-map ;
+
+:: (cross-section) ( depth samples -- flat )
+    samples collect-threads
+    [ [ depth collect-cross-section ] <profile-root-node> ] assoc-map ;
+
+: cross-section ( depth -- tree )
+    get-raw-profile-data (cross-section) ;
 
 : depth. ( depth -- )
     [ "| " write ] times ;

    } cleave ;

:: (profile-node.) ( word node depth -- )
    depth depth. node times. ": " write word pprint-short nl
    node children>> depth 1 + (profile.) ;

: (profile.) ( nodes depth -- )


DEFER: (profile.)

:: times. ( node depth -- )
    node {
        [ depth>> number>string 3 CHAR: \s pad-head write " " write depth depth. ]
        [ total-time>> duration. ]
        [ " (GC:" write [ gc-time>> ] [ total-time>> ] bi percentage. ]
        [ ", JIT:" write [ jit-time>> ] [ total-time>> ] bi percentage. ]
