[webkit-changes] [WebKit/WebKit] 18d9fe: [JSC] Skip ProxyObject's ICs trap result validatio...
Commit Queue
noreply at github.com
Wed Apr 26 20:07:09 PDT 2023
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 18d9fef12db3ad57b2a20f7a8c8120059be66c70
https://github.com/WebKit/WebKit/commit/18d9fef12db3ad57b2a20f7a8c8120059be66c70
Author: Alexey Shvayka <ashvayka at apple.com>
Date: 2023-04-26 (Wed, 26 Apr 2023)
Changed paths:
M JSTests/microbenchmarks/proxy-get-miss-handler.js
M JSTests/microbenchmarks/proxy-get.js
M JSTests/microbenchmarks/proxy-has-hit.js
M JSTests/microbenchmarks/proxy-has-miss-handler.js
M JSTests/microbenchmarks/proxy-has-miss.js
M JSTests/microbenchmarks/proxy-set-miss-handler.js
M JSTests/microbenchmarks/proxy-set.js
M Source/JavaScriptCore/builtins/BuiltinNames.h
M Source/JavaScriptCore/builtins/ProxyHelpers.js
M Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h
M Source/JavaScriptCore/bytecode/BytecodeList.rb
M Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp
M Source/JavaScriptCore/bytecode/LinkTimeConstant.h
M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
M Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
M Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
M Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
M Source/JavaScriptCore/dfg/DFGClobberize.h
M Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
M Source/JavaScriptCore/dfg/DFGDoesGC.cpp
M Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
M Source/JavaScriptCore/dfg/DFGGraph.cpp
M Source/JavaScriptCore/dfg/DFGNode.h
M Source/JavaScriptCore/dfg/DFGNodeType.h
M Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
M Source/JavaScriptCore/dfg/DFGSafeToExecute.h
M Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
M Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
M Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
M Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
M Source/JavaScriptCore/ftl/FTLCapabilities.cpp
M Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
M Source/JavaScriptCore/jit/JIT.cpp
M Source/JavaScriptCore/jit/JIT.h
M Source/JavaScriptCore/jit/JITOpcodes.cpp
M Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
M Source/JavaScriptCore/llint/LLIntSlowPaths.h
M Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
M Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
M Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
M Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h
M Source/JavaScriptCore/runtime/JSGlobalProxy.h
M Source/JavaScriptCore/runtime/JSTypeInfo.h
M Source/JavaScriptCore/runtime/PropertySlot.h
M Source/JavaScriptCore/runtime/ProxyObject.cpp
M Source/JavaScriptCore/runtime/ProxyObject.h
M Source/JavaScriptCore/runtime/Structure.cpp
M Source/JavaScriptCore/runtime/Structure.h
M Source/JavaScriptCore/runtime/StructureInlines.h
M Source/JavaScriptCore/wasm/js/WebAssemblyGCObjectBase.h
M Source/WebCore/bindings/js/JSDOMWindowProperties.h
Log Message:
-----------
[JSC] Skip ProxyObject's ICs trap result validation in the common case
https://bugs.webkit.org/show_bug.cgi?id=255661
<rdar://problem/108269769>
Reviewed by Yusuke Suzuki.
Invariants of the essential internal methods [1] are enforced for all objects, both ordinary and exotic,
to avoid them having unpredictable behavior that negatively impacts developer experience and creates
security issues.
Enforcing them for Proxy objects is especially cumbersome, given traps are userland code, and quite
expensive performance-wise: invariants invalidation requires checking property attributes,
which currently requires JS => C++ call.
After carefully analyzing all the invariants of the all internal methods, it was concluded that if
[[ProxyTarget]] is an ordinary extensible object without non-configurable properties, validation of
the invariants can be safely (non-observably) skipped.
trap name IC attributes checked
======================== == ==================================
getOwnPropertyDescriptor no non-configurable || non-extensible
defineProperty no non-configurable || non-extensible
has yes non-configurable || non-extensible
get yes non-configurable && (non-writable || accessor)
set yes non-configurable && (non-writable || accessor)
deleteProperty maybe non-configurable || non-extensible
ownKeys no non-configurable || non-extensible
This change:
1. Introduces OverridesIsExtensible out-of-line type info flag to tighten Structure's didPreventExtensions()
flag, making it more pessimistic: it being `true` doesn't necessarily mean the structure is non-extensible,
but the reverse of it being `false` can be safely relied on.
It's not a completely new approach: https://github.com/WebKit/WebKit/pull/11843 does the same thing.
This change was proved not to introduce bugs since Structure's didPreventExtensions() flag is currently
checked only for objects without isExtensible() override.
2. Introduces hasNonConfigurableProperties and hasNonConfigurableReadOnlyOrGetterSetterProperties Structure
flags that are also pessimistic.
When inferring their initial values, we do extra care not to be overly pessimistic for objects except
JSFinalObject by checking overridesGetOwnPropertySlot() so that userland code, which heavily uses
Map / Set as [[ProxyTarget]], more performant, while making an exception for JSArray's non-configurable
non-structure "length" property.
While there is existing hasReadOnlyOrGetterSetterPropertiesExcludingProto flag, we can't combine it with
hasNonConfigurableProperties because MobX installs a non-writable administration property even on arrays,
which have non-configurable "length" already, so combining them would disable optimization for JSArray.
3. Introduces HasStructureWithFlags bytecode op to be utilized in ProxyObject IC helpers to skip trap result
validation for most of ProxyObject's targets. In the follow-ups, this approach will be expanded to C++ code.
Currently, due to lack of proper profiling of GetInternalField results, constant folding for HasStructureWithFlags
doesn't work in microbenchmarks.
ToT patch
proxy-has-miss 159.9825+-2.4190 ^ 43.1435+-0.5994 ^ definitely 3.7082x faster
proxy-set-miss-handler 158.7617+-2.3615 ^ 139.2158+-1.9197 ^ definitely 1.1404x faster
proxy-set 125.5967+-1.3678 ^ 14.4533+-0.1739 ^ definitely 8.6898x faster
proxy-get 115.8061+-2.2413 ^ 14.2136+-0.1138 ^ definitely 8.1475x faster
<geometric> 138.5985+-0.9526 ^ 33.3237+-0.2255 ^ definitely 4.1592x faster
[1]: https://tc39.es/ecma262/#sec-invariants-of-the-essential-internal-methods
* Source/JavaScriptCore/builtins/BuiltinNames.h:
* Source/JavaScriptCore/builtins/ProxyHelpers.js:
(linkTimeConstant.performProxyObjectHas):
(linkTimeConstant.performProxyObjectGet):
(linkTimeConstant.performProxyObjectSetSloppy):
(linkTimeConstant.performProxyObjectSetStrict):
* Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h:
* Source/JavaScriptCore/bytecode/BytecodeList.rb:
* Source/JavaScriptCore/bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* Source/JavaScriptCore/bytecode/LinkTimeConstant.h:
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitHasStructureWithFlags):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_mustValidateResultOfProxyGetAndSetTraps):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_mustValidateResultOfProxyTrapsExceptGetAndSet):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGHeapLocation.cpp:
(WTF::printInternal):
* Source/JavaScriptCore/dfg/DFGHeapLocation.h:
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::structureFlags):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* Source/JavaScriptCore/jit/JIT.h:
* Source/JavaScriptCore/jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_has_structure_with_flags):
* Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm:
* Source/JavaScriptCore/llint/LowLevelInterpreter64.asm:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::globalFuncHandleProxySetTrapResult): Deleted.
* Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h:
* Source/JavaScriptCore/runtime/JSTypeInfo.h:
(JSC::TypeInfo::overridesIsExtensible const):
* Source/JavaScriptCore/runtime/PropertySlot.h:
* Source/JavaScriptCore/runtime/ProxyObject.cpp:
(JSC::ProxyObject::performPut):
(JSC::ProxyObject::validatePositiveSetTrapResult):
(JSC::ProxyObject::validateSetTrapResult): Deleted.
* Source/JavaScriptCore/runtime/ProxyObject.h:
* Source/JavaScriptCore/runtime/Structure.cpp:
(JSC::Structure::validateFlags):
(JSC::Structure::Structure):
(JSC::Structure::nonPropertyTransitionSlow):
* Source/JavaScriptCore/runtime/Structure.h:
(JSC::Structure::isNonExtensibleOrHasNonConfigurableProperties const):
(JSC::Structure::bitField const):
* Source/JavaScriptCore/runtime/StructureInlines.h:
(JSC::Structure::add):
(JSC::Structure::attributeChange):
* Source/JavaScriptCore/wasm/js/WebAssemblyGCObjectBase.h:
* Source/WebCore/bindings/js/JSDOMWindowProperties.h:
Canonical link: https://commits.webkit.org/263443@main
More information about the webkit-changes
mailing list