aboutsummaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/builtins.zc4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/compiler/builtins.zc b/src/compiler/builtins.zc
index fb2dcb2..be8c3b4 100644
--- a/src/compiler/builtins.zc
+++ b/src/compiler/builtins.zc
@@ -858,11 +858,13 @@ int tdroppable(word t) {
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)
+// a pointer to a struct with a mailbox: its drop knows a worker's copy closes nothing
+int mailbox_type(word t) { return t && isptr(t) && t[4][0] == TY_STRUCT && tfindfield(t[4], intern("__mailbox")) >= 0; }
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)) {
+ if (!empty(lstate[i]) && !isalias(i) && lstate[i] != S_BORROW && ldroppable(i) && !mailbox_type(ltype[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++;