diff options
Diffstat (limited to 'src/compiler')
| -rw-r--r-- | src/compiler/builtins.zc | 13 | ||||
| -rw-r--r-- | src/compiler/expr.zc | 1 |
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); } |
