aboutsummaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/builtins.zc13
-rw-r--r--src/compiler/expr.zc1
2 files changed, 14 insertions, 0 deletions
diff --git a/src/compiler/builtins.zc b/src/compiler/builtins.zc
index 44ed3b1..fb2dcb2 100644
--- a/src/compiler/builtins.zc
+++ b/src/compiler/builtins.zc
@@ -856,6 +856,19 @@ int tdroppable(word t) {
}
// local i holds a value with a drop: one set on it, or one its type declares
int ldroppable(int i) { return (local_dropset && local_dropset[i]) || tdroppable(ltype[i]); }
+// x.spawn() on a mailbox struct snapshots the whole vm into a worker process, so an
+// owned value with a drop that is live there is dropped once in each process (6.15.4)
+int spawn_hint() {
+ int i = lbase;
+ if (!fchk || !local_dropset) return 0;
+ while (i < nloc) {
+ if (!empty(lstate[i]) && !isalias(i) && lstate[i] != S_BORROW && ldroppable(i) && hint_begin(tpack(), HINT_SMALL)) {
+ rt.put_s(lname[i]); rt.put_s(": has drop and is live at spawn; the worker's copy drops it too"); dg_close();
+ }
+ i++;
+ }
+ return 0;
+}
// entering o3 from normal code: the collector waits until the outermost region is left
int o3_enter_code() { callname(intern("rt.o3_enter")); op(O_DROP); return 0; }
// a fresh value with a drop that nothing holds: it is held in a hidden slot and
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc
index 7687394..1cd765b 100644
--- a/src/compiler/expr.zc
+++ b/src/compiler/expr.zc
@@ -1199,6 +1199,7 @@ word field(int c) {
st = xty;
if (rt.eq_w(n, "drop") && (is_op(s_lp) || is_op(s_eq)) && (isptr(st) || st == tword) && !(isptr(st) && st[4][0] == TY_STRUCT && tfindfield(st[4], n) >= 0)) return drop_member(c, borrowed);
if (rt.eq_w(n, "send") && is_op(s_lp) && isptr(st) && st[4][0] == TY_STRUCT && tfindfield(st[4], intern("__mailbox")) >= 0) send_check = 1;
+ if (rt.eq_w(n, "spawn") && is_op(s_lp) && isptr(st) && st[4][0] == TY_STRUCT && tfindfield(st[4], intern("__mailbox")) >= 0) spawn_hint();
if (st[0] == TY_ARR || st[0] == TY_DYN) {
if (pmatch) probe_member(st);
if (is_op(s_lp) && array_method(n)) { xaf = borrowed; return array_member(c, n); }