forked from reflex-frp/reflex-platform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fast-weak.patch
85 lines (83 loc) · 3.29 KB
/
fast-weak.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
diff --git a/lib/boot/shims/src/gc.js b/lib/boot/shims/src/gc.js
index 384cd77..d21757a 100644
--- a/lib/boot/shims/src/gc.js
+++ b/lib/boot/shims/src/gc.js
@@ -435,6 +435,49 @@ function h$follow(obj, sp) {
TRACE_GC("adding static marks");
for(var i=0;i<s.length;i++) ADDW(s[i]);
}
+ } else if(c instanceof h$FastWeak) {
+ MARK_OBJ(c);
+ if(c.ticket !== null && !IS_MARKED(c.ticket)) {
+ 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
+ }
+ } else if(c instanceof h$FastWeakTicket) {
+ MARK_OBJ(c);
+ if(!IS_MARKED(c.val)) {
+ ADDW(c.val);
+ }
+ if(IS_MARKED(c.weak)) {
+ // In this case, the weak side has been marked first, which means it's been cleared; restore it
+ c.weak.ticket = c;
+ }
+ } else if(c instanceof h$FastWeakBag) {
+ MARK_OBJ(c);
+ 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
+ for(i = 0; i < c.tickets.length; i++) {
+ // 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
+ if(c.tickets[i] !== null) {
+ if(j !== i) {
+ c.tickets[i].pos = j;
+ }
+ if(!IS_MARKED(c.tickets[i])) {
+ // 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
+ c.tickets[j] = null;
+ } else if(j !== i) {
+ // We need to move the item
+ c.tickets[j] = c.tickets[i];
+ } // If it's marked and not moving, don't do anything
+ j++;
+ }
+ }
+ c.tickets.length = j; // Shrink the array if any nulls have been dropped
+ } else if(c instanceof h$FastWeakBagTicket) {
+ MARK_OBJ(c);
+ if(!IS_MARKED(c.val)) {
+ ADDW(c.val);
+ }
+ if(IS_MARKED(c.bag)) {
+ // In this case, the weak side has been marked first, which means it's been cleared; restore it
+ c.bag.tickets[c.pos] = c;
+ }
} else if(c instanceof h$Weak) {
MARK_OBJ(c);
} else if(c instanceof h$MVar) {
diff --git a/lib/boot/shims/src/weak.js b/lib/boot/shims/src/weak.js
index 0e68f51..3a9d4ab 100644
--- a/lib/boot/shims/src/weak.js
+++ b/lib/boot/shims/src/weak.js
@@ -81,3 +81,26 @@ function h$finalizeWeak(w) {
}
+function h$FastWeak(ticket) {
+ this.ticket = ticket;
+ this.m = 0;
+}
+
+function h$FastWeakTicket(val) {
+ this.val = val;
+ this.weak = new h$FastWeak(this);
+ this.m = 0;
+}
+
+function h$FastWeakBag() {
+ this.tickets = [];
+ this.m = 0;
+}
+
+function h$FastWeakBagTicket(bag, val) {
+ this.val = val;
+ this.bag = bag;
+ this.pos = bag.tickets.length;
+ bag.tickets.push(this);
+ this.m = 0;
+};