Bug 215250 - Inline cache Replace and Setters on PureForwardingProxy
Summary: Inline cache Replace and Setters on PureForwardingProxy
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Saam Barati
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-08-06 18:26 PDT by Saam Barati
Modified: 2020-08-12 21:51 PDT (History)
15 users (show)

See Also:


Attachments
WIP (13.85 KB, patch)
2020-08-07 20:11 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
patch (23.43 KB, patch)
2020-08-10 17:36 PDT, Saam Barati
saam: review-
Details | Formatted Diff | Diff
WIP (28.16 KB, patch)
2020-08-10 19:54 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (28.12 KB, patch)
2020-08-10 19:59 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
patch (28.25 KB, patch)
2020-08-11 18:40 PDT, Saam Barati
saam: review-
Details | Formatted Diff | Diff
patch (29.05 KB, patch)
2020-08-11 19:10 PDT, Saam Barati
ysuzuki: review+
Details | Formatted Diff | Diff
patch for landing (29.08 KB, patch)
2020-08-12 19:14 PDT, Saam Barati
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Saam Barati 2020-08-06 18:26:24 PDT
Should help with perf.
Comment 1 Saam Barati 2020-08-07 20:11:05 PDT
Created attachment 406243 [details]
WIP

This implements replace and JS setters. Next I'll do custom value/custom accessor. Then it should be done.

15% faster on 3d-cube-SP
Comment 2 Saam Barati 2020-08-10 17:36:10 PDT
Created attachment 406349 [details]
patch
Comment 3 Yusuke Suzuki 2020-08-10 18:21:11 PDT
Comment on attachment 406349 [details]
patch

r=me
Comment 4 Yusuke Suzuki 2020-08-10 18:23:31 PDT
Looks like some failures are occurring?
Comment 5 Saam Barati 2020-08-10 18:30:18 PDT
Comment on attachment 406349 [details]
patch

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

> Source/JavaScriptCore/runtime/JSObject.cpp:822
> +                if (!this->structure(vm)->isUncacheableDictionary())

I wonder if this is the cause of the failure. If so, I suspect it might be revealing an implementation bug.
Comment 6 Saam Barati 2020-08-10 19:54:36 PDT
Created attachment 406356 [details]
WIP

test on EWS
Comment 7 Saam Barati 2020-08-10 19:59:51 PDT
Created attachment 406357 [details]
WIP
Comment 8 Saam Barati 2020-08-11 18:40:02 PDT
Created attachment 406440 [details]
patch
Comment 9 Saam Barati 2020-08-11 19:10:57 PDT
Created attachment 406442 [details]
patch
Comment 10 Yusuke Suzuki 2020-08-12 11:23:00 PDT
Comment on attachment 406442 [details]
patch

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

r=me

> Source/JavaScriptCore/bytecode/AccessCase.cpp:1468
> +        if (viaProxy() && doesPropertyStorageLoads && !m_polyProtoAccessChain && !hasAlternateBase()) {
> +            // We only need this when loading an inline or out of line property. For customs, we can
> +            // invoke with a receiver value that is a JSProxy. For getters/setters, we'll also invoke
> +            // them with the JSProxy as |this|, but we need to load the actual GetterSetter cell from
> +            // the JSProxy's target.
> +
>              if (m_type == Getter || m_type == Setter)
> -                baseForGetGPR = scratchGPR;
> +                propertyOwnerGPR = scratchGPR;
>              else
> -                baseForGetGPR = valueRegsPayloadGPR;
> -
> -            ASSERT((m_type != Getter && m_type != Setter) || baseForGetGPR != baseGPR);
> -            ASSERT(m_type != Setter || baseForGetGPR != valueRegsPayloadGPR);
> +                propertyOwnerGPR = valueRegsPayloadGPR;
>  
>              jit.loadPtr(
> -                CCallHelpers::Address(baseGPR, JSProxy::targetOffset()),
> -                baseForGetGPR);
> -        } else
> -            baseForGetGPR = baseGPR;
> -
> -        GPRReg baseForAccessGPR;
> -        if (m_polyProtoAccessChain) {
> +                CCallHelpers::Address(baseGPR, JSProxy::targetOffset()), propertyOwnerGPR);
> +        } else if (m_polyProtoAccessChain) {
>              // This isn't pretty, but we know we got here via generateWithGuard,
>              // and it left the baseForAccess inside scratchGPR. We could re-derive the base,
>              // but it'd require emitting the same code to load the base twice.
> -            baseForAccessGPR = scratchGPR;
> -        } else {
> -            if (hasAlternateBase()) {
> -                jit.move(
> -                    CCallHelpers::TrustedImmPtr(alternateBase()), scratchGPR);
> -                baseForAccessGPR = scratchGPR;
> -            } else
> -                baseForAccessGPR = baseForGetGPR;
> -        }
> +            propertyOwnerGPR = scratchGPR;
> +        } else if (hasAlternateBase()) {
> +            jit.move(
> +                CCallHelpers::TrustedImmPtr(alternateBase()), scratchGPR);
> +            propertyOwnerGPR = scratchGPR;

I think reordering it as follows makes code easy to follow.

if (m_polyProtoAccessChain) {
   ...
} else if (hasAlternateBase()) {
   ...
} else if (viaProxy() && doesPropertyStorageLoads) {
   ...
} else if (viaProxy() && takesPropertyOwnerAsCFunctionArgument) {
   ...
} else {
    ASSERT(!viaProxy());
   ...
}

> Source/JavaScriptCore/jit/Repatch.cpp:612
> +        if (isProxy) {
> +            // We currently only cache Replace and JS/Custom Setters on JSProxy. We don't
> +            // cache transitions because global objects will never share the same structure
> +            // in our current implementation.
> +            bool isCacheableProxy = (slot.isCacheablePut() && slot.type() == PutPropertySlot::ExistingProperty)
> +                || slot.isCacheableSetter()
> +                || slot.isCacheableCustom();
> +            if (!isCacheableProxy)
> +                return GiveUpOnCache;
> +        }

How about putting this branch under `baseCell->type() == PureForwardingProxyType` branch too?
Comment 11 Saam Barati 2020-08-12 16:09:53 PDT
Comment on attachment 406442 [details]
patch

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

>> Source/JavaScriptCore/bytecode/AccessCase.cpp:1468
>> +            propertyOwnerGPR = scratchGPR;
> 
> I think reordering it as follows makes code easy to follow.
> 
> if (m_polyProtoAccessChain) {
>    ...
> } else if (hasAlternateBase()) {
>    ...
> } else if (viaProxy() && doesPropertyStorageLoads) {
>    ...
> } else if (viaProxy() && takesPropertyOwnerAsCFunctionArgument) {
>    ...
> } else {
>     ASSERT(!viaProxy());
>    ...
> }

Sounds good. The only thing is the last assert in the else isn’t correct. For example, for custom accessors may be viaProxy

>> Source/JavaScriptCore/jit/Repatch.cpp:612
>> +        }
> 
> How about putting this branch under `baseCell->type() == PureForwardingProxyType` branch too?

Yeah makes sense. They were originally separate because i had some code between them. But I deleted that code.
Comment 12 Saam Barati 2020-08-12 19:14:12 PDT
Created attachment 406489 [details]
patch for landing
Comment 13 EWS 2020-08-12 21:50:16 PDT
Committed r265600: <https://trac.webkit.org/changeset/265600>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 406489 [details].
Comment 14 Radar WebKit Bug Importer 2020-08-12 21:51:24 PDT
<rdar://problem/66960215>