Bug 213191 - Add DFG/FTL fast path for GetPrototypeOf based on OverridesGetPrototype flag
Summary: Add DFG/FTL fast path for GetPrototypeOf based on OverridesGetPrototype flag
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: All All
: P2 Enhancement
Assignee: Alexey Shvayka
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-06-15 07:17 PDT by Alexey Shvayka
Modified: 2020-06-25 12:34 PDT (History)
8 users (show)

See Also:


Attachments
Patch (43.77 KB, patch)
2020-06-21 05:47 PDT, Alexey Shvayka
no flags Details | Formatted Diff | Diff
Patch (43.77 KB, patch)
2020-06-21 06:58 PDT, Alexey Shvayka
no flags Details | Formatted Diff | Diff
Patch (43.96 KB, patch)
2020-06-24 08:09 PDT, Alexey Shvayka
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Shvayka 2020-06-15 07:17:23 PDT
Also consider extracting AssemblyHelpers::emitLoadPrototype() and vet InstanceOfGeneric case of AccessCase::generateWithGuard().
Comment 1 Alexey Shvayka 2020-06-21 05:47:48 PDT
Created attachment 402418 [details]
Patch
Comment 2 Alexey Shvayka 2020-06-21 06:58:29 PDT
Created attachment 402422 [details]
Patch

Attempt to fix 32-bit builds.
Comment 3 Yusuke Suzuki 2020-06-23 20:04:28 PDT
Comment on attachment 402422 [details]
Patch

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

r=me

> Source/JavaScriptCore/bytecode/AccessCase.cpp:1287
> +        jit.emitLoadPrototype(vm, valueGPR, scratch2GPR, scratchGPR, failAndIgnore);

#if USE(JSVALUE64)
JSValueRegs resultRegs(scratch2GPR);
#else
JSValueRegs resultRegs(scratchGPR, scratch2GPR);
#endif

jit.emitLoadPrototype(vm, valueGPR, resultRegs, scratchGPR, failAndIgnore);

> Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:13952
> +        m_jit.emitLoadPrototype(vm(), objectGPR, tempGPR, temp2GPR, slowCases);

m_jit.emitLoadPrototype(vm(), objectGPR, resultRegs, temp2GPR, slowCases);

> Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:13969
> +        m_jit.emitLoadPrototype(vm(), valueGPR, tempGPR, temp2GPR, slowCases);

m_jit.emitLoadPrototype(vm(), valueGPR, resultRegs, temp2GPR, slowCases);

> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:4450
> +            m_out.appendTo(slowPath, continuation);

m_out.appendTo(slowPath, fastPath);

> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:4470
> +            m_out.appendTo(isObjectPath, continuation);

m_out.appendTo(isObjectPath, slowPath);

> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:4478
> +            m_out.appendTo(slowPath, continuation);

m_out.appendTo(slowPath, fastPath);

> Source/JavaScriptCore/jit/AssemblyHelpers.cpp:395
> +void AssemblyHelpers::emitLoadPrototype(VM& vm, RegisterID source, RegisterID dest, RegisterID scratch, JumpList& slowPath)

Let's accept `GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR` instead.
Changing the meaning of scratch to part of resultRegs inside function looks weird. We should get JSValueRegs resultRegs in this function's parameter.
And let's note that scratch can be a resultRegs.tagGPR().
You can insert,

ASSERT(resultRegs.payloadGPR() != objectGPR);
ASSERT(resultRegs.payloadGPR() != scratchGPR);
ASSERT(objectGPR != scratchGPR);

> Source/JavaScriptCore/jit/AssemblyHelpers.cpp:397
> +    emitLoadStructure(vm, source, dest, scratch);

emitLoadStructure(vm, objectGPR, resultRegs.payloadGPR(), scratchGPR);

> Source/JavaScriptCore/jit/AssemblyHelpers.cpp:408
> +#if USE(JSVALUE64)
> +    JSValueRegs resultRegs(dest);
> +#else
> +    JSValueRegs resultRegs(scratch, dest);
> +#endif

This is not necessary.

> Source/JavaScriptCore/jit/AssemblyHelpers.cpp:410
> +    loadValue(MacroAssembler::Address(dest, Structure::prototypeOffset()), resultRegs);

loadValue(MacroAssembler::Address(resultRegs.payloadGPR(), Structure::prototypeOffset()), resultRegs);

> Source/JavaScriptCore/jit/AssemblyHelpers.cpp:412
> +    loadValue(MacroAssembler::Address(source, offsetRelativeToBase(knownPolyProtoOffset)), resultRegs);

loadValue(MacroAssembler::Address(objectGPR, offsetRelativeToBase(knownPolyProtoOffset)), resultRegs);

> Source/JavaScriptCore/jit/JITOpcodes.cpp:1753
> +    JSValueRegs resultRegs(regT2);

Add
GPRReg scratchGPR = regT3;

> Source/JavaScriptCore/jit/JITOpcodes.cpp:1756
> +    JSValueRegs resultRegs(regT3, regT2);

Add
GPRReg scratchGPR = regT1;
ASSERT(valueRegs.tagGPR() == scratchGPR);

> Source/JavaScriptCore/jit/JITOpcodes.cpp:1762
> +    slowCases.append(branchIfNotObject(regT0));

Let's use valueRegs.payloadGPR().

> Source/JavaScriptCore/jit/JITOpcodes.cpp:1764
> +    emitLoadPrototype(vm(), regT0, regT2, regT3, slowCases);

Let's use it to something like this.

`
emitLoadPrototype(vm(), valueRegs.payloadGPR(), resultRegs, scratchGPR, slowCases);
`
Comment 4 Alexey Shvayka 2020-06-24 08:09:22 PDT
Created attachment 402651 [details]
Patch

Accept JSValueRegs in emitLoadPrototype, add ASSERTs, fix FTL blocks linking.
Comment 5 EWS 2020-06-24 12:51:53 PDT
Committed r263470: <https://trac.webkit.org/changeset/263470>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 402651 [details].
Comment 6 Radar WebKit Bug Importer 2020-06-24 12:52:21 PDT
<rdar://problem/64716119>
Comment 7 Saam Barati 2020-06-25 12:34:01 PDT
Comment on attachment 402651 [details]
Patch

lgtm too