Path: blob/develop/haskell-overlays/ghcjs-8.6-fast-weak/fast-weak.patch
1 views
diff --git a/lib/boot/shims/src/gc.js b/lib/boot/shims/src/gc.js1index 76321b2..a2cf416 1006442--- a/lib/boot/shims/src/gc.js3+++ b/lib/boot/shims/src/gc.js4@@ -444,6 +444,50 @@ function h$follow(obj, sp) {5} else if(typeof c.len === 'number' && c.buf instanceof ArrayBuffer) {6TRACE_GC("marking ByteArray");7MARK_OBJ(c);8+ } else if(c instanceof h$FastWeak) {9+ MARK_OBJ(c);10+ if(c.ticket !== null && !IS_MARKED(c.ticket)) {11+ c.ticket = null; // If the ticket isn't reachable, this will let it get cleaned up by the JS gc; if it is reachable, it'll fill this back in12+ }13+ } else if(c instanceof h$FastWeakTicket) {14+ MARK_OBJ(c);15+ if(!IS_MARKED(c.val)) {16+ ADDW(c.val);17+ }18+ if(IS_MARKED(c.weak)) {19+ // In this case, the weak side has been marked first, which means it's been cleared; restore it20+ c.weak.ticket = c;21+ }22+ } else if(c instanceof h$FastWeakBag) {23+ MARK_OBJ(c);24+ var j = 0; // j should always be equal to the number of not-yet-necessarily-dead tickets that have been traversed; this should always be less than or equal to i25+ for(i = 0; i < c.tickets.length; i++) {26+ // Any nulls left in the array prior to checking on the tickets must be tickets that died in the last GC, so we ignore them27+ if(c.tickets[i] !== null) {28+ if(j !== i) {29+ c.tickets[i].pos = j;30+ }31+ if(!IS_MARKED(c.tickets[i])) {32+ // If the ticket isn't reachable, this will let it get cleaned up by the JS gc; if it is reachable, it'll fill this back in33+ c.tickets[j] = null;34+ } else if(j !== i) {35+ // We need to move the item36+ c.tickets[j] = c.tickets[i];37+ } // If it's marked and not moving, don't do anything38+ j++;39+ }40+ }41+ c.tickets.length = j; // Shrink the array if any nulls have been dropped42+ } else if(c instanceof h$FastWeakBagTicket) {43+ MARK_OBJ(c);44+ if(!IS_MARKED(c.val)) {45+ ADDW(c.val);46+ }47+ if(IS_MARKED(c.bag)) {48+ // In this case, the weak side has been marked first, which means it's been cleared; restore it49+ c.bag.tickets[c.pos] = c;50+ }51+52} else if(c instanceof h$Weak) {53MARK_OBJ(c);54} else if(c instanceof h$MVar) {55diff --git a/lib/boot/shims/src/weak.js b/lib/boot/shims/src/weak.js56index 8df313b..d537027 10064457--- a/lib/boot/shims/src/weak.js58+++ b/lib/boot/shims/src/weak.js59@@ -87,3 +87,27 @@ function h$finalizeWeak(w) {60RETURN_UBX_TUP2(r, 1);61}62}63+64+function h$FastWeak(ticket) {65+ this.ticket = ticket;66+ this.m = 0;67+}68+69+function h$FastWeakTicket(val) {70+ this.val = val;71+ this.weak = new h$FastWeak(this);72+ this.m = 0;73+}74+75+function h$FastWeakBag() {76+ this.tickets = [];77+ this.m = 0;78+}79+80+function h$FastWeakBagTicket(bag, val) {81+ this.val = val;82+ this.bag = bag;83+ this.pos = bag.tickets.length;84+ bag.tickets.push(this);85+ this.m = 0;86+};878889