@@ -717,185 +717,20 @@ function renderDataStructures(curEntry, vizDiv) {
717717 $ ( vizDiv + " #stack" ) . append ( '<div id="stackHeader">Frames</div>' ) ;
718718
719719
720- // first build up a list of lists representing the locations of TOP-LEVEL heap objects to be rendered.
721- // doing so decouples the data format of curEntry from the nitty-gritty HTML rendering code,
722- // which gives us more flexibility in experimenting with layout strategies.
723- //
724- // each outer list represents a "row" in the heap layout (represented via, say, div elements)
725- // and each inner list represents "columns" within a row (represented via, say, table td elements)
726- var toplevelHeapLayout = [ ] ;
727- var toplevelHeapLayoutIDs = { } ; // set of IDs contained within toplevelHeapLayout
728- var alreadyLaidObjectIDs = { } ; // set of IDs of objects that have already been laid out
729- // (not necessarily just in toplevelHeapLayout since some elements
730- // are EMBEDDED within other heap objects)
731-
732-
733- function layoutHeapObject ( ref ) {
734-
735- function layoutHeapObjectHelper ( id , row /* list of IDs */ , isTopLevel ) {
736- if ( alreadyLaidObjectIDs [ id ] == undefined ) {
737-
738- // Only push to row if isTopLevel since it only stores top-level objects ...
739- if ( isTopLevel ) {
740- row . push ( id ) ;
741- }
742-
743- // but ALWAYS record that this object has already been laid out, no matter what
744- alreadyLaidObjectIDs [ id ] = 1 ;
745-
746- // heuristic for laying out 1-D linked data structures: check for enclosing elements that are
747- // structurally identical and then lay them out as siblings in the same "row"
748- var heapObj = curEntry . heap [ id ] ;
749- assert ( heapObj ) ;
750-
751- if ( heapObj [ 0 ] == 'LIST' || heapObj [ 0 ] == 'TUPLE' ) {
752- jQuery . each ( heapObj , function ( ind , child ) {
753- if ( ind < 1 ) return ; // skip type tag
754-
755- if ( ! isPrimitiveType ( child ) ) {
756- var childID = getRefID ( child ) ;
757- if ( structurallyEquivalent ( heapObj , curEntry . heap [ childID ] ) ) {
758- layoutHeapObjectHelper ( childID , row , true ) ;
759- }
760- else {
761- layoutHeapObjectHelper ( childID , null , false /* render embedded within heapObj */ ) ;
762- }
763- }
764- } ) ;
765- }
766- else if ( heapObj [ 0 ] == 'SET' ) {
767- jQuery . each ( heapObj , function ( ind , child ) {
768- if ( ind < 1 ) return ; // skip type tag
769- if ( ! isPrimitiveType ( child ) ) {
770- layoutHeapObjectHelper ( getRefID ( child ) , null , false /* render embedded within heapObj */ ) ;
771- }
772- } ) ;
773- }
774- else if ( heapObj [ 0 ] == 'DICT' ) {
775- jQuery . each ( heapObj , function ( ind , child ) {
776- if ( ind < 1 ) return ; // skip type tag
777-
778- var dictKey = child [ 0 ] ;
779- if ( ! isPrimitiveType ( dictKey ) ) {
780- layoutHeapObjectHelper ( getRefID ( dictKey ) , null , false /* render embedded within heapObj */ ) ;
781- }
782-
783- var dictVal = child [ 1 ] ;
784- if ( ! isPrimitiveType ( dictVal ) ) {
785- var childID = getRefID ( dictVal ) ;
786- if ( structurallyEquivalent ( heapObj , curEntry . heap [ childID ] ) ) {
787- layoutHeapObjectHelper ( childID , row , true ) ;
788- }
789- else {
790- layoutHeapObjectHelper ( childID , null , false /* render embedded within heapObj */ ) ;
791- }
792- }
793- } ) ;
794- }
795- else if ( heapObj [ 0 ] == 'INSTANCE' ) {
796- jQuery . each ( heapObj , function ( ind , child ) {
797- if ( ind < 2 ) return ; // skip type tag and class name
798-
799- // instance keys are always strings, so no need to recurse
800- assert ( typeof child [ 0 ] == "string" ) ;
801-
802- var instVal = child [ 1 ] ;
803- if ( ! isPrimitiveType ( instVal ) ) {
804- var childID = getRefID ( instVal ) ;
805- if ( structurallyEquivalent ( heapObj , curEntry . heap [ childID ] ) ) {
806- layoutHeapObjectHelper ( childID , row , true ) ;
807- }
808- else {
809- layoutHeapObjectHelper ( childID , null , false /* render embedded within heapObj */ ) ;
810- }
811- }
812- } ) ;
813- }
814- else if ( heapObj [ 0 ] == 'CLASS' ) {
815- jQuery . each ( heapObj , function ( ind , child ) {
816- if ( ind < 3 ) return ; // skip type tag, class name, and superclass names
817- // class attr keys are always strings, so no need to recurse
818-
819- var classAttrVal = child [ 1 ] ;
820- if ( ! isPrimitiveType ( classAttrVal ) ) {
821- layoutHeapObjectHelper ( getRefID ( classAttrVal ) , null , false /* render embedded within heapObj */ ) ;
822- }
823- } ) ;
824- }
825- }
826- }
827-
828- var id = getRefID ( ref ) ;
829- var newRow = [ ] ;
830-
831- layoutHeapObjectHelper ( id , newRow , true ) ;
832- if ( newRow . length > 0 ) {
833- toplevelHeapLayout . push ( newRow ) ;
834- $ . each ( newRow , function ( i , e ) {
835- toplevelHeapLayoutIDs [ e ] = 1 ;
836- } ) ;
837- }
838- }
839-
840-
841-
842- // variables are displayed in the following order, so lay out heap objects in the same order:
843- // - globals
844- // - stack entries (regular and zombies)
845-
846- // if there are multiple aliases to the same object, we want to render
847- // the one "deepest" in the stack, so that we can hopefully prevent
848- // objects from jumping around as functions are called and returned.
849- // e.g., if a list L appears as a global variable and as a local in a
850- // function, we want to render L when rendering the global frame.
851- //
852- // this is straightforward: just go through globals first and then
853- // each stack frame in order :)
854-
855- $ . each ( curEntry . ordered_globals , function ( i , varname ) {
856- var val = curEntry . globals [ varname ] ;
857- // (use '!==' to do an EXACT match against undefined)
858- if ( val !== undefined ) { // might not be defined at this line, which is OKAY!
859- if ( ! isPrimitiveType ( val ) ) {
860- layoutHeapObject ( val ) ;
861- //console.log('global:', varname, getRefID(val));
862- }
863- }
864- } ) ;
865-
866- $ . each ( curEntry . stack_to_render , function ( i , frame ) {
867- if ( frame . ordered_varnames . length > 0 ) {
868- $ . each ( frame . ordered_varnames , function ( xxx , varname ) {
869- var val = frame . encoded_locals [ varname ] ;
870720
871- if ( ! isPrimitiveType ( val ) ) {
872- layoutHeapObject ( val ) ;
873- //console.log(frame.func_name + ':', varname, getRefID(val));
874- }
875- } ) ;
876- }
877- } ) ;
721+ // Heap object rendering phase:
878722
879723
880- // print toplevelHeapLayout
881- /*
882- $.each(toplevelHeapLayout, function(i, elt) {
883- console.log(elt);
884- });
885- console.log('---');
886- */
887724
888725 // VERY VERY experimental!!!
889726 // when doing this for realz, convert to using d3 and use row ID tag
890727 // as unique object ID for object constancy.
891728 var curEntryLayout = curTraceLayouts [ curInstr ] ;
892- toplevelHeapLayout = curEntryLayout . map ( function ( row )
893- { return row . slice ( 1 , row . length ) ; // KRAZY!!! remove row ID tag for now
894- } ) ;
895-
896729
730+ var toplevelHeapLayout = curEntryLayout . map ( function ( row ) {
731+ return row . slice ( 1 , row . length ) ; // KRAZY!!! remove row ID tag for now
732+ } ) ;
897733
898- // Heap object rendering phase:
899734
900735
901736 // Key: CSS ID of the div element representing the stack frame variable
@@ -909,12 +744,14 @@ function renderDataStructures(curEntry, vizDiv) {
909744 var heap_pointer_src_id = 1 ; // increment this to be unique for each heap_pointer_src_*
910745
911746
912- var renderedObjectIDs = { } ; // set (TODO: refactor all sets to use d3.map)
747+ var renderedObjectIDs = d3 . map ( ) ;
913748
914- // count all toplevelHeapLayoutIDs as already rendered since we will render them
749+ // count everything in toplevelHeapLayout as already rendered since we will render them
915750 // in the d3 .each() statement labeled 'FOOBAR' (might be confusing!)
916- $ . each ( toplevelHeapLayoutIDs , function ( k , v ) {
917- renderedObjectIDs [ k ] = v ;
751+ $ . each ( toplevelHeapLayout , function ( xxx , row ) {
752+ for ( var i = 0 ; i < row . length ; i ++ ) {
753+ renderedObjectIDs . set ( row [ i ] , 1 ) ;
754+ }
918755 } ) ;
919756
920757
@@ -978,8 +815,9 @@ function renderDataStructures(curEntry, vizDiv) {
978815
979816
980817 function renderCompoundObject ( objID , d3DomElement , isTopLevel ) {
981- if ( ! isTopLevel && ( renderedObjectIDs [ objID ] != undefined ) ) {
982- // TODO: render jsPlumb arrow source since this heap object has already been rendered
818+ if ( ! isTopLevel && renderedObjectIDs . has ( objID ) ) {
819+ // render jsPlumb arrow source since this heap object has already been rendered
820+ // (or will be rendered soon)
983821
984822 // add a stub so that we can connect it with a connector later.
985823 // IE needs this div to be NON-EMPTY in order to properly
@@ -1005,7 +843,7 @@ function renderDataStructures(curEntry, vizDiv) {
1005843 d3DomElement = $ ( '#heap_object_' + objID ) ;
1006844
1007845
1008- renderedObjectIDs [ objID ] = 1 ;
846+ renderedObjectIDs . set ( objID , 1 ) ;
1009847
1010848 var obj = curEntry . heap [ objID ] ;
1011849 assert ( $ . isArray ( obj ) ) ;
0 commit comments