WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
213372
[JSC][ESNext] Create a new opcode to handle private fields store/define
https://bugs.webkit.org/show_bug.cgi?id=213372
Summary
[JSC][ESNext] Create a new opcode to handle private fields store/define
Caio Lima
Reported
2020-06-19 05:48:48 PDT
Now we are using `put_by_val_direct` with a `PutByValFlags` to indicate such operation, but while there are some similarities of `put_by_val_direct`, the semantics of set/define operation of private fields are different enough to be profitable adding a new opcode for it.
Attachments
WIP - Patch
(32.74 KB, patch)
2020-06-19 11:21 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
WIP - Patch
(70.59 KB, patch)
2020-07-10 12:22 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
WIP - Patch
(96.39 KB, patch)
2020-07-14 11:55 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
WIP - Patch
(94.17 KB, patch)
2020-07-15 14:26 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
WIP - Patch
(94.17 KB, patch)
2020-07-16 10:12 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(112.96 KB, patch)
2020-07-17 08:12 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
WIP - Patch
(119.14 KB, patch)
2020-07-22 12:49 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(121.43 KB, patch)
2020-07-23 13:56 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(121.74 KB, patch)
2020-07-28 11:23 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(121.31 KB, patch)
2020-07-28 12:19 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(120.93 KB, patch)
2020-07-29 08:20 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(115.49 KB, patch)
2020-08-04 08:37 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(131.92 KB, patch)
2020-08-11 08:18 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(142.37 KB, patch)
2020-08-14 09:25 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(142.65 KB, patch)
2020-08-17 10:21 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(147.53 KB, patch)
2020-08-25 13:11 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(147.54 KB, patch)
2020-08-28 09:15 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(156.08 KB, patch)
2020-09-03 09:09 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(156.23 KB, patch)
2020-09-04 05:56 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(158.75 KB, patch)
2020-09-04 08:05 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(159.07 KB, patch)
2020-09-04 08:33 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(157.85 KB, patch)
2020-09-07 07:56 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(163.88 KB, patch)
2020-09-17 09:51 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(163.96 KB, patch)
2020-09-17 11:51 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(164.61 KB, patch)
2020-09-21 09:52 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(162.38 KB, patch)
2020-09-21 19:12 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(169.93 KB, patch)
2020-09-22 17:23 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(170.11 KB, patch)
2020-09-22 19:24 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(170.20 KB, patch)
2020-09-22 22:31 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Patch
(170.19 KB, patch)
2020-09-23 09:31 PDT
,
Caio Lima
no flags
Details
Formatted Diff
Diff
Show Obsolete
(29)
View All
Add attachment
proposed patch, testcase, etc.
Caio Lima
Comment 1
2020-06-19 11:21:26 PDT
Created
attachment 402297
[details]
WIP - Patch It starts the implementation. There is a lot of work to do yet like refactoring (there is a lot of repeated code) and rolling back the usage of private fields from `put_by_val_direct`. DFG/FTL support is not done as well.
Caitlin Potter (:caitp)
Comment 2
2020-06-22 08:20:33 PDT
Comment on
attachment 402297
[details]
WIP - Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=402297&action=review
> Source/JavaScriptCore/bytecode/BytecodeList.rb:581 > + flags: PutByValFlags,
Do we want to keep PutByValFlags around? Since they only existed to distinguish put-by-val from put-private-field operations, I think we could replace it with a simpler flag here that just distinguishes between the define and update operations. It would free up a few bits for PutByVal's own flags, if it ever needs to add new ones. We don't necessarily need to remove PutByValFlags entirely, but it might make sense to remove the private-specific parts of it
> Source/JavaScriptCore/jit/JITInlines.h:708 > +ALWAYS_INLINE ECMAMode JIT::ecmaMode<OpPutPrivateName>(OpPutPrivateName)
this seems to be unused now in this patch, is it needed by JITInlineCacheGenerator?
> Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:1354 > + // and class methods are always in strict mode
nit: if we're going to have this informational comment, lets add `const bool isStrictMode = true;` to make it obvious what it's talking about --- A lot of us don't have PutPropertySlot parameter names memorized
Caio Lima
Comment 3
2020-07-10 12:18:56 PDT
Comment on
attachment 402297
[details]
WIP - Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=402297&action=review
>> Source/JavaScriptCore/bytecode/BytecodeList.rb:581 >> + flags: PutByValFlags, > > Do we want to keep PutByValFlags around? Since they only existed to distinguish put-by-val from put-private-field operations, I think we could replace it with a simpler flag here that just distinguishes between the define and update operations. It would free up a few bits for PutByVal's own flags, if it ever needs to add new ones. We don't necessarily need to remove PutByValFlags entirely, but it might make sense to remove the private-specific parts of it
After the refactoring I applied, I don't think `PutByValFlags` makes much sense now and I removed it. I'm using a `PrivateFieldPutKind` instead.
>> Source/JavaScriptCore/jit/JITInlines.h:708 >> +ALWAYS_INLINE ECMAMode JIT::ecmaMode<OpPutPrivateName>(OpPutPrivateName) > > this seems to be unused now in this patch, is it needed by JITInlineCacheGenerator?
I don't think this is would be necessary anymore. I'll remove it.
>> Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:1354 >> + // and class methods are always in strict mode > > nit: if we're going to have this informational comment, lets add `const bool isStrictMode = true;` to make it obvious what it's talking about --- A lot of us don't have PutPropertySlot parameter names memorized
Agreed. Done.
Caio Lima
Comment 4
2020-07-10 12:22:28 PDT
Created
attachment 403988
[details]
WIP - Patch
Caio Lima
Comment 5
2020-07-14 11:55:21 PDT
Created
attachment 404260
[details]
WIP - Patch It adds DFG and FTL support for 32-bits and some tests.
Caio Lima
Comment 6
2020-07-15 14:26:10 PDT
Created
attachment 404394
[details]
WIP - Patch Patch is almost done, let's see EWS results
Caio Lima
Comment 7
2020-07-16 10:12:24 PDT
Created
attachment 404459
[details]
WIP - Patch
Caio Lima
Comment 8
2020-07-17 08:12:15 PDT
Created
attachment 404563
[details]
Patch
Caio Lima
Comment 9
2020-07-17 08:15:22 PDT
Comment on
attachment 404563
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=404563&action=review
> Source/JavaScriptCore/runtime/OptionsList.h:568 > + v(usePrivateClassFields, SupportsDFG | SupportsFTL, "
https://bugs.webkit.org/show_bug.cgi?id=212781
", "
https://bugs.webkit.org/show_bug.cgi?id=212784
")
I changed it and also added `runNoDFG` mode into some tests that emit `get_private_name` to be able to see EWS run with JIT configurations of `put_private_name`. This should be changed back `LLIntAndBaselineOnly` until we get proper JIT support of both `put_private_name` and `get_private_name`.
Caitlin Potter (:caitp)
Comment 10
2020-07-17 09:37:10 PDT
Comment on
attachment 404563
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=404563&action=review
> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:6060 > + compiledAsPutById = true;
nit: I would write this as `didCompileAsPutById`, to make the past tense more obvious
> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:6068 > + if (identifier.isSymbolCell())
lets just `ASSERT(identifier.isSymbolCell())`, since it has to be, and will make the code a bit simpler
> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:6083 > + handlePutById(base, identifier, identifierNumber, value, putByIdStatus, isDirect, nextOpcodeIndex(), ECMAMode::strict());
nit: there's no reason we can't do this in the block above where `compiledAsPutById` is set to true
Caio Lima
Comment 11
2020-07-17 13:32:54 PDT
Comment on
attachment 404563
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=404563&action=review
I've found a bug
>> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:6083 >> + handlePutById(base, identifier, identifierNumber, value, putByIdStatus, isDirect, nextOpcodeIndex(), ECMAMode::strict()); > > nit: there's no reason we can't do this in the block above where `compiledAsPutById` is set to true
The way we are compiling here is wrong. In a case where we have a megamorphic callsite, this will compile as PutByID but slow path won't have the proper semantics for private fields. A test case for it is also needed.
Caio Lima
Comment 12
2020-07-22 12:49:41 PDT
Created
attachment 404951
[details]
WIP - Patch
Caio Lima
Comment 13
2020-07-23 13:56:42 PDT
Created
attachment 405073
[details]
Patch
Caio Lima
Comment 14
2020-07-28 11:23:11 PDT
Created
attachment 405381
[details]
Patch
Caio Lima
Comment 15
2020-07-28 12:19:50 PDT
Created
attachment 405391
[details]
Patch
Caio Lima
Comment 16
2020-07-29 08:20:18 PDT
Created
attachment 405459
[details]
Patch
Yusuke Suzuki
Comment 17
2020-07-30 01:09:36 PDT
Comment on
attachment 405459
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=405459&action=review
Continue reviewing, early comments.
> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:253 > + bool isDirect, BytecodeIndex osrExitIndex, ECMAMode, PrivateFieldPutKind = PrivateFieldPutKind::none());
We should not use default parameter here since it is hard to follow what is passed.
> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:6078 > + handlePutById(base, identifier, identifierNumber, value, putByIdStatus, isDirect, nextOpcodeIndex(), ECMAMode::strict(), bytecode.m_putKind);
If we separate the bytecode from put_by_val_direct, then I think still using PutByIdDirect for op_put_private_name looks strange here. IIUC, there is semantics difference, so can we use it?
Caio Lima
Comment 18
2020-07-30 04:20:35 PDT
(In reply to Yusuke Suzuki from
comment #17
)
> Comment on
attachment 405459
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=405459&action=review
> > Continue reviewing, early comments. > > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:253 > > + bool isDirect, BytecodeIndex osrExitIndex, ECMAMode, PrivateFieldPutKind = PrivateFieldPutKind::none()); > > We should not use default parameter here since it is hard to follow what is > passed. > > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:6078 > > + handlePutById(base, identifier, identifierNumber, value, putByIdStatus, isDirect, nextOpcodeIndex(), ECMAMode::strict(), bytecode.m_putKind); > > If we separate the bytecode from put_by_val_direct, then I think still using > PutByIdDirect for op_put_private_name looks strange here. IIUC, there is > semantics difference, so can we use it?
We are using `bytecode.m_putKind` into the JITPutByIdGenerator and this will make we properly set slow path function for it when there is an IC miss (like it is done on Baseline), keeping the semantics correct (see `JITPutByIdGenerator::slowPathFunction`). We are storing `bytecode.m_putKind` into `PutByIdDirect`'s OpInfo and using it on `SpeculativeJIT::compilePutByIdDirect` and `FTLLowerDFGToB3::compilePutById()`. The test case dedicated to validate this is `JSTests/stress/dfg-put-private-name-compiled-as-put-by-id-direct.js`. The usage of `PutByIdDirect` here is to be able to re-use all optimizations we already apply to it, including the constant folding and IC for generic cases. One alternative we have is to avoid using `handlePutById` and only try to inline the IC on `PutByOffset` or `MultiPutByOffset`, while implementing all optimizations to `PutPrivateName`, like what's being proposed for `get_private_name`[1]. I'm liking this alternative more than current patch, but I'd rather implement it in a followup patch, though. [1] -
https://bugs.webkit.org/show_bug.cgi?id=214861
Yusuke Suzuki
Comment 19
2020-08-03 16:13:06 PDT
Comment on
attachment 405459
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=405459&action=review
> Source/JavaScriptCore/ChangeLog:14 > + This patch is adding a new opcode to handle private field storage. > + Before this change, we were using `put_by_val_direct` and including > + the information of `PutKind` into `PutByValFlags`. We initially decided > + to use `put_by_val_direct` to take advantage of all IC mechanism already > + implemented for this instruction, however the semantics of private field > + is different enough to complicate the understanding of > + `put_by_val_direct`.
I agree. So I think we should not complicate DFG PutByIdDirect too.
>>> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:253 >>> + bool isDirect, BytecodeIndex osrExitIndex, ECMAMode, PrivateFieldPutKind = PrivateFieldPutKind::none()); >> >> We should not use default parameter here since it is hard to follow what is passed. > > We are using `bytecode.m_putKind` into the JITPutByIdGenerator and this will make we properly set slow path function for it when there is an IC miss (like it is done on Baseline), keeping the semantics correct (see `JITPutByIdGenerator::slowPathFunction`). We are storing `bytecode.m_putKind` into `PutByIdDirect`'s OpInfo and using it on `SpeculativeJIT::compilePutByIdDirect` and `FTLLowerDFGToB3::compilePutById()`. The test case dedicated to validate this is `JSTests/stress/dfg-put-private-name-compiled-as-put-by-id-direct.js`. The usage of `PutByIdDirect` here is to be able to re-use all optimizations we already apply to it, including the constant folding and IC for generic cases. > > One alternative we have is to avoid using `handlePutById` and only try to inline the IC on `PutByOffset` or `MultiPutByOffset`, while implementing all optimizations to `PutPrivateName`, like what's being proposed for `get_private_name`[1]. I'm liking this alternative more than current patch, but I'd rather implement it in a followup patch, though. > > [1] -
https://bugs.webkit.org/show_bug.cgi?id=214861
If we share the DFG nodes, why do we need to introduce new bytecode in this patch? Introducing new bytecodes while using shared DFG nodes is tricky. You can add new DFG nodes (e.g. PutPrivateNameDirect), and wire existing optimizations to that DFG opcode. I think we can use the same IC mechanism for different DFG nodes. (PutByIdDirect and PutPrivateNameDirect). I agree to reusing cachePutById etc. We should reuse them. But I don't think extending DFG PutByIdDirect is a good idea. We have a lot of strong assumption about PutByIdDirect. If the behavior is sufficiently different, we should have different DFG nodes.
Caio Lima
Comment 20
2020-08-04 08:37:26 PDT
Created
attachment 405922
[details]
Patch
Caio Lima
Comment 21
2020-08-04 09:23:11 PDT
Comment on
attachment 405459
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=405459&action=review
>>>> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:253 >>>> + bool isDirect, BytecodeIndex osrExitIndex, ECMAMode, PrivateFieldPutKind = PrivateFieldPutKind::none()); >>> >>> We should not use default parameter here since it is hard to follow what is passed. >> >> We are using `bytecode.m_putKind` into the JITPutByIdGenerator and this will make we properly set slow path function for it when there is an IC miss (like it is done on Baseline), keeping the semantics correct (see `JITPutByIdGenerator::slowPathFunction`). We are storing `bytecode.m_putKind` into `PutByIdDirect`'s OpInfo and using it on `SpeculativeJIT::compilePutByIdDirect` and `FTLLowerDFGToB3::compilePutById()`. The test case dedicated to validate this is `JSTests/stress/dfg-put-private-name-compiled-as-put-by-id-direct.js`. The usage of `PutByIdDirect` here is to be able to re-use all optimizations we already apply to it, including the constant folding and IC for generic cases. >> >> One alternative we have is to avoid using `handlePutById` and only try to inline the IC on `PutByOffset` or `MultiPutByOffset`, while implementing all optimizations to `PutPrivateName`, like what's being proposed for `get_private_name`[1]. I'm liking this alternative more than current patch, but I'd rather implement it in a followup patch, though. >> >> [1] -
https://bugs.webkit.org/show_bug.cgi?id=214861
> > If we share the DFG nodes, why do we need to introduce new bytecode in this patch? > Introducing new bytecodes while using shared DFG nodes is tricky. > You can add new DFG nodes (e.g. PutPrivateNameDirect), and wire existing optimizations to that DFG opcode. > I think we can use the same IC mechanism for different DFG nodes. (PutByIdDirect and PutPrivateNameDirect). > I agree to reusing cachePutById etc. We should reuse them. > But I don't think extending DFG PutByIdDirect is a good idea. We have a lot of strong assumption about PutByIdDirect. > If the behavior is sufficiently different, we should have different DFG nodes.
I agree that sharing them is a recipe for headaches. I uploaded a new version that is not emitting `PutByIdDirect` when compiling `put_private_name` and the idea is to optimize `PutPrivateName` on
https://bugs.webkit.org/show_bug.cgi?id=215126
Yusuke Suzuki
Comment 22
2020-08-07 02:22:12 PDT
Comment on
attachment 405922
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=405922&action=review
> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4841 > if (!isDirect) { > + ASSERT(privateFieldPutKind.isNone()); > for (unsigned variantIndex = putByIdStatus.numVariants(); variantIndex--;) { > if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition) > continue;
We are using PutById / Direct path for private names. However privateFieldPutKind has Define / Set modes. If Define and Set has different semantics, why can we use the same PutByOffset etc.? Can you explain it?
Caio Lima
Comment 23
2020-08-07 06:24:07 PDT
(In reply to Yusuke Suzuki from
comment #22
)
> Comment on
attachment 405922
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=405922&action=review
> > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4841 > > if (!isDirect) { > > + ASSERT(privateFieldPutKind.isNone()); > > for (unsigned variantIndex = putByIdStatus.numVariants(); variantIndex--;) { > > if (putByIdStatus[variantIndex].kind() != PutByIdVariant::Transition) > > continue; > > We are using PutById / Direct path for private names. However > privateFieldPutKind has Define / Set modes. > If Define and Set has different semantics, why can we use the same > PutByOffset etc.? Can you explain it?
For now, we are only compiling `put_private_name` as `[Multi]PutByOffset` from information we get from stubInfo. This info is populated during Baseline IC slow path execution of private name on `operationPutByIdDefinePrivateFieldStrictOptimize` and `operationPutByIdPutPrivateFieldStrictOptimize` (this was already added by
https://trac.webkit.org/changeset/262613
). Once we have a stub for any given structure set, we can infer that put private field operations always succeed for this set, and we don't need to check for `Set|Define` semantics for those cases. Since we emit a `CheckStructure` before `PutByOffset`, in case of a structure check miss, we will OSR and then perform the proper `Set|Define` semantics in whatever tier we OSR to. For cases where we decide to not emit `PutByOffset`, we then emit `PutPrivateName` and this node checks for `Set|Define` private field semantics. We are testing OSR cases in `JSTests/stress/put-private-name-osr.js` and `JSTests/stress/put-private-name-set-before-define.js`. It is important to notice that a `put_private_name` with `Define` put kind will only have `PutByIdVariant::Transition` while the one with `Set` will only have `PutByIdVariant::Replace` (this should be added as an ASSERT).
Caio Lima
Comment 24
2020-08-07 06:25:49 PDT
Comment on
attachment 405922
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=405922&action=review
> JSTests/stress/put-private-name-set-before-define.js:1 > +//@ requireOptions("--allowUnsupportedTiers=true", "--usePrivateClassFields=true")
This test is a duplicate of JSTests/stress/put-private-name-invalid-store.js. Also, this test is probably wrong on its purpose, since the idea here is to trigger an OSR due to `this.#foo` `BadCache`, put it is potentially getting invalidate when we execute `shouldStore = true;` within the for loop.
Caio Lima
Comment 25
2020-08-11 08:18:37 PDT
Created
attachment 406381
[details]
Patch
Caitlin Potter (:caitp)
Comment 26
2020-08-11 08:51:48 PDT
Comment on
attachment 406381
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=406381&action=review
> Source/JavaScriptCore/jit/JITOperations.cpp:1168 > + if (++byValInfo->slowPathCount >= 10)
Would it make sense to define this in an JSC::Options field instead of just hardcoding `10` here?
> Source/JavaScriptCore/jit/JITPropertyAccess.cpp:1551 > + genericFunction = bytecode.m_putKind.isDefine() ? operationDefinePrivateNameGeneric : operationSetPrivateNameGeneric;
It might be better to give PutPrivateName its own JIT and DFG handling. There are downsides, but it seems less fragile than sharing with PutByID.
Caio Lima
Comment 27
2020-08-14 09:25:06 PDT
Created
attachment 406597
[details]
Patch
Caio Lima
Comment 28
2020-08-17 10:21:40 PDT
Created
attachment 406725
[details]
Patch
Caio Lima
Comment 29
2020-08-25 13:11:05 PDT
Created
attachment 407222
[details]
Patch
Caio Lima
Comment 30
2020-08-28 09:15:30 PDT
Created
attachment 407475
[details]
Patch
Yusuke Suzuki
Comment 31
2020-09-03 01:55:42 PDT
Comment on
attachment 407475
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=407475&action=review
> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:4050 > PutByIdStatus status = PutByIdStatus::computeFor(
Inside PutByIdStatus::computeFor, it can find transitioned-structure by adding a new property. And this transition can be constructed in different "define" type PutPrivateName. But even if this PutPrivateNameById is "set" version, this structure transition will be populated here, and I think this is not correct.
> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:1406 > + PutByIdStatus status = PutByIdStatus::computeFor( > + m_graph.globalObjectFor(origin.semantic), > + baseValue.m_structure.toStructureSet(), > + node->cacheableIdentifier().uid(), > + isDirect);
Ditto. I think this can populate adding-property-structure-transition case even if this is "set" PutPrivateNameById.
> Source/JavaScriptCore/jit/JIT.h:172 > + ByValCompilationInfo(ByValInfo* byValInfo, BytecodeIndex bytecodeIndex, MacroAssembler::PatchableJump notIndexJump, MacroAssembler::Label doneTarget, MacroAssembler::Label nextHotPathTarget) > + : byValInfo(byValInfo) > + , bytecodeIndex(bytecodeIndex) > + , notIndexJump(notIndexJump) > + , doneTarget(doneTarget) > + , nextHotPathTarget(nextHotPathTarget) > + { > + }
Need to update this to setUp function which stores these fields to avoid overriding bytecodeIndex again.
> Source/JavaScriptCore/jit/JITPropertyAccess.cpp:378 > + ByValInfo* byValInfo = m_codeBlock->addByValInfo();
Need to update it to pass bytecodeIndex.
> Source/JavaScriptCore/jit/Repatch.cpp:545 > return operationPutByIdDirectStrict; > - if (putKind == DirectPrivateFieldCreate) > + if (putKind == DirectPrivateFieldDefine) > return operationPutByIdDefinePrivateFieldStrict; > - if (putKind == DirectPrivateFieldPut) > - return operationPutByIdPutPrivateFieldStrict; > + if (putKind == DirectPrivateFieldSet) > + return operationPutByIdSetPrivateFieldStrict; > return operationPutByIdStrict;
Let's convert it to switch to avoid missing some kinds.
> Source/JavaScriptCore/jit/Repatch.cpp:561 > if (putKind == Direct) > return operationPutByIdDirectStrictOptimize; > - if (putKind == DirectPrivateFieldCreate) > + if (putKind == DirectPrivateFieldDefine) > return operationPutByIdDefinePrivateFieldStrictOptimize; > - if (putKind == DirectPrivateFieldPut) > - return operationPutByIdPutPrivateFieldStrictOptimize; > + if (putKind == DirectPrivateFieldSet) > + return operationPutByIdSetPrivateFieldStrictOptimize; > return operationPutByIdStrictOptimize;
Let's convert it to switch to avoid missing some kinds.
> Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:-1196 > - if (subscript.isDouble()) { > - ASSERT(!isPrivateFieldAccess); > - double subscriptAsDouble = subscript.asDouble(); > - uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble); > - if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) { > - baseObject->putDirectIndex(globalObject, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow); > - LLINT_END(); > - } > - }
Why is it removed?
Caio Lima
Comment 32
2020-09-03 08:08:51 PDT
Comment on
attachment 407475
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=407475&action=review
Thank you very much for the review
>> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:4050 >> PutByIdStatus status = PutByIdStatus::computeFor( > > Inside PutByIdStatus::computeFor, it can find transitioned-structure by adding a new property. And this transition can be constructed in different "define" type PutPrivateName. > But even if this PutPrivateNameById is "set" version, this structure transition will be populated here, and I think this is not correct.
This is definitely not correct. I added a test that is wrongly optimized by this bug. Thanks for the catch.
>> Source/JavaScriptCore/jit/JIT.h:172 >> + } > > Need to update this to setUp function which stores these fields to avoid overriding bytecodeIndex again.
I see a `setUp` function into `ByValInfo`, but not into `ByValCompilationInfo`. I added this new constructor since there's no `badTypeJump`, `arrayMode` and `arrayProfile` for `put_private_name` case.
>> Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:-1196 >> - } > > Why is it removed?
This was introduced by
https://trac.webkit.org/changeset/262613
and I'm reverting all changes of `put_by_val_direct` from this bug. TBH, I don't know was this was introduced back in that revision
Caio Lima
Comment 33
2020-09-03 09:09:25 PDT
Created
attachment 407884
[details]
Patch
Caio Lima
Comment 34
2020-09-04 05:56:15 PDT
Created
attachment 407964
[details]
Patch
Caio Lima
Comment 35
2020-09-04 08:05:49 PDT
Created
attachment 407972
[details]
Patch
Caio Lima
Comment 36
2020-09-04 08:33:34 PDT
Created
attachment 407977
[details]
Patch
Caio Lima
Comment 37
2020-09-07 07:56:52 PDT
Created
attachment 408180
[details]
Patch
Caio Lima
Comment 38
2020-09-07 08:02:07 PDT
(In reply to Caio Lima from
comment #37
)
> Created
attachment 408180
[details]
> Patch
This fixed some nits and added microbenchmarks. Here are results for reference: ``` Collected 10 samples per benchmark/VM, with 10 VM invocations per benchmark. Emitted a call to gc() between sample measurements. Used 1 benchmark iteration per VM invocation for warm-up. Used the jsc-specific preciseTime() function to get microsecond-level timing. Reporting benchmark execution times with 95% confidence intervals in milliseconds. baseline changes Microbenchmarks: put-public-field 21.2727+-0.4655 21.0484+-0.5071 might be 1.0107x faster polymorphic-put-public-field 36.0990+-1.2683 ? 36.8361+-1.6222 ? might be 1.0204x slower <geometric> 27.7048+-0.6616 ? 27.8283+-0.6683 ? might be 1.0045x slower baseline changes PrivateFieldsBench: put-private-field 51.0347+-2.2051 ^ 21.5075+-0.3837 ^ definitely 2.3729x faster polymorphic-put-private-field 148.8444+-0.9087 ^ 36.8156+-0.8545 ^ definitely 4.0430x faster <geometric> 87.1192+-1.8639 ^ 28.1339+-0.4085 ^ definitely 3.0966x faster baseline changes Geomean of preferred means: <scaled-result> 49.1189+-0.8266 ^ 27.9757+-0.3906 ^ definitely 1.7558x faster ``` We can see that it makes private fields put operations significantly faster and considering DFG/FTL, we have same performance numbers than common properties. It's also important to notice that PrivateFields bench on "baseline" version is not running with JIT enabled.
Yusuke Suzuki
Comment 39
2020-09-15 11:53:34 PDT
Comment on
attachment 408180
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=408180&action=review
> Source/JavaScriptCore/bytecode/PutByIdStatus.cpp:316 > return PutByIdStatus(TakesSlowPath);
Is this if (isValidOffset(offset)) { ... } correct for define case?
Yusuke Suzuki
Comment 40
2020-09-15 13:03:25 PDT
Comment on
attachment 408180
[details]
Patch Discussed with Caio at Slack. My suggestion is that we should have branches and ASSERTs in code that is newly exercised by PutPrivate to ensure that this new semantic is correctly handled.
Yusuke Suzuki
Comment 41
2020-09-15 13:29:03 PDT
Comment on
attachment 408180
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=408180&action=review
Commented, I think the change is being really solid. I think we should make PutByIdStatus / PutByIdVariant / ComplexPutById etc. robust against private name things, and after that the change looks good :)
> Source/JavaScriptCore/dfg/DFGNode.h:2298 > + if (op() == PutPrivateName || op() == PutPrivateNameById)
I think you can just remove this and return `return PrivateFieldPutKind::fromByte(m_opInfo2.as<uint8_t>());` since we have `ASSERT(hasPrivateFieldPutKind());`.
> Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp:160 > + return operationPutByIdDefinePrivateFieldStrictOptimize;
Let's make this function switch. This will prevent us from missing new m_putKind handling. m_putKind did not have many kinds. But now it has. If the enum has various kinds, switch is better for readability & avoids the bug missing handling some values. switch (m_putKind) { case DirectPrivateFieldSet: { ASSERT(m_ecmaMode.isStrict()); return operationPutByIdSetPrivateFieldStrictOptimize; } case DirectPrivateFieldDefine: { ASSERT(m_ecmaMode.isStrict()); return operationPutByIdDefinePrivateFieldStrictOptimize; } case Direct: { if (m_ecmaMode.isStrict()) return operationPutByIdDirectStrictOptimize; return operationPutByIdDirectNonStrictOptimize; } case NonDirect: { if (m_ecmaMode.isStrict()) return operationPutByIdStrictOptimize; return operationPutByIdNonStrictOptimize; } }
> Source/JavaScriptCore/jit/JITOperations.cpp:1188 > + baseObject->putPrivateField(globalObject, propertyName, value, slot);
I suggest renaming putPrivateField to setPrivateField.
> Source/JavaScriptCore/jit/JITOperations.cpp:1213 > + baseObject->putPrivateField(globalObject, propertyName, value, slot);
I suggest renaming putPrivateField to setPrivateField.
> Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:-1197 > - if (subscript.isDouble()) { > - ASSERT(!isPrivateFieldAccess); > - double subscriptAsDouble = subscript.asDouble(); > - uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble); > - if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) { > - baseObject->putDirectIndex(globalObject, subscriptAsUInt32, value, 0, isStrictMode ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow); > - LLINT_END(); > - } > - } > -
I think it is worth keeping it. Let's keep it for now.
Caio Lima
Comment 42
2020-09-16 08:22:31 PDT
Comment on
attachment 408180
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=408180&action=review
>> Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:-1197 >> - > > I think it is worth keeping it. Let's keep it for now.
I don't see how this path adds anything that previous `subscript.tryGetAsUint32Index()` is covering. From `subscript.tryGetAsUint32Index` we already check if it `isNumber` and also checks if it's a valid `uint32_t` and is index. @caitp do you remember why you added it on
https://trac.webkit.org/changeset/262613
?
Caio Lima
Comment 43
2020-09-17 09:51:22 PDT
Created
attachment 409045
[details]
Patch
Caio Lima
Comment 44
2020-09-17 11:51:13 PDT
Created
attachment 409053
[details]
Patch
Caio Lima
Comment 45
2020-09-21 09:52:20 PDT
Created
attachment 409281
[details]
Patch
Caio Lima
Comment 46
2020-09-21 19:12:27 PDT
Created
attachment 409344
[details]
Patch
Yusuke Suzuki
Comment 47
2020-09-22 01:03:59 PDT
Comment on
attachment 409344
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=409344&action=review
r=me
> Source/JavaScriptCore/jit/JITInlineCacheGenerator.cpp:170 > + default: > + RELEASE_ASSERT_NOT_REACHED(); > + return nullptr;
Let's remove this default clause. To make it possible, let's make PutKind enum class. Then, we can purge this default clause. This make it possible that future extension of PutKind will warn at compile time.
> Source/JavaScriptCore/jit/Repatch.cpp:555 > + default: > + RELEASE_ASSERT_NOT_REACHED(); > + return nullptr;
Ditto.
> Source/JavaScriptCore/jit/Repatch.cpp:578 > + default: > + RELEASE_ASSERT_NOT_REACHED(); > + return nullptr;
Ditto.
> Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1189 > if (subscript.isDouble()) { > - ASSERT(!isPrivateFieldAccess); > double subscriptAsDouble = subscript.asDouble(); > uint32_t subscriptAsUInt32 = static_cast<uint32_t>(subscriptAsDouble); > if (subscriptAsDouble == subscriptAsUInt32 && isIndex(subscriptAsUInt32)) {
OK, now I understand. `subscript.tryGetAsUint32Index` subsumes this branch. So, this is dead code. Then we can remove it.
> Source/JavaScriptCore/runtime/PrivateFieldPutKind.cpp:39 > + if (isSet()) > + out.print("Set"); > + else > + out.print("Define");
Let's support None too.
Caio Lima
Comment 48
2020-09-22 17:23:57 PDT
Created
attachment 409429
[details]
Patch
Caio Lima
Comment 49
2020-09-22 19:24:38 PDT
Created
attachment 409441
[details]
Patch
Caio Lima
Comment 50
2020-09-22 22:31:39 PDT
Created
attachment 409450
[details]
Patch
Caio Lima
Comment 51
2020-09-23 09:31:17 PDT
Created
attachment 409480
[details]
Patch
Caio Lima
Comment 52
2020-09-23 09:33:52 PDT
Comment on
attachment 409480
[details]
Patch Thank you very much for the review!
EWS
Comment 53
2020-09-23 10:19:42 PDT
Committed
r267489
: <
https://trac.webkit.org/changeset/267489
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 409480
[details]
.
Radar WebKit Bug Importer
Comment 54
2020-09-23 10:20:21 PDT
<
rdar://problem/69443132
>
Caio Lima
Comment 55
2020-11-19 13:04:49 PST
***
Bug 214421
has been marked as a duplicate of this bug. ***
Caio Lima
Comment 56
2020-11-19 13:10:01 PST
***
Bug 212784
has been marked as a duplicate of this bug. ***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug