Skip to content

Commit f0eefe1

Browse files
author
Philip Guo
committed
continue massive refactoring to use new precomputed layout cod
1 parent 0479387 commit f0eefe1

File tree

1 file changed

+14
-176
lines changed

1 file changed

+14
-176
lines changed

PyTutorGAE/js/edu-python.js

Lines changed: 14 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)