Bug 188151 - We should zero unused property storage when rebalancing array storage.
Summary: We should zero unused property storage when rebalancing array storage.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mark Lam
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-07-29 15:45 PDT by Mark Lam
Modified: 2018-09-26 11:57 PDT (History)
7 users (show)

See Also:


Attachments
proposed patch. (7.73 KB, patch)
2018-07-29 15:59 PDT, Mark Lam
no flags Details | Formatted Diff | Diff
Patch (3.94 KB, patch)
2018-09-26 11:53 PDT, Keith Miller
msaboff: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Lam 2018-07-29 15:45:44 PDT
When putting a new property, JSObject::prepareToPutDirectWithoutTransition() and JSObject::putDirectInternal() currently always asserts that the target slot contains an effectively empty value (and is safe for GC scanning).  This assertion may be false if the slot is from the existing butterfly and not a newly allocated one.  For example, an array splice operation may shift entries in the existing butterfly, and therefore, result in unused property slots containing valid values.  As a result, the slot for the new property may already contain a non-empty value (before the put) that is safe for GC.  But because it is non-empty, it will fail the assertion.

We should fix the assertion to only do this empty check if the butterfly is actually newly allocated.

<rdar://problem/42020385>
Comment 1 Mark Lam 2018-07-29 15:59:40 PDT
Created attachment 346046 [details]
proposed patch.
Comment 2 Saam Barati 2018-07-29 17:17:39 PDT
Maybe I’m missing something here but it feels like this patch is loosing a lot of the value of the assertion.

Also, you say that slot has a valid value. But is it guaranteed to be scanned during GC even if it’s an unused slot?
Comment 3 Mark Lam 2018-07-29 23:19:09 PDT
(In reply to Saam Barati from comment #2)
> Maybe I’m missing something here but it feels like this patch is loosing a
> lot of the value of the assertion.

There's a more conservative way I can do this, that is: when asserts are enabled, nullify the shifted out slot when splicing.  I'll look into that.

> Also, you say that slot has a valid value. But is it guaranteed to be
> scanned during GC even if it’s an unused slot?

I should also double check this.  If your stipulation is true, then these assertions may be meaningless entirely.
Comment 4 Mark Lam 2018-07-29 23:19:50 PDT
Comment on attachment 346046 [details]
proposed patch.

r- while I investigate additional details brought up by Saam.
Comment 5 Keith Miller 2018-07-29 23:39:16 PDT
Comment on attachment 346046 [details]
proposed patch.

View in context: https://bugs.webkit.org/attachment.cgi?id=346046&action=review

> Source/JavaScriptCore/runtime/JSObjectInlines.h:210
> +            ASSERT(!needToAllocateNewButterfly || getDirect(offset).isEffectivelyEmptyAndSafeForGCScanning());

This is wrong.

It's wrong to ever have bits that look like a cell in an unused slot. The slot may or may not get scanned do to raciness of our GC. So if it an unused slot had a stale cell in it we might deference scavenged or otherwise bad memory and crash.

> Source/JavaScriptCore/runtime/JSObjectInlines.h:337
> +        ASSERT(!needToAllocateNewButterfly || getDirect(offset).isEffectivelyEmptyAndSafeForGCScanning());

ditto.

> Source/JavaScriptCore/runtime/JSObjectInlines.h:394
> +    ASSERT(!needToAllocateNewButterfly || getDirect(offset).isEffectivelyEmptyAndSafeForGCScanning());

ditto.
Comment 6 Saam Barati 2018-07-30 13:00:46 PDT
(In reply to Mark Lam from comment #3)
> (In reply to Saam Barati from comment #2)
> > Maybe I’m missing something here but it feels like this patch is loosing a
> > lot of the value of the assertion.
> 
> There's a more conservative way I can do this, that is: when asserts are
> enabled, nullify the shifted out slot when splicing.  I'll look into that.
> 
> > Also, you say that slot has a valid value. But is it guaranteed to be
> > scanned during GC even if it’s an unused slot?
> 
> I should also double check this.  If your stipulation is true, then these
> assertions may be meaningless entirely.

I didn't mean entirely. I just mean the splice case here. Do we skip the dead space in butterfly from splice when visiting or no? (I think we call that area the precapacity?)
Comment 7 Keith Miller 2018-09-26 11:53:37 PDT
Created attachment 350877 [details]
Patch
Comment 8 Michael Saboff 2018-09-26 11:55:33 PDT
Comment on attachment 350877 [details]
Patch

r=me
Comment 9 Keith Miller 2018-09-26 11:57:40 PDT
Committed r236514: <https://trac.webkit.org/changeset/236514>