From ccd55b7b4e3185dcb186c9137c704095f4f89130 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Wed, 30 Jan 2019 16:22:42 -0800 Subject: [PATCH] Bug 1513614 - Preemptively register a outline typed object owner in the whole cell buffer, r=jonco --HG-- extra : topic : TO.preempt extra : rebase_source : c9a7998a0a77b7ed14bebcd820e4ae2edd23dbc6 extra : amend_source : a0e9aa46c56c98f6740b438812d343ad4027e39b --- js/src/builtin/TypedObject.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 4c25c1fa9471..4a052e5b8aee 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -1541,10 +1541,23 @@ void OutlineTypedObject::setOwnerAndData(JSObject* owner, uint8_t* data) { owner_ = owner; data_ = data; - // Trigger a post barrier when attaching an object outside the nursery to - // one that is inside it. - if (owner && !IsInsideNursery(this) && IsInsideNursery(owner)) { - owner->storeBuffer()->putWholeCell(this); + if (owner) { + if (!IsInsideNursery(this) && IsInsideNursery(owner)) { + // Trigger a post barrier when attaching an object outside the nursery to + // one that is inside it. + owner->storeBuffer()->putWholeCell(this); + } else if (IsInsideNursery(this) && !IsInsideNursery(owner)) { + // ...and also when attaching an object inside the nursery to one that is + // outside it, for a subtle reason -- the outline object now points to + // the memory owned by 'owner', and can modify object/string references + // stored in that memory, potentially storing nursery pointers in it. If + // the outline object is in the nursery, then the post barrier will do + // nothing; you will be writing a nursery pointer "into" a nursery + // object. But that will result in the tenured owner's data containing a + // nursery pointer, and thus we need a store buffer edge. Since we can't + // catch the actual write, register the owner preemptively now. + storeBuffer()->putWholeCell(owner); + } } }