Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
reflex-frp
GitHub Repository: reflex-frp/reflex-platform
Path: blob/develop/haskell-overlays/ghcjs-8.10-fast-weak/fast-weak.patch
1 views
1
diff --git a/lib/boot/shims/src/gc.js.pp b/lib/boot/shims/src/gc.js.pp
2
index 76321b2..a2cf416 100644
3
--- a/lib/boot/shims/src/gc.js.pp
4
+++ b/lib/boot/shims/src/gc.js.pp
5
@@ -444,6 +444,50 @@ function h$follow(obj, sp) {
6
} else if(typeof c.len === 'number' && c.buf instanceof ArrayBuffer) {
7
TRACE_GC("marking ByteArray");
8
MARK_OBJ(c);
9
+ } else if(c instanceof h$FastWeak) {
10
+ MARK_OBJ(c);
11
+ if(c.ticket !== null && !IS_MARKED(c.ticket)) {
12
+ 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 in
13
+ }
14
+ } else if(c instanceof h$FastWeakTicket) {
15
+ MARK_OBJ(c);
16
+ if(!IS_MARKED(c.val)) {
17
+ ADDW(c.val);
18
+ }
19
+ if(IS_MARKED(c.weak)) {
20
+ // In this case, the weak side has been marked first, which means it's been cleared; restore it
21
+ c.weak.ticket = c;
22
+ }
23
+ } else if(c instanceof h$FastWeakBag) {
24
+ MARK_OBJ(c);
25
+ 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 i
26
+ for(i = 0; i < c.tickets.length; i++) {
27
+ // Any nulls left in the array prior to checking on the tickets must be tickets that died in the last GC, so we ignore them
28
+ if(c.tickets[i] !== null) {
29
+ if(j !== i) {
30
+ c.tickets[i].pos = j;
31
+ }
32
+ if(!IS_MARKED(c.tickets[i])) {
33
+ // 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 in
34
+ c.tickets[j] = null;
35
+ } else if(j !== i) {
36
+ // We need to move the item
37
+ c.tickets[j] = c.tickets[i];
38
+ } // If it's marked and not moving, don't do anything
39
+ j++;
40
+ }
41
+ }
42
+ c.tickets.length = j; // Shrink the array if any nulls have been dropped
43
+ } else if(c instanceof h$FastWeakBagTicket) {
44
+ MARK_OBJ(c);
45
+ if(!IS_MARKED(c.val)) {
46
+ ADDW(c.val);
47
+ }
48
+ if(IS_MARKED(c.bag)) {
49
+ // In this case, the weak side has been marked first, which means it's been cleared; restore it
50
+ c.bag.tickets[c.pos] = c;
51
+ }
52
+
53
} else if(c instanceof h$Weak) {
54
MARK_OBJ(c);
55
} else if(c instanceof h$MVar) {
56
diff --git a/lib/boot/shims/src/weak.js.pp b/lib/boot/shims/src/weak.js.pp
57
index 8df313b..d537027 100644
58
--- a/lib/boot/shims/src/weak.js.pp
59
+++ b/lib/boot/shims/src/weak.js.pp
60
@@ -87,3 +87,27 @@ function h$finalizeWeak(w) {
61
RETURN_UBX_TUP2(r, 1);
62
}
63
}
64
+
65
+function h$FastWeak(ticket) {
66
+ this.ticket = ticket;
67
+ this.m = 0;
68
+}
69
+
70
+function h$FastWeakTicket(val) {
71
+ this.val = val;
72
+ this.weak = new h$FastWeak(this);
73
+ this.m = 0;
74
+}
75
+
76
+function h$FastWeakBag() {
77
+ this.tickets = [];
78
+ this.m = 0;
79
+}
80
+
81
+function h$FastWeakBagTicket(bag, val) {
82
+ this.val = val;
83
+ this.bag = bag;
84
+ this.pos = bag.tickets.length;
85
+ bag.tickets.push(this);
86
+ this.m = 0;
87
+};
88
89