Commit Graph

1185 Commits

Author SHA1 Message Date
Mark Lam c209a4cab6 Add some offlineasm enhancements.
https://bugs.webkit.org/show_bug.cgi?id=229332
rdar://82163923

Reviewed by Keith Miller.

1. Enhance "include" offlineasm Instruction to always attempt to include an asm
   file from <build-products>/usr/local/include/WebKitAdditions/ first.  If the
   specified file is not available there, then it will attempt to include the file
   from the same directory as the current source file (which in practice, means
   Source/JavaScriptCore/llint/).

2. Enhance "include" offlineasm Instruction to allow an optional file to be
   included if it exists.  For example, the following offlineasm code:

        include? LowLevelInterpreterAdditions

   ... will attempt to include a file LowLevelInterpreterAdditions.asm.  If the
   file does not exist, this will be a no-op.  Note: the "?" after the "include"
   means the include is optional.

3. Enhanced "emit" offlineasm Instruction to be able to take more than one operand.

   "emit" used to just copy the string operand that follows into the generated
   LLIntAssembly.h.  Now, "emit" can take multiple comma separated operands, and
   will concatenate all the operands.

   Additionally, "emit" can now take a LocalLabelReference as an operand.  For
   example, this offline asm code:

           emit "b ", .done
           ...
        .done:

   ... will generate this inline asm code in LLIntAssembly.h:

        "b " LOCAL_LABEL_STRING(_offlineasm_someLabel_done) "\n"

   This makes it easier to emit branches to local labels.

4. Also fixed LLInt code alignment for ARM_THUMB2 and ARM64.

   Previously, it was aligned using ".align 4" which means aligned on a 4
   instruction boundary.  Note: the interpretation of .align varies for different
   target CPU architectures.

   Now, we do the alignment using ".balign 4" which means align on a 4 byte
   boundary.  This is the intended alignment because ARM64 instruction size is
   4 bytes, and ARM_THUMB2 instruction size is either 2 bytes or 4 bytes.
   Using .align before was potentially wasting some code space.

* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter.cpp:
* offlineasm/ast.rb:
* offlineasm/parser.rb:



Canonical link: https://commits.webkit.org/240738@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@281321 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-20 17:01:00 +00:00
Mark Lam bb29688e15 Ensure that unused LLInt opcodes are not inadvertently used.
https://bugs.webkit.org/show_bug.cgi?id=229161

Reviewed by Robin Morisset.

The op macro is used for generating LLInt asm code for some entry points to the
LLInt, where we don't need 16 bits and 32 bit wide versions of the entry point.
For example, we use it for llint_program_prologue.

Note that llint_program_prologue is generated using:

    op(llint_program_prologue, macro () ...

where op is:

    macro op(l, fn)
        commonOp(l, macro () end, macro (size)
            size(fn, macro() end, macro() end, macro(gen) gen() end)
            #        ^            ^----- wide32 generator
            #        `------------------ wide16 generator
        end)
    end

Note that the generators for the wide16 and wide32 versions of the entry point
currently emit nothing.  As a result, if we ever have a bug that ends up
dispatching to llint_program_prologue_wide16 or llint_program_prologue_wide32,
we'll end up falling thru to llint_module_program_prologue, which just happens
to be the entry point positioned after those labels.

This patch adds breakpoints in those 2 unused generators so that we won't
inadvertently execute code for something else.

* llint/LowLevelInterpreter.asm:



Canonical link: https://commits.webkit.org/240574@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@281115 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-16 23:11:51 +00:00
Michael Catanzaro 2a6731b62b Adding missing REFERENCED_FROM_ASM annotations to facilitate LTO
https://bugs.webkit.org/show_bug.cgi?id=228865

Patch by Michael Catanzaro <mcatanzaro@gnome.org> on 2021-08-09
Reviewed by Yusuke Suzuki.

When investigating why WebKitGTK fails to build with LTO (link-time optimization) enabled,
one of the GCC developers noticed that we are missing __attribute__ (("used")) on several
C++ functions declared in LLIntSlowPaths.h and WasmSlowPaths.h that are called only from
asm. Without this attribute, GCC assumes the functions are unused and drops them, then
linking fails because they really are used.

* llint/LLIntSlowPaths.h:
* wasm/WasmSlowPaths.h:

Canonical link: https://commits.webkit.org/240354@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280770 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-09 10:53:05 +00:00
Keith Miller af53d48e72 for-in should only emit one loop in bytecode
https://bugs.webkit.org/show_bug.cgi?id=227989

Reviewed by Yusuke Suzuki.

JSTests:

* microbenchmarks/for-in-double-array-with-own-named.js: Added.
(test):
* microbenchmarks/for-in-double-array.js: Added.
(test):
* microbenchmarks/for-in-getters.js: Added.
(test):
* microbenchmarks/for-in-int32-array-with-own-named.js: Added.
(test):
* microbenchmarks/for-in-int32-array.js: Added.
(test):
* microbenchmarks/for-in-int32-object-with-own-named-and-getters.js: Added.
(test):
* microbenchmarks/for-in-int32-object-with-own-named.js: Added.
(test):
* microbenchmarks/for-in-object-with-own-named.js: Added.
(sum):
(opaqueSet):
* microbenchmarks/for-in-string-array.js: Added.
(test):
* microbenchmarks/for-of-iterate-array-map-set.js: Added.
(sum):
(let.generator):
* stress/for-in-array-mode.js:
(test):
* stress/for-in-base-reassigned-later.js:
* stress/for-in-delete-during-iteration.js:
* stress/for-in-primitive-index-on-prototype.js: Added.
(test):
* stress/for-in-tests.js:
* stress/has-own-property-structure-for-in-loop-correctness.js:
(test5):

Source/JavaScriptCore:

This patch redesigns how we implement for-in loops. Before this patch we would emit three copies of the for-in loop body. One for the indexed properties, one for the named-own properties, and one for generic properties (anything else). This had a couple of problems. Firstly, it meant bytecode size grew exponentially to number of nested for-in loops. This in turn meant DFG/FTL compilation took much longer.

Going off our experience with fast for-of, this patch turns for-in loops specializations into
a "fused" opcode that internally switches on the enumeration mode it currently sees. For example, if we are enumerating an own-named property, the new enumerator_get_by_val bytecode will check the enumerator cell's cached structure matches the base's then load the property offset directly.

There are four new opcodes this patch adds, which replace the various operations we had for the specialized loops previously. The new opcodes are EnumeratorGetByVal, EnumeratorInByVal, EnumeratorHasOwnProperty, and EnumeratorNext. The first three correspond to GetByVal, InByVal, and HasOwnProperty respectively. The EnumeratorNext opcode has three results in bytecode, the next enumeration value's mode, the index of the property name, and the property name string itself. When enumeration is done EnumeratorNext returns JS null as the property name string. Since the DFG doesn't support tuples yet this opcode is spilt into four new nodes. The first computes the updated index and mode for the next enumeration key, which is encoded into a single JS number. Then there are two nodes that extract the mode and index. Finally, the last new node produces the property name string or null based on the extracted mode and index.

Since, in most benchmarks, any given enumeration opcode tends to profile exactly one enumeration mode. This patch focuses primarily on reimplementing all the optimizations we have for any one specific mode. This means there are still potential optimizations for the multi-mode flavors of each new opcode.

The main optimizations implemented for each new opcode are:

EnumeratorNext:
1) IndexedMode loops are loaded and checked for presence inline (DFG/FTL).
2) NamedMode is computed inline as long as the cached structure on the enumerator cell matches the base (Baseline+). This can only differ if there's a transition.
3) property names are extracted from the cached buffer inline (Baseline+).

EnumeratorGetByVal:
EnumeratorInByVal:
EnumeratorHasOwnProperty:
1) IndexedMode has all the optimizations of a normal XByVal on indexed properties (DFG/FTL).
2) NamedMode will extract the value directly from the inline/out-of-line offset if the structure matches the enumerator's (Baseline+).

There are also a few interesting changes worth mentioning here:
1) If a for-in loop would produce an empty enumerator we now always
return the VMs empty enumerator. This has two benefits, most importantly, it distingishes between an unprofiled for-in loop and empty enumeration, which prevents OSR exit loops. Also, it means that the various Enumerator opcodes no longer need to handle undefined/null when `toObject`ing the base value.

2) The enumerator now contains a bit set of all the modes it will produce. This removes a few extra branches when speculating on the modes we will see in EnumeratorNext.

3) In the DFG, enumerator GetByVal relies on compileGetByVal to set the result it also passes a prefix callback which emits code after the various cases set up their operands but before code is emitting to help satisfy the branch over register allocation validation. Also, the array mode branch in compileGetByVal passes the data format that it would prefer, which for normal GetByVal is returned. For EnumeratorGetByVal, that preference is completely ignored and it always returns DataFormatJS.

* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::or8):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::or8):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::rshift64):
(JSC::MacroAssemblerX86_64::or8): Deleted.
* builtins/BuiltinNames.h:
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* bytecode/LinkTimeConstant.h:
* bytecode/Opcode.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::recordHasOwnPropertyInForInLoop):
(JSC::BytecodeGenerator::emitInByVal):
(JSC::BytecodeGenerator::emitGetByVal):
(JSC::BytecodeGenerator::emitEnumeratorNext):
(JSC::BytecodeGenerator::emitEnumeratorHasOwnProperty):
(JSC::BytecodeGenerator::pushForInScope):
(JSC::BytecodeGenerator::popForInScope):
(JSC::rewriteOp):
(JSC::ForInContext::finalize):
(JSC::BytecodeGenerator::findForInContext):
(JSC::BytecodeGenerator::recordHasOwnStructurePropertyInForInLoop): Deleted.
(JSC::BytecodeGenerator::emitGetEnumerableLength): Deleted.
(JSC::BytecodeGenerator::emitHasEnumerableIndexedProperty): Deleted.
(JSC::BytecodeGenerator::emitHasEnumerableStructureProperty): Deleted.
(JSC::BytecodeGenerator::emitHasEnumerableProperty): Deleted.
(JSC::BytecodeGenerator::emitHasOwnStructureProperty): Deleted.
(JSC::BytecodeGenerator::emitEnumeratorStructurePropertyName): Deleted.
(JSC::BytecodeGenerator::emitEnumeratorGenericPropertyName): Deleted.
(JSC::BytecodeGenerator::emitToIndexString): Deleted.
(JSC::BytecodeGenerator::pushIndexedForInScope): Deleted.
(JSC::BytecodeGenerator::popIndexedForInScope): Deleted.
(JSC::BytecodeGenerator::pushStructureForInScope): Deleted.
(JSC::BytecodeGenerator::popStructureForInScope): Deleted.
(JSC::StructureForInContext::finalize): Deleted.
(JSC::IndexedForInContext::finalize): Deleted.
(JSC::BytecodeGenerator::findStructureForInContext): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::ForInContext::isValid const):
(JSC::ForInContext::invalidate):
(JSC::ForInContext::local const):
(JSC::ForInContext::propertyName const):
(JSC::ForInContext::propertyOffset const):
(JSC::ForInContext::enumerator const):
(JSC::ForInContext::mode const):
(JSC::ForInContext::ForInContext):
(JSC::ForInContext::bodyBytecodeStartOffset const):
(JSC::ForInContext::type const): Deleted.
(JSC::ForInContext::isIndexedForInContext const): Deleted.
(JSC::ForInContext::isStructureForInContext const): Deleted.
(JSC::ForInContext::asIndexedForInContext): Deleted.
(JSC::ForInContext::asStructureForInContext): Deleted.
(JSC::StructureForInContext::StructureForInContext): Deleted.
(JSC::StructureForInContext::index const): Deleted.
(JSC::StructureForInContext::property const): Deleted.
(JSC::StructureForInContext::enumerator const): Deleted.
(JSC::StructureForInContext::baseVariable const): Deleted.
(JSC::StructureForInContext::addGetInst): Deleted.
(JSC::StructureForInContext::addInInst): Deleted.
(JSC::StructureForInContext::addHasOwnPropertyJump): Deleted.
(JSC::IndexedForInContext::IndexedForInContext): Deleted.
(JSC::IndexedForInContext::index const): Deleted.
(JSC::IndexedForInContext::addGetInst): Deleted.
* bytecompiler/NodesCodegen.cpp:
(JSC::HasOwnPropertyFunctionCallDotNode::emitBytecode):
(JSC::ForInNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::isSaneChain const):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::injectOSR):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::setJSArraySaneChainIfPossible):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGIntegerRangeOptimizationPhase.cpp:
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasStorageChild const):
(JSC::DFG::Node::storageChildIndex):
(JSC::DFG::Node::hasArrayMode):
(JSC::DFG::Node::hasEnumeratorMetadata const):
(JSC::DFG::Node::enumeratorMetadata):
* dfg/DFGNodeType.h:
* dfg/DFGOpInfo.h:
(JSC::DFG::OpInfo::OpInfo):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSSALoweringPhase.cpp:
(JSC::DFG::SSALoweringPhase::handleNode):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
(JSC::DFG::SpeculativeJIT::compileGetByValOnString):
(JSC::DFG::SpeculativeJIT::setIntTypedArrayLoadResult):
(JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithString):
(JSC::DFG::SpeculativeJIT::compileGetByValForObjectWithSymbol):
(JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
(JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdateIndexAndMode):
(JSC::DFG::SpeculativeJIT::compileEnumeratorNextExtractIndex):
(JSC::DFG::SpeculativeJIT::compileEnumeratorNextExtractMode):
(JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
(JSC::DFG::SpeculativeJIT::compileEnumeratorGetByVal):
(JSC::DFG::SpeculativeJIT::compileEnumeratorHasProperty):
(JSC::DFG::SpeculativeJIT::compileEnumeratorInByVal):
(JSC::DFG::SpeculativeJIT::compileEnumeratorHasOwnProperty):
(JSC::DFG::SpeculativeJIT::compileHasIndexedProperty):
(JSC::DFG::SpeculativeJIT::compileGetEnumerableLength): Deleted.
(JSC::DFG::SpeculativeJIT::compileHasEnumerableProperty): Deleted.
(JSC::DFG::SpeculativeJIT::compileToIndexString): Deleted.
(JSC::DFG::SpeculativeJIT::compileHasEnumerableStructureProperty): Deleted.
(JSC::DFG::SpeculativeJIT::compileHasOwnStructurePropertyImpl): Deleted.
(JSC::DFG::SpeculativeJIT::compileHasOwnStructureProperty): Deleted.
(JSC::DFG::SpeculativeJIT::compileInStructureProperty): Deleted.
(JSC::DFG::SpeculativeJIT::compileGetEnumeratorPname): Deleted.
(JSC::DFG::SpeculativeJIT::compileGetDirectPname): Deleted.
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::allocate):
(JSC::DFG::JSValueOperand::regs):
(JSC::DFG::JSValueOperand::gpr):
(JSC::DFG::StorageOperand::StorageOperand):
(JSC::DFG::StorageOperand::~StorageOperand):
(JSC::DFG::StorageOperand::emplace):
(JSC::DFG::JSValueRegsTemporary::operator bool):
(JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByVal):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByVal):
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetByValImpl):
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCharAtImpl):
(JSC::FTL::DFG::LowerDFGToB3::compileStringCharAt):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* ftl/FTLOutput.h:
(JSC::FTL::Output::phi):
* generator/DSL.rb:
* interpreter/Register.h:
* interpreter/RegisterInlines.h:
(JSC::Register::operator=):
* jit/AssemblyHelpers.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::privateCompileHasIndexedProperty):
(JSC::JIT::emit_op_has_structure_propertyImpl): Deleted.
(JSC::JIT::emit_op_has_enumerable_structure_property): Deleted.
(JSC::JIT::emit_op_has_own_structure_property): Deleted.
(JSC::JIT::emit_op_in_structure_property): Deleted.
(JSC::JIT::emit_op_has_enumerable_indexed_property): Deleted.
(JSC::JIT::emitSlow_op_has_enumerable_indexed_property): Deleted.
(JSC::JIT::emit_op_get_direct_pname): Deleted.
(JSC::JIT::emit_op_enumerator_structure_pname): Deleted.
(JSC::JIT::emit_op_enumerator_generic_pname): Deleted.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileHasIndexedProperty):
(JSC::JIT::emit_op_has_structure_propertyImpl): Deleted.
(JSC::JIT::emit_op_has_enumerable_structure_property): Deleted.
(JSC::JIT::emit_op_has_own_structure_property): Deleted.
(JSC::JIT::emit_op_in_structure_property): Deleted.
(JSC::JIT::emit_op_has_enumerable_indexed_property): Deleted.
(JSC::JIT::emitSlow_op_has_enumerable_indexed_property): Deleted.
(JSC::JIT::emit_op_get_direct_pname): Deleted.
(JSC::JIT::emit_op_enumerator_structure_pname): Deleted.
(JSC::JIT::emit_op_enumerator_generic_pname): Deleted.
* jit/JITPropertyAccess.cpp:
(JSC::JIT::generateGetByValSlowCase):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_enumerator_next):
(JSC::JIT::emit_op_enumerator_get_by_val):
(JSC::JIT::emitSlow_op_enumerator_get_by_val):
(JSC::JIT::emit_enumerator_has_propertyImpl):
(JSC::JIT::emit_op_enumerator_in_by_val):
(JSC::JIT::emit_op_enumerator_has_own_property):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_enumerator_next):
(JSC::JIT::emit_op_enumerator_get_by_val):
(JSC::JIT::emitSlow_op_enumerator_get_by_val):
(JSC::JIT::emit_op_enumerator_in_by_val):
(JSC::JIT::emit_op_enumerator_has_own_property):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* runtime/CommonSlowPaths.h:
* runtime/FileBasedFuzzerAgent.cpp:
(JSC::FileBasedFuzzerAgent::getPredictionInternal):
* runtime/FileBasedFuzzerAgentBase.cpp:
(JSC::FileBasedFuzzerAgentBase::opcodeAliasForLookupKey):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSPropertyNameEnumerator.cpp:
(JSC::JSPropertyNameEnumerator::JSPropertyNameEnumerator):
(JSC::JSPropertyNameEnumerator::computeNext):
* runtime/JSPropertyNameEnumerator.h:
(JSC::propertyNameEnumerator):
* runtime/PredictionFileCreatingFuzzerAgent.cpp:
(JSC::PredictionFileCreatingFuzzerAgent::getPredictionInternal):


Canonical link: https://commits.webkit.org/240345@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-08-07 21:38:59 +00:00
Commit Queue d0333311de Unreviewed, reverting r279546, r279554, r279558 and r279567.
https://bugs.webkit.org/show_bug.cgi?id=227732

Speedometer/jQuery-TodoMVC 2-3% regression

Reverted changesets:

"[WebIDL] Rework runtime enabled properties leveraging
PropertyCallback"
https://bugs.webkit.org/show_bug.cgi?id=227275
https://commits.webkit.org/r279546

"[WebIDL] Generate constructor's hash table in
GenerateConstructorHelperMethods"
https://bugs.webkit.org/show_bug.cgi?id=227668
https://commits.webkit.org/r279554

"[WebIDL] Simplify generation of runtime conditionally read-
write attributes"
https://bugs.webkit.org/show_bug.cgi?id=227672
https://commits.webkit.org/r279558

"Use AbortSignal's [PrivateIdentifier] whenSignalAborted()
static method"
https://bugs.webkit.org/show_bug.cgi?id=227673
https://commits.webkit.org/r279567

Canonical link: https://commits.webkit.org/239449@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279635 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-07 03:12:05 +00:00
Alexey Shvayka a55a807985 [WebIDL] Rework runtime enabled properties leveraging PropertyCallback
https://bugs.webkit.org/show_bug.cgi?id=227275

Reviewed by Saam Barati.

JSTests:

* stress/lazy-property-cross-realm.js: Added.
* stress/lazy-property-get-cache.js: Added.
* stress/lazy-property-gopd.js: Added.
* stress/lazy-property-hasownproperty-cache.js: Added.
* stress/lazy-property-put-cache.js: Added.

Source/JavaScriptCore:

To make the implementation of WebIDL runtime enabled properties independent of eager
property reification, this change:

1. Introduces IsLazyPropertyEnabledCallback, which is needed separately from existing
   value callback to maintain the invariant that reifyStaticProperty() always puts a
   property, and to keep enumeration fast.

   Calling disableCaching() isn't enough to achieve correct [[Get]] inline caching,
   so isTaintedByOpaqueObject() is leveraged to prohibit caching of runtime disabled
   properties, just like in operationTryGetByIdOptimize().

   The only case that might seem weird is runtime disabled properties, which were
   enabled after all static properties were reified via [[Delete]], are not appearing.
   It's fixable, yet there is currently no demand for it.

2. Adds support for LazyPropertyCallback returning GetterSetter / CustomGetterSetter,
   ensuring correct structure flags and slot initialization. Previously, the callback
   was used to init only objects and constructors, using putDirect() unconditionally.

   To avoid mixing other non-basic attributes with PropertyCallback, which would require
   hoisting of checks against PropertyCallback and complicating attribute validation in
   HashTableValue methods, this patch checks the type of callback's return value instead.

   In the future, sticking to this approach will make returning CustomValue impossible
   as it can't be distinguished from CustomAccessor. That's fine because all present
   CustomValue usages merely do lazy init, which PropertyCallback is better suited for.

Also, this patch:

3. Expands setUpStaticFunctionSlot() to handle constant integers so the code using
   `Node.ELEMENT_NODE` & friends doesn't regress (proven by attached microbenchmark).

4. Removes extra checks from setUpStaticPropertySlot(), which is called only on
   non-reified properties.

5. Removes invariant that DOMJITAttribute property is read-only, which was broken
   by `document.body` having a non-JIT custom setter. This aligns non-reified
   properties with structure ones.

* jit/Repatch.cpp:
(JSC::tryCacheGetBy):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setupGetByIdPrototypeCache):
* runtime/HasOwnPropertyCache.h:
(JSC::HasOwnPropertyCache::tryAdd):
* runtime/JSObject.cpp:
(JSC::lookupPropertyForPut):
(JSC::JSObject::putInlineSlow):
(JSC::JSObject::reifyAllStaticProperties):
* runtime/JSObject.h:
(JSC::JSObject::getOwnNonIndexPropertySlot):
(JSC::JSObject::fillStructurePropertySlot):
* runtime/JSObjectInlines.h:
(JSC::JSObject::getNonReifiedStaticPropertyNames):
* runtime/Lookup.cpp:
(JSC::setUpStaticPropertySlot):
(JSC::setUpStaticFunctionSlot): Deleted.
* runtime/Lookup.h:
(JSC::HashTableValue::isLazyPropertyEnabled const):
(JSC::getStaticPropertySlotFromTable):
(JSC::reifyStaticProperty):
(JSC::reifyStaticProperties):
* tools/JSDollarVM.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSDollarVM::finishCreation):

Source/WebCore:

This performance-neutral change makes implementation of runtime enabled properties independent
of eager property reification, slightly optimizing DOM global objects initialization.
A follow-up patch (webkit.org/b/158557) will remove eager property reification of WebIDL
constructors / prototypes, further reducing CPU usage and memory cost on page load.

Provided we reify properties without creating transitions and avoid conversion to a cacheable
dictionary, that should not regress performance & memory usage as well. Non-reified custom
accessors / values are inline-cached, even through JSProxy. DOM methods are reified on first
lookup; the same approach is used for multiple hot JSC built-ins (e.g. StringPrototype).

A huge refactoring was required to keep generation of lazy property callbacks within a single
function. Handling of private identifiers was decoupled from public ones, while hash table
generation for constructors / prototypes / instances was merged into GenerateHashTable.

This approach preserves HashTable's immutability while avoiding addition of extra checks to
entry lookup and memory usage increase. Another important advantage: a feature that was
enabled after its interface was created, immediately becomes usable (no page reload needed).

Also, this change removes all usages of DeletePropertyModeScope from WebCore, which was used
to disable non-configurable constants at runtime, allowing its complete removal in the future.

No new tests, no behavior change.

* bindings/js/JSDOMBuiltinConstructor.h:
* bindings/js/JSDOMConstructor.h:
* bindings/js/JSDOMConstructorNotCallable.h:
* bindings/js/JSDOMConstructorNotConstructable.h:
* bindings/scripts/CodeGeneratorJS.pm:
Extract IDLInterface::className() to avoid passing $className as an argument.

(InstanceOperationCount): Deleted.
(PrototypeOperationCount): Deleted.
(InstancePropertyCount): Deleted.
(PrototypePropertyCount): Deleted.
(PrototypeHasStaticPropertyTable): Deleted.
(ConstructorHasProperties):
(PrototypeHasProperties):
(InstanceHasProperties):
Remove *Count helpers because they were incorrect with constants, overloads, private identifiers,
and Symbol.iterator. Instead, do the count in GeneratePropertiesHashTable to avoid duplicate checks.

(GeneratePropertiesHashTable):
(GenerateHashTableValueArray):
- Compute $hasSetterOrReadonlyProperties early because it's impossible to detect runtime enabled accessors,
  which are concealed behind PropertyAttribute::PropertyCallback, in GenerateHashTableValueArray.
- Set HashTable.hasSetterOrReadonlyProperties to `true` if a read-only value (constant) was seen.

(GenerateRuntimeEnableConditionalString):
Always use provided $globalObjectPtr parameter.

(GenerateHashTable):
- Simplify name inference for HashTable's values / indices since hash table names never include ":".
- Nicely simplify generation of hash table kind comment.
- Set HashTable.classForThis to `nullptr` for constructors because they can't have DOMAttribute properties.

(GenerateImplementation):
- Set ReadOnly attribute for runtime read-only accessors that shadow setter from static hash table.
- Reify "entries" property of an iterable interface to ensure its identity with Symbol.iterator method.

(GeneratePrivateIdentifiers):
- Add support for accelerated DOM attributes, which are rather common.
- Add support for static operations, which we have a use case for (see @whenSignalAborted).

(GeneratePrototypeDeclaration):
Set HasStaticPropertyTable structure flag for global interfaces as well, progressing idlharness.js test.

(GenerateConstructorHelperMethods):
Ensure that HasStaticPropertyTable structure flag is set for constructors as well.

(StringifyJSCAttributes):
(GetJSCAttributesForAttribute):
(ShouldBeOnInstance):
(GenerateHeader):
(GetAttributeGetter):
(GetAttributeSetter):
(GetAttributeJSValue):
(GetOperationJSValue):
(GenerateLazyPropertyCallbacks):
(GenerateCallbackImplementationContent):
(GetRuntimeEnabledStaticProperties): Deleted.

* bindings/scripts/test/JS/*: Updated.
* bindings/scripts/test/DOMWindowConstructors.idl:
* bindings/scripts/test/TestEnabledBySetting.idl:
* bindings/scripts/test/TestObj.idl:
Cover [PrivateIdentifiers] with accelerated DOM attributes, static operations, and constructors.

LayoutTests:

* platform/gtk/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
* platform/ios-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
* platform/mac-wk1/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
* platform/mac-wk2/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:
* platform/wpe/imported/w3c/web-platform-tests/html/dom/idlharness.https-expected.txt:


Canonical link: https://commits.webkit.org/239382@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279546 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-07-03 19:57:46 +00:00
Mikhail R. Gadelha 23d9da5cf2 Add LLInt fast path for less, lesseq, greater and greatereq
https://bugs.webkit.org/show_bug.cgi?id=226266

Patch by Mikhail R. Gadelha <mikhail@igalia.com> on 2021-06-28
Reviewed by Tadeu Zagallo.

The motivation is to add fast path for integers and doubles
in LLInt, so we don't need to go to slow path for those cases.

This patch implements the less, lesseq, greater, greatereq
instruction for ARMv7, MIPS and CLoop.

Microbenchmarking results:
* x86_64: number-comparison-inline definitely 1.3520x faster
* ARMv7: number-comparison-inline definitely 1.3520x faster

JetStream2 results:
* x86_64 jit: 1.015 times better
* x86_64 no-jit: 1.018 times better
* ARMv7 no-jit: 1.004 times worse

* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm.rb:
* offlineasm/cloop.rb:
* offlineasm/mips.rb:

Canonical link: https://commits.webkit.org/239211@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279343 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-28 17:55:12 +00:00
Xan Lopez 982695a54c [JSC] Implement returnEarlyFromInfiniteLoopsForFuzzing for 32bits
https://bugs.webkit.org/show_bug.cgi?id=227290

JSTests:

Patch by Xan Lopez <xan@igalia.com> on 2021-06-24
Reviewed by Mark Lam.

Now that we can return early from infinite (actual or just
extremely long running) loops on 32bits, we can pass these tests.

* stress/construct-return-early-from-infinite-loop-for-fuzzer.js: unskip for 32bits.
* stress/early-return-from-builtin2.js: ditto.
* stress/validate-does-gc-with-return-early-from-infinite-loop-2.js: ditto.
* stress/validate-does-gc-with-return-early-from-infinite-loop.js: ditto.

Source/JavaScriptCore:

Patch by Xan López <xan@igalia.com> on 2021-06-24
Reviewed by Mark Lam.

Mostly a matter of changing the counter type to uintptr_t and
making the baseline/dfg/ftl code generation work on both 32 and
64bits, most of it can be shared with minor tweaks.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileLoopHint):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_loop_hint):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter32_64.asm:
* runtime/VM.cpp:
(JSC::VM::addLoopHintExecutionCounter):
(JSC::VM::getLoopHintExecutionCounter):
* runtime/VM.h:

Canonical link: https://commits.webkit.org/239102@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279216 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-24 08:31:48 +00:00
Saam Barati da9b14f999 jitCompileAndSetHeuristics shouldn't return true when we fail to compile
https://bugs.webkit.org/show_bug.cgi?id=227155

Reviewed by Tadeu Zagallo.

JSTests:

* microbenchmarks/interpreter-wasm.js:
* microbenchmarks/memcpy-wasm-large.js:
* microbenchmarks/memcpy-wasm-medium.js:
* microbenchmarks/memcpy-wasm-small.js:
* microbenchmarks/memcpy-wasm.js:
* stress/wasm-error-message-cross-threads.js:

Source/JavaScriptCore:

jitCompileAndSetHeuristics should only return true when we've successfully
compiled a baseline JIT CodeBlock. However, with the rewrite to using a
unified JIT worklist, the code was changed to returning true when a
compilation finished, regardless of it being successful or not. This patch
fixes that error.

This bug was found by our existing executable allocation fuzzer, but at a low
hit rate. That fuzzer only ran a single test case. This patch also introduces
a new form of the executable fuzzer where we fail to allocate JIT code
randomly, and the crash manifests more reliably. And this patch also hooks
the new fuzzer into more JSC stress tests.

* dfg/DFGLICMPhase.cpp:
(JSC::DFG::LICMPhase::run):
* jit/ExecutableAllocationFuzz.cpp:
(JSC::doExecutableAllocationFuzzing):
* jsc.cpp:
(runJSC):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/OptionsList.h:

Source/WTF:

* wtf/WeakRandom.h:

Tools:

* Scripts/run-jsc-stress-tests:


Canonical link: https://commits.webkit.org/239041@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279126 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-22 17:48:42 +00:00
Ross Kirsling 57ebbb5b72 [JSC] Add JIT ICs for `#x in obj` feature
https://bugs.webkit.org/show_bug.cgi?id=226146

Reviewed by Saam Barati.

JSTests:

* microbenchmarks/has-private-brand.js: Added.
* microbenchmarks/has-private-name.js: Added.

Source/JavaScriptCore:

This patch implements JIT ICs for the new `#x in obj` feature and turns the feature on by default.
Implementation closely follows InByVal, though HasPrivateBrand has a few subtleties
(namely, it cannot be viewed in terms of a PropertySlot and should not be converted to InById).

Microbenchmarks:
    has-private-name        46.5777+-0.1374     ^      6.0589+-0.0296        ^ definitely 7.6875x faster
    has-private-brand       25.8823+-0.0561     ^     19.1509+-0.0447        ^ definitely 1.3515x faster

* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInByAsMatchStructure):
(JSC::DFG::ByteCodeParser::handleInById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileInByVal):
(JSC::DFG::SpeculativeJIT::compileHasPrivate):
(JSC::DFG::SpeculativeJIT::compileHasPrivateName):
(JSC::DFG::SpeculativeJIT::compileHasPrivateBrand):
* dfg/DFGSpeculativeJIT.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITInByValGenerator::JITInByValGenerator):
* jit/JITInlineCacheGenerator.h:
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitHasPrivate):
(JSC::JIT::emitHasPrivateSlow):
(JSC::JIT::emit_op_has_private_name):
(JSC::JIT::emitSlow_op_has_private_name):
(JSC::JIT::emit_op_has_private_brand):
(JSC::JIT::emitSlow_op_has_private_brand):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitHasPrivate):
(JSC::JIT::emitHasPrivateSlow):
(JSC::JIT::emit_op_has_private_name):
(JSC::JIT::emitSlow_op_has_private_name):
(JSC::JIT::emit_op_has_private_brand):
(JSC::JIT::emitSlow_op_has_private_brand):
* jit/Repatch.cpp:
(JSC::appropriateOptimizingInByFunction):
(JSC::appropriateGenericInByFunction):
(JSC::tryCacheInBy):
(JSC::repatchInBy):
(JSC::tryCacheHasPrivateBrand):
(JSC::repatchHasPrivateBrand):
(JSC::resetInBy):
(JSC::resetHasPrivateBrand):
* jit/Repatch.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
* runtime/CommonSlowPaths.h:
* runtime/OptionsList.h:


Canonical link: https://commits.webkit.org/239022@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279105 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-22 06:41:14 +00:00
Mark Lam f59662477a Rename numberOfPACBits to maxNumberOfAllowedPACBits.
https://bugs.webkit.org/show_bug.cgi?id=227156

Reviewed by Saam Barati.

Source/JavaScriptCore:

Just renaming the constant to better describe what it represents.  There are no
behavior changes.

* assembler/MacroAssemblerARM64E.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::cageWithoutUntagging):
(JSC::AssemblyHelpers::cageConditionallyAndUntag):
* llint/LowLevelInterpreter64.asm:

Source/WTF:

* wtf/CagedPtr.h:



Canonical link: https://commits.webkit.org/238949@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@279029 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-18 02:06:58 +00:00
Yusuke Suzuki 223870911c [JSC] Use ResolvedClosureVar to get brand from scope
https://bugs.webkit.org/show_bug.cgi?id=226677
rdar://78802869

Reviewed by Saam Barati.

JSTests:

* stress/private-access-nested-eval.js: Added.
(shouldThrow):
(shouldThrow.prototype.x):
(shouldThrow.prototype.m.C.prototype.z):
(shouldThrow.prototype.m.C.prototype.a):
(shouldThrow.prototype.m.C):
(shouldThrow.prototype.m):
* stress/private-access-nested.js: Added.
(shouldThrow):
(shouldThrow.prototype.x):
(shouldThrow.prototype.m.C.prototype.z):
(shouldThrow.prototype.m.C.prototype.a):
(shouldThrow.prototype.m.C):
(shouldThrow.prototype.m):

Source/JavaScriptCore:

Private brand lookup is doing wrong way to get scope.

    1. op_resolve_scope with private name (e.g. #x)
    2. then, doing op_get_from_scope with (1)'s scope with different name (e.g. @privateBrand)

This is wrong in JSC. We resolve scope at link-time in CodeBlock. So we need to ensure that both op_resolve_scope and op_get_from_scope
starts with the current scope-register. As a result, private-brand lookup is broken right now. Let's see the buggy case.

    class D {
      #x() {}
      m() {
        class C {
          #yy;
          #z() { }
          a() {
            this.#x(); // <===== This point.
          }
        }
        let c = new C();
        c.a();
      }
    }

In the above point, we first lookup the scope with #x, and we get the D's class-scope. But our get_from_scope is using privateBrand, and
privateBrand property exists too in C's class-scope too since C also has #yy and #z. As a result, CodeBlock linking configures the offset for
C's class-scope in get_from_scope. And this offset is different from D's class-scope's privateBrand.

Only allowed case for the above usage is ResolvedClosureVar. And generatorification uses it too. In this patch,

1. We ensure that class-scope (with private name) must have @privateBrand and @privateClassBrand with offset 1 and 0.
2. Use ResolvedClosureVar with the above pre-defined offset

Since CodeBlock's linking does not resolve the scope for get_from_scope if it is ResolvedClosureVar, we can just perform the desired ResolvedClosureVar lookup
with the given scope with the compiled offset.

* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::instantiateLexicalVariables):
(JSC::BytecodeGenerator::pushLexicalScope):
(JSC::BytecodeGenerator::pushLexicalScopeInternal):
(JSC::BytecodeGenerator::emitCreatePrivateBrand):
(JSC::BytecodeGenerator::emitGetPrivateBrand):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BaseDotNode::emitGetPropertyValue):
(JSC::BaseDotNode::emitPutProperty):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitDot):
(JSC::InNode::emitBytecode):
(JSC::BlockNode::emitBytecode):
(JSC::ForNode::emitBytecode):
(JSC::ForInNode::emitBytecode):
(JSC::ForOfNode::emitBytecode):
(JSC::SwitchNode::emitBytecode):
(JSC::ClassExprNode::emitBytecode):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
* parser/VariableEnvironment.h:

Canonical link: https://commits.webkit.org/238581@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278591 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-08 03:22:27 +00:00
Ross Kirsling 64dfd005eb [JSC] Implement JIT ICs for InByVal
https://bugs.webkit.org/show_bug.cgi?id=226563

Reviewed by Saam Barati.

JSTests:

* microbenchmarks/in-by-val-int32.js: Added.
* microbenchmarks/in-by-val-string-index.js: Added.
* microbenchmarks/in-by-val-symbol.js: Added.

Source/JavaScriptCore:

Until now, InByVal has had few optimizations implemented:
DFG would attempt to convert string index lookups to InById and int32 lookups to HasIndexedProperty,
but there has been no inline caching nor any special handling for symbol lookups.

This has become a more urgent problem now, as `#x in obj` (i.e. HasPrivateName / HasPrivateBrand)
will need to mimic InByVal's inline caching strategy in order to be deemed performant enough to ship.

This patch thus implements inline caching for InByVal at all JIT tiers.
The result is a night-and-day difference for symbols, a nice boost for string indices, and no change for int32s:

in-by-val-symbol                  203.5572+-2.7647     ^     19.1035+-0.7498        ^ definitely 10.6555x faster
in-by-val-string-index             87.0368+-44.7766          45.9971+-32.0007         might be 1.8922x faster
in-by-val-int32                   110.9904+-1.7109     ?    111.3431+-1.7558        ?

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/CheckPrivateBrandStatus.cpp:
(JSC::CheckPrivateBrandStatus::singleIdentifier const):
* bytecode/DeleteByStatus.cpp:
(JSC::DeleteByStatus::singleIdentifier const):
* bytecode/GetByStatus.cpp:
(JSC::GetByStatus::singleIdentifier const):
* bytecode/ICStatusMap.h:
* bytecode/ICStatusUtils.h:
(JSC::singleIdentifierForICStatus):
* bytecode/InByIdVariant.cpp:
(JSC::InByIdVariant::InByIdVariant):
(JSC::InByIdVariant::attemptToMerge):
(JSC::InByIdVariant::dumpInContext const):
* bytecode/InByIdVariant.h:
(JSC::InByIdVariant::identifier const):
(JSC::InByIdVariant::overlaps):
* bytecode/InByStatus.cpp: Renamed from Source/JavaScriptCore/bytecode/InByIdStatus.cpp.
(JSC::InByStatus::appendVariant):
(JSC::InByStatus::shrinkToFit):
(JSC::InByStatus::computeFor):
(JSC::InByStatus::computeForStubInfo):
(JSC::InByStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::InByStatus::merge):
(JSC::InByStatus::filter):
(JSC::InByStatus::markIfCheap):
(JSC::InByStatus::finalize):
(JSC::InByStatus::singleIdentifier const):
(JSC::InByStatus::dump const):
* bytecode/InByStatus.h: Renamed from Source/JavaScriptCore/bytecode/InByIdStatus.h.
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::addInByStatus): Renamed from addInByIdStatus.
* bytecode/RecordedStatuses.h:
* bytecode/SetPrivateBrandStatus.cpp:
(JSC::SetPrivateBrandStatus::singleIdentifier const):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInById):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addInByVal):
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasInByStatus): Renamed from hasInByIdStatus.
(JSC::DFG::Node::inByStatus): Renamed from inByIdStatus.
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileInByVal):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileInBy):
(JSC::FTL::DFG::LowerDFGToB3::compileInById):
(JSC::FTL::DFG::LowerDFGToB3::compileInByVal):
* jit/ICStats.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITInByValGenerator::JITInByValGenerator):
(JSC::JITInByValGenerator::generateFastPath):
(JSC::JITInByValGenerator::finalize):
(JSC::JITInByIdGenerator::JITInByIdGenerator):
* jit/JITInlineCacheGenerator.h:
(JSC::JITDelByIdGenerator::slowPathJump const):
(JSC::JITInByValGenerator::JITInByValGenerator):
(JSC::JITInByValGenerator::slowPathJump const):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitSlow_op_in_by_val):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitSlow_op_in_by_val):
* jit/Repatch.cpp:
(JSC::tryCacheInBy): Renamed from tryCacheInByID.
(JSC::repatchInBy): Renamed from repatchInByID.
(JSC::resetInBy): Renamed from resetInByID.
* jit/Repatch.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
* runtime/CommonSlowPaths.h:


Canonical link: https://commits.webkit.org/238465@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278445 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-04 03:10:54 +00:00
Darin Adler e98ff129bc Remove WTF::Optional synonym for std::optional, using that class template directly instead
https://bugs.webkit.org/show_bug.cgi?id=226433

Reviewed by Chris Dumez.

Source/JavaScriptCore:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

* inspector/scripts/codegen/generate_objc_protocol_types_implementation.py:
(ObjCProtocolTypesImplementationGenerator._generate_init_method_for_payload): Use auto instead
of Optional<>. Also use * instead of value() and nest the definition of the local inside an if
statement in the case where it's an optional.

* inspector/scripts/tests/expected/*: Regenerated these results.

Source/WebCore:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebCore/PAL:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebDriver:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebKit:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

* Scripts/webkit/tests: Regenerated expected results, by running the command "python
Scripts/webkit/messages_unittest.py -r". (How am I supposed to know to do that?)

Source/WebKitLegacy/ios:

* WebCoreSupport/WebChromeClientIOS.h: Let the do-webcore-rename script rename
Optional<> to std::optional<>.

Source/WebKitLegacy/mac:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WebKitLegacy/win:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

Source/WTF:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.

* wtf/Optional.h: Remove WTF::Optional.

Tools:

* <many files>: Let the do-webcore-rename script rename Optional<> to std::optional<>.


Canonical link: https://commits.webkit.org/238290@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278253 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-30 16:11:40 +00:00
Daniel Kolesa e5b1ed65bb [JSC] Fix crash on 32-bit big endian systems.
https://bugs.webkit.org/show_bug.cgi?id=226264

Patch by Daniel Kolesa <dkolesa@igalia.com> on 2021-05-27
Reviewed by Caio Araujo Neponoceno de Lima.

This is an instance where properly offsetting was missed since
the issue was not present in 2.30 series and therefore not fixed
by r273104.

* llint/LowLevelInterpreter32_64.asm:

Canonical link: https://commits.webkit.org/238201@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278157 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-27 09:56:53 +00:00
Tadeu Zagallo e42c8deaf6 Merge all the JIT worklists into a shared worklist
https://bugs.webkit.org/show_bug.cgi?id=226207

Reviewed by Saam Barati.

Delete the DFG and FTL worklists and refactor JITWorklist to handle the compilation
for all tiers. This reduces the total number of compiler threads while allowing each
tier to use more threads whenever necessary. The default configuration is for the
worklist to have 3 threads, baseline can use up to all 3 threads and DFG and FTL follow
the previous limits set through JSC::Options. Right now, the worklist will only do work
on upper tiers when all lower tiers have no pending tasks or have exceeded the maximum
number of concurrent compilations. i.e. by default we only DFG compile when there are
no baseline tasks in the queue and we only FTL compile when we either have no DFG tasks
in the queue OR there are already 2 DFG compilations in progress.

* API/JSVirtualMachine.mm:
(+[JSVirtualMachine setNumberOfDFGCompilerThreads:]):
(+[JSVirtualMachine setNumberOfFTLCompilerThreads:]):
* API/tests/testapi.mm:
(runJITThreadLimitTests):
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::checkIfOptimizationThresholdReached):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCommon.h:
(JSC::DFG::verboseCompilationEnabled):
(JSC::DFG::logCompilationChanges):
(JSC::DFG::shouldDumpGraphAtEachPhase):
(JSC::DFG::shouldDumpDisassembly):
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
(JSC::DFG::compile):
* dfg/DFGDriver.h:
* dfg/DFGGraph.h:
* dfg/DFGGraphSafepoint.h:
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
* dfg/DFGOSREntrypointCreationPhase.cpp:
(JSC::DFG::OSREntrypointCreationPhase::run):
* dfg/DFGOperations.cpp:
(JSC::DFG::triggerFTLReplacementCompile):
(JSC::DFG::tierUpCommon):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::codeSize const):
(JSC::DFG::Plan::finalizeInGC):
(JSC::DFG::Plan::notifyReady):
(JSC::DFG::Plan::cancel):
(JSC::DFG::Plan::compileInThreadImpl):
(JSC::DFG::Plan::finalize):
(JSC::DFG::Plan::iterateCodeBlocksForGC):
(JSC::DFG::Plan::checkLivenessAndVisitChildren):
(JSC::DFG::Plan::isKnownToBeLiveDuringGC):
(JSC::DFG::Plan::isKnownToBeLiveAfterGC):
* dfg/DFGPlan.h:
* dfg/DFGPlanInlines.h: Removed.
* dfg/DFGTierUpCheckInjectionPhase.cpp:
(JSC::DFG::TierUpCheckInjectionPhase::run):
* dfg/DFGWorklist.cpp: Removed.
* dfg/DFGWorklist.h: Removed.
* dfg/DFGWorklistInlines.h: Removed.
* ftl/FTLCompile.h:
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
(JSC::FTL::DFG::LowerDFGToB3::buildExitArguments):
* ftl/FTLState.cpp:
(JSC::FTL::State::State):
* ftl/FTLState.h:
(JSC::FTL::verboseCompilationEnabled):
(JSC::FTL::shouldDumpDisassembly):
* heap/Heap.cpp:
(JSC::Heap::completeAllJITPlans):
(JSC::Heap::iterateExecutingAndCompilingCodeBlocks):
(JSC::Heap::removeDeadCompilerWorklistEntries):
(JSC::Heap::stopThePeriphery):
(JSC::Heap::suspendCompilerThreads):
(JSC::Heap::resumeCompilerThreads):
(JSC::Heap::addCoreConstraints):
* heap/Heap.h:
* heap/RootMarkReason.h:
* jit/JIT.cpp:
(JSC::JIT::compileAndLinkWithoutFinalizing):
(JSC::JIT::codeSize const):
(JSC::JIT::compileTimeStats):
* jit/JIT.h:
* jit/JITBaselinePlan.cpp: Copied from Source/JavaScriptCore/ftl/FTLState.cpp.
(JSC::JITBaselinePlan::JITBaselinePlan):
(JSC::JITBaselinePlan::compileInThreadImpl):
(JSC::JITBaselinePlan::codeSize const):
(JSC::JITBaselinePlan::finalize):
* jit/JITBaselinePlan.h: Copied from Source/JavaScriptCore/dfg/DFGScannable.h.
* jit/JITCompilationKey.cpp: Renamed from Source/JavaScriptCore/dfg/DFGCompilationKey.cpp.
(JSC::JITCompilationKey::dump const):
* jit/JITCompilationKey.h: Renamed from Source/JavaScriptCore/dfg/DFGCompilationKey.h.
(JSC::JITCompilationKey::JITCompilationKey):
(JSC::JITCompilationKey::operator! const):
(JSC::JITCompilationKey::isHashTableDeletedValue const):
(JSC::JITCompilationKey::mode const):
(JSC::JITCompilationKey::operator== const):
(JSC::JITCompilationKey::hash const):
(JSC::JITCompilationKeyHash::hash):
(JSC::JITCompilationKeyHash::equal):
* jit/JITCompilationMode.cpp: Renamed from Source/JavaScriptCore/dfg/DFGCompilationMode.cpp.
(WTF::printInternal):
* jit/JITCompilationMode.h: Renamed from Source/JavaScriptCore/dfg/DFGCompilationMode.h.
(JSC::isFTL):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITPlan.cpp: Added.
(JSC::JITPlan::JITPlan):
(JSC::JITPlan::cancel):
(JSC::JITPlan::notifyCompiling):
(JSC::JITPlan::notifyReady):
(JSC::JITPlan::tier const):
(JSC::JITPlan::key):
(JSC::JITPlan::isKnownToBeLiveAfterGC):
(JSC::JITPlan::isKnownToBeLiveDuringGC):
(JSC::JITPlan::iterateCodeBlocksForGC):
(JSC::JITPlan::checkLivenessAndVisitChildren):
(JSC::JITPlan::computeCompileTimes const):
(JSC::JITPlan::reportCompileTimes const):
(JSC::JITPlan::compileInThread):
* jit/JITPlan.h: Added.
(JSC::JITPlan::~JITPlan):
(JSC::JITPlan::vm const):
(JSC::JITPlan::codeBlock const):
(JSC::JITPlan::thread const):
(JSC::JITPlan::mode const):
(JSC::JITPlan::stage const):
(JSC::JITPlan::isFTL const):
(JSC::JITPlan::finalizeInGC):
* jit/JITPlanStage.h: Renamed from Source/JavaScriptCore/dfg/DFGThreadData.cpp.
* jit/JITSafepoint.cpp: Renamed from Source/JavaScriptCore/dfg/DFGSafepoint.cpp.
(JSC::Safepoint::Safepoint):
(JSC::Safepoint::~Safepoint):
(JSC::Safepoint::begin):
(JSC::Safepoint::cancel):
* jit/JITSafepoint.h: Renamed from Source/JavaScriptCore/dfg/DFGSafepoint.h.
* jit/JITScannable.h: Copied from Source/JavaScriptCore/dfg/DFGScannable.h.
* jit/JITWorklist.cpp:
(JSC::JITWorklist::JITWorklist):
(JSC::JITWorklist::~JITWorklist):
(JSC::JITWorklist::existingGlobalWorklistOrNull):
(JSC::JITWorklist::ensureGlobalWorklist):
(JSC::JITWorklist::enqueue):
(JSC::JITWorklist::queueLength const):
(JSC::JITWorklist::suspendAllThreads):
(JSC::JITWorklist::resumeAllThreads):
(JSC::JITWorklist::compilationState):
(JSC::JITWorklist::completeAllReadyPlansForVM):
(JSC::JITWorklist::waitUntilAllPlansForVMAreReady):
(JSC::JITWorklist::completeAllPlansForVM):
(JSC::JITWorklist::cancelAllPlansForVM):
(JSC::JITWorklist::removeDeadPlans):
(JSC::JITWorklist::setMaximumNumberOfConcurrentDFGCompilations):
(JSC::JITWorklist::setMaximumNumberOfConcurrentFTLCompilations):
(JSC::JITWorklist::visitWeakReferences):
(JSC::JITWorklist::dump const):
(JSC::JITWorklist::removeAllReadyPlansForVM):
(JSC::JITWorklist::removeMatchingPlansForVM):
* jit/JITWorklist.h:
(JSC::JITWorklist::static_cast<size_t>):
* jit/JITWorklistInlines.h: Renamed from Source/JavaScriptCore/dfg/DFGScannable.h.
(JSC::JITWorklist::iterateCodeBlocksForGC):
* jit/JITWorklistThread.cpp: Added.
(JSC::JITWorklistThread::JITWorklistThread):
(JSC::JITWorklistThread::name const):
(JSC::JITWorklistThread::poll):
(JSC::JITWorklistThread::work):
(JSC::JITWorklistThread::threadDidStart):
(JSC::JITWorklistThread::threadIsStopping):
* jit/JITWorklistThread.h: Renamed from Source/JavaScriptCore/dfg/DFGThreadData.h.
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
* runtime/OptionsList.h:
* runtime/VM.cpp:
(JSC::VM::~VM):


Canonical link: https://commits.webkit.org/238161@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278082 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 15:15:22 +00:00
Mark Lam 2dba95ec1a Enhance Link Buffer stats to have more fine grain profiles, and to collect count information.
https://bugs.webkit.org/show_bug.cgi?id=226151
rdar://problem/78359436

Reviewed by Yusuke Suzuki.

And also add a total of the sizes.
Also added $vm.clearLinkBufferStats() which resets all the stats to 0.

Here's an example of that the new stats look like:

    Cummulative LinkBuffer profile sizes:
               BaselineJIT: 61092032 (58.261902 MB) count 11621 avg size 5257
                       DFG: 35387904 (33.748535 MB) count 11143 avg size 3175
               InlineCache: 19639155 (18.729358 MB) count 283890 avg size 69
              VirtualThunk: 14256800 (13.596344 MB) count 43900 avg size 324
                DFGOSRExit: 7636736 (7.282959 MB) count 5235 avg size 1458
                       FTL: 4927616 (4.699341 MB) count 5269 avg size 935
                      Wasm: 2134688 (2.035797 MB) count 847 avg size 2520
                   YarrJIT: 1320928 (1.259735 MB) count 2075 avg size 636
                FTLOSRExit: 1084096 (1.033875 MB) count 417 avg size 2599
                 WasmThunk: 41408 (40.437500 KB) count 252 avg size 164
                  FTLThunk: 25088 (24.500000 KB) count 426 avg size 58
             ExtraCTIThunk: 5984 (5.843750 KB) count 95 avg size 62
          SpecializedThunk: 3456 (3.375000 KB) count 19 avg size 181
                     Thunk: 1760 (1.718750 KB) count 10 avg size 176
        BoundFunctionThunk: 864 count 3 avg size 288
                LLIntThunk: 608 count 18 avg size 33
                  DFGThunk: 608 count 1 avg size 608
               DFGOSREntry: 160 count 1 avg size 160
                JumpIsland: 0
                    CSSJIT: 0
             Uncategorized: 0
                     Total: 147559891 (140.724078 MB)

* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::performFinalization):
(JSC::LinkBuffer::clearProfileStatistics):
(JSC::LinkBuffer::dumpProfileStatistics):
* assembler/LinkBuffer.h:
* dfg/DFGOSRExit.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrExitGenerationThunkGenerator):
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLThunks.cpp:
(JSC::FTL::genericGenerationThunkGenerator):
(JSC::FTL::slowPathCallThunkGenerator):
* jit/ExecutableAllocator.cpp:
* jit/JITOpcodes.cpp:
(JSC::JIT::op_ret_handlerGenerator):
(JSC::JIT::op_throw_handlerGenerator):
(JSC::JIT::op_enter_handlerGenerator):
(JSC::JIT::op_check_traps_handlerGenerator):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::slow_op_get_by_val_prepareCallGenerator):
(JSC::JIT::slow_op_get_private_name_prepareCallGenerator):
(JSC::JIT::slow_op_put_by_val_prepareCallGenerator):
(JSC::JIT::slow_op_put_private_name_prepareCallGenerator):
(JSC::JIT::slow_op_del_by_id_prepareCallGenerator):
(JSC::JIT::slow_op_del_by_val_prepareCallGenerator):
(JSC::JIT::slow_op_get_by_id_prepareCallGenerator):
(JSC::JIT::slow_op_get_by_id_with_this_prepareCallGenerator):
(JSC::JIT::slow_op_put_by_id_prepareCallGenerator):
(JSC::JIT::slow_op_get_from_scopeGenerator):
(JSC::JIT::slow_op_put_to_scopeGenerator):
* jit/SlowPathCall.cpp:
(JSC::JITSlowPathCall::generateThunk):
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::finalize):
* jit/ThunkGenerators.cpp:
(JSC::handleExceptionGenerator):
(JSC::handleExceptionWithCallFrameRollbackGenerator):
(JSC::popThunkStackPreservesAndHandleExceptionGenerator):
(JSC::checkExceptionGenerator):
(JSC::virtualThunkFor):
(JSC::boundFunctionCallGenerator):
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::generateThunkWithJumpToPrologue):
(JSC::LLInt::generateThunkWithJumpToLLIntReturnPoint):
(JSC::LLInt::getHostCallReturnValueThunk):
(JSC::LLInt::createJSGateThunk):
(JSC::LLInt::createWasmGateThunk):
(JSC::LLInt::createTailCallGate):
(JSC::LLInt::loopOSREntryGateThunk):
(JSC::LLInt::entryOSREntryGateThunk):
(JSC::LLInt::wasmOSREntryGateThunk):
(JSC::LLInt::exceptionHandlerGateThunk):
(JSC::LLInt::returnFromLLIntGateThunk):
(JSC::LLInt::tagGateThunk):
(JSC::LLInt::untagGateThunk):
(JSC::LLInt::jitCagePtrThunk):
* tools/JSDollarVM.cpp:
(JSC::JSDollarVM::finishCreation):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::throwStackOverflowFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGEntryTierUpThunkGenerator):
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):



Canonical link: https://commits.webkit.org/238059@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277928 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-23 06:07:01 +00:00
Ross Kirsling e40702b9a8 Support Ergonomic Brand Checks proposal (`#x in obj`)
https://bugs.webkit.org/show_bug.cgi?id=221093

Reviewed by Caio Araujo Neponoceno de Lima.

JSTests:

* stress/private-in.js: Added.
* test262/config.yaml: Add feature flag.

Source/JavaScriptCore:

This patch implements the following Stage 3 proposal (behind a runtime option):
https://github.com/tc39/proposal-private-fields-in-in

Specifically, it extends the `in` keyword to allow the LHS to be a private name,
thereby allowing users to implement Array.isArray-esque brand checks for their own classes
*without* having to wrap a private member get in a try-catch.

For example:
```
class C {
    #x;
    static isC(obj) { return #x in obj; }
}
```

This is done by adding two new bytecode ops, HasPrivateName and HasPrivateBrand. For the moment,
these are implemented without fast paths, as we should do so for InByVal first and then have these follow suit.

* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitHasPrivateName):
(JSC::BytecodeGenerator::emitHasPrivateBrand):
(JSC::BytecodeGenerator::emitCheckPrivateBrand):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::InNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileHasPrivateName):
(JSC::DFG::SpeculativeJIT::compileHasPrivateBrand):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileHasPrivateName):
(JSC::FTL::DFG::LowerDFGToB3::compileHasPrivateBrand):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.h:
* llint/LowLevelInterpreter.asm:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createPrivateIdentifierNode):
* parser/NodeConstructors.h:
(JSC::PrivateIdentifierNode::PrivateIdentifierNode):
* parser/Nodes.h:
(JSC::ExpressionNode::isPrivateIdentifier const):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseBinaryExpression):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createPrivateIdentifierNode):
* parser/VariableEnvironment.h:
* runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* runtime/CommonSlowPaths.h:
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::hasPrivateField):
(JSC::JSObject::hasPrivateBrand):
(JSC::JSObject::checkPrivateBrand):
* runtime/OptionsList.h:


Canonical link: https://commits.webkit.org/238057@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277926 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-23 03:50:06 +00:00
Ross Kirsling 7f7b0e6797 [JSC] Prune CommonSlowPaths of JITPropertyAccess functions
https://bugs.webkit.org/show_bug.cgi?id=225953

Reviewed by Mark Lam.

A few bytecode operations with slow paths in JITPropertyAccess appear to have either redundant or unnecessary
"common" slow paths; namely, get_private_name and del_by_val already have LLInt slow paths, while in_by_id
and get_by_id_with_this can have their "common" slow path moved to be LLInt-specific.

* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
* runtime/CommonSlowPaths.h:


Canonical link: https://commits.webkit.org/237895@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277716 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-19 05:21:57 +00:00
Mark Lam f5513225d5 Add support to collect stats on cumulative LinkBuffer linked sizes based on profiles.
https://bugs.webkit.org/show_bug.cgi?id=225617

Reviewed by Saam Barati.

Source/JavaScriptCore:

There are 2 ways to dump the stats:
1. Specify --dumpLinkBufferStats as an argument to the jsc shell.
2. Call $vm.dumpLinkBufferStats() from your JS script to get the stats as a string.
   e.g.
        $vm.print($vm.dumpLinkBufferStats());

Here's an example of what the dump looks like:

    Cummulative LinkBuffer profile sizes:
               BaselineJIT: 79480320 (75.798340 MB)
                       DFG: 36108672 (34.435913 MB)
                     Thunk: 22495360 (21.453247 MB)
               InlineCache: 19538521 (18.633386 MB)
                       FTL: 5186240 (4.945984 MB)
                      Wasm: 1998272 (1.905701 MB)
                   YarrJIT: 1331072 (1.269409 MB)
                    CSSJIT: 0
             Uncategorized: 0

The stats are currently grouped into some coarse profiles.  If needed, we can
break these down into more fine grain profiles later.

* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::performFinalization):
(JSC::LinkBuffer::dumpProfileStatistics):
* assembler/LinkBuffer.h:
(JSC::LinkBuffer::LinkBuffer):
* bytecode/InlineAccess.cpp:
(JSC::linkCodeInline):
(JSC::InlineAccess::rewireStubAsJump):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compile):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrExitGenerationThunkGenerator):
(JSC::DFG::osrEntryThunkGenerator):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLazySlowPath.cpp:
(JSC::FTL::LazySlowPath::generate):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLThunks.cpp:
(JSC::FTL::genericGenerationThunkGenerator):
(JSC::FTL::slowPathCallThunkGenerator):
* jit/ExecutableAllocator.cpp:
(JSC::jitWriteThunkGenerator):
* jit/JIT.cpp:
(JSC::JIT::compileWithoutLinking):
* jit/JITMathIC.h:
(JSC::JITMathIC::generateOutOfLine):
* jit/JITOpcodes.cpp:
(JSC::JIT::privateCompileHasIndexedProperty):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileHasIndexedProperty):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByVal):
(JSC::JIT::privateCompilePutPrivateNameWithCachedId):
(JSC::JIT::privateCompilePutByValWithCachedId):
* jit/Repatch.cpp:
(JSC::linkPolymorphicCall):
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::finalize):
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromCallSlowPathGenerator):
(JSC::linkCallThunkGenerator):
(JSC::linkPolymorphicCallThunkGenerator):
(JSC::virtualThunkFor):
(JSC::nativeForGenerator):
(JSC::arityFixupGenerator):
(JSC::unreachableGenerator):
(JSC::stringGetByValGenerator):
(JSC::boundFunctionCallGenerator):
* jsc.cpp:
(CommandLine::parseArguments):
(jscmain):
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::generateThunkWithJumpToPrologue):
(JSC::LLInt::generateThunkWithJumpToLLIntReturnPoint):
(JSC::LLInt::getHostCallReturnValueThunk):
(JSC::LLInt::createJSGateThunk):
(JSC::LLInt::createWasmGateThunk):
(JSC::LLInt::createTailCallGate):
(JSC::LLInt::loopOSREntryGateThunk):
(JSC::LLInt::entryOSREntryGateThunk):
(JSC::LLInt::wasmOSREntryGateThunk):
(JSC::LLInt::exceptionHandlerGateThunk):
(JSC::LLInt::returnFromLLIntGateThunk):
(JSC::LLInt::tagGateThunk):
(JSC::LLInt::untagGateThunk):
(JSC::LLInt::jitCagePtrThunk):
* tools/JSDollarVM.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSDollarVM::finishCreation):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::work):
(JSC::Wasm::BBQPlan::didCompleteCompilation):
* wasm/WasmBinding.cpp:
(JSC::Wasm::wasmToWasm):
* wasm/WasmLLIntPlan.cpp:
(JSC::Wasm::LLIntPlan::didCompleteCompilation):
* wasm/WasmOMGForOSREntryPlan.cpp:
(JSC::Wasm::OMGForOSREntryPlan::work):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/WasmThunks.cpp:
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::throwStackOverflowFromWasmThunkGenerator):
(JSC::Wasm::triggerOMGEntryTierUpThunkGenerator):
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::jsCallEntrypointSlow):
* yarr/YarrJIT.cpp:

Source/WebCore:

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::compile):



Canonical link: https://commits.webkit.org/237566@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277305 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-10 23:21:41 +00:00
Dmitry Bezhetskov e772c5b3f0 [WASM-Function-References] Add call_ref instruction
https://bugs.webkit.org/show_bug.cgi?id=222903

Patch by Dmitry Bezhetskov <dbezhetskov@igalia.com> on 2021-05-03
Reviewed by Yusuke Suzuki.

JSTests:

Add basic tests for new call_ref instruction:
https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md.
Add tests for calling same-instance wasm function, foreign-instance
wasm function and for calling imported js function.

* wasm.yaml:
* wasm/function-references/call_ref.js: Added.
(module):
(async basics):
(async indirectCall):
(async importHostCall):
* wasm/wasm.json:

Source/JavaScriptCore:

Add support for call_ref instruction from the typed function
references proposal: https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md.
call_ref calls the given function references from the stack
and it does almost the same stuff as call_indirect but
it doesn't check signatures because wasm types system guaranties
correctness.

* bytecode/BytecodeList.rb:
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* llint/LowLevelInterpreter.asm:
* llint/WebAssembly.asm:
* runtime/Gate.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addCallIndirect):
(JSC::Wasm::AirIRGenerator::addCallRef):
(JSC::Wasm::AirIRGenerator::emitIndirectCall):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::emitIndirectCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::B3IRGenerator::addCallRef):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::addCallRef):
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::doWasmCallRef):
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/js/JSWebAssemblyTable.cpp:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::WebAssemblyFunction):
* wasm/js/WebAssemblyFunction.h:
* wasm/js/WebAssemblyFunctionBase.cpp:
(JSC::WebAssemblyFunctionBase::WebAssemblyFunctionBase):
* wasm/js/WebAssemblyFunctionBase.h:
(JSC::WebAssemblyFunctionBase::offsetOfEntrypointLoadLocation):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::WebAssemblyWrapperFunction):
* wasm/js/WebAssemblyWrapperFunction.h:
* wasm/wasm.json:

Canonical link: https://commits.webkit.org/237242@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@276896 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-03 11:00:43 +00:00
Yusuke Suzuki 557bc7c422 [JSC] Use FixedVector for LLIntPrototypeLoadAdaptiveStructureWatchpoint vector
https://bugs.webkit.org/show_bug.cgi?id=224729

Reviewed by Darin Adler.

Replace Vector<LLIntPrototypeLoadAdaptiveStructureWatchpoint> with FixedVector.

* bytecode/CodeBlock.h:
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::initialize):
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setupGetByIdPrototypeCache):

Canonical link: https://commits.webkit.org/236772@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@276290 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-20 07:26:08 +00:00
Yusuke Suzuki cb1da55e9c [JSC] Do not copy SimpleJumpTable
https://bugs.webkit.org/show_bug.cgi?id=224472

Reviewed by Mark Lam.

This patch avoids copying UnlinkedSimpleJumpTable to SimpleJumpTable by decoupling CTI addresses from jump offset in SimpleJumpTable.
SimpleJumpTable and UnlinkedSimpleJumpTable are almost identical. SimpleJumpTable adds JIT jump target for each branch.
We should use data from UnlinkedSimpleJumpTable and jump via SimpleJumpTable. Do not need to have copy of branches from UnlinkedSimpleJumpTable.

This way removes Vector<SimpleJumpTable> from CodeBlock::RareData. And this is moved to CodeBlock::JITData. And it only includes jump target addresses,
and branch offset information is kept in UnlinkedSimpleJumpTable side. We no longer need to carefully copy these vectors in CodeBlock including DFG / FTL ones.

In LLInt, we instead use UnlinkedSimpleJumpTable for jumping.

In Baseline, we first allocate enough FixedVector<SimpleJumpTable> and fill content via SimpleJumpTable::ensureCTITable() call when compiling corresponding
switch opcode. Finally we fill these data structures with actual code locations in JIT::link function.

In DFG, we first collect UnlinkedSimpleJumpTable without copying. This is OK since it is kept by UnlinkedCodeBlock, and UnlinkedCodeBlock is kept by baseline CodeBlocks that
are handled by this DFG compilation. We hold Vector<const UnlinkedSimpleJumpTable*> in DFG::Graph and we materialize Vector<SimpleJumpTable> in DFG::Graph.
During DFG compilation, we touch this DFG::Graph's jump tables, and JIT compiler generates code via these tables. And when linking, we move the content to CodeBlock.

In FTL, while we use UnlinkedSimpleJumpTable in FTL code generation, FTL do not use SimpleJumpTable and instead FTL uses Switch in B3.

* bytecode/BytecodeDumper.cpp:
(JSC::CodeBlockBytecodeDumper<Block>::dumpSwitchJumpTables):
* bytecode/BytecodeDumper.h:
* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::run):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::switchJumpTable):
(JSC::CodeBlock::numberOfUnlinkedSwitchJumpTables const):
(JSC::CodeBlock::unlinkedSwitchJumpTable):
(JSC::CodeBlock::numberOfSwitchJumpTables const): Deleted.
(JSC::CodeBlock::clearSwitchJumpTables): Deleted.
(JSC::CodeBlock::addSwitchJumpTableFromProfiledCodeBlock): Deleted.
* bytecode/JumpTable.cpp:
(JSC::SimpleJumpTable::offsetForValue): Deleted.
* bytecode/JumpTable.h:
(JSC::SimpleJumpTable::ensureCTITable):
(JSC::SimpleJumpTable::ctiForValue const):
(JSC::SimpleJumpTable::isEmpty const):
(): Deleted.
(JSC::SimpleJumpTable::cloneNonJITPart const): Deleted.
(JSC::SimpleJumpTable::ctiForValue): Deleted.
(JSC::SimpleJumpTable::clear): Deleted.
* bytecode/PreciseJumpTargetsInlines.h:
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedSimpleJumpTable::offsetForValue const):
(JSC::UnlinkedSimpleJumpTable::add):
(JSC::UnlinkedCodeBlock::numberOfUnlinkedSwitchJumpTables const):
(JSC::UnlinkedCodeBlock::unlinkedSwitchJumpTable const):
(JSC::UnlinkedCodeBlock::unlinkedStringSwitchJumpTable const):
(JSC::UnlinkedCodeBlock::numberOfSwitchJumpTables const): Deleted.
(JSC::UnlinkedCodeBlock::switchJumpTable): Deleted.
(JSC::UnlinkedCodeBlock::unlinkedStringSwitchJumpTable): Deleted.
* bytecode/UnlinkedCodeBlockGenerator.cpp:
(JSC::UnlinkedCodeBlockGenerator::finalize):
* bytecode/UnlinkedCodeBlockGenerator.h:
(JSC::UnlinkedCodeBlockGenerator::numberOfUnlinkedSwitchJumpTables const):
(JSC::UnlinkedCodeBlockGenerator::addUnlinkedSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::unlinkedSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::numberOfSwitchJumpTables const): Deleted.
(JSC::UnlinkedCodeBlockGenerator::addSwitchJumpTable): Deleted.
(JSC::UnlinkedCodeBlockGenerator::switchJumpTable): Deleted.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::beginSwitch):
(JSC::prepareJumpTableForSwitch):
(JSC::BytecodeGenerator::endSwitch):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGGraph.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::emitSwitchString):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* jit/JIT.cpp:
(JSC::JIT::compileWithoutLinking):
(JSC::JIT::link):
* jit/JIT.h:
(JSC::SwitchRecord::SwitchRecord):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CachedTypes.cpp:
(JSC::CachedSimpleJumpTable::encode):
(JSC::CachedSimpleJumpTable::decode const):
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):

Canonical link: https://commits.webkit.org/236547@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275995 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-15 03:29:18 +00:00
Yusuke Suzuki 530aca80c4 [JSC] Do not copy StringSwitchJumpTable
https://bugs.webkit.org/show_bug.cgi?id=224414

Reviewed by Keith Miller.

Previously, we were copying UnlinkedStringJumpTable to CodeBlock's StringJumpTable because we embed CodeLocation pointer
inside CodeBlock's StringJumpTable. This is copying a mostly identical hashtable to each CodeBlock even in DFG and FTL. This
even prevents us from inlining op_switch_string in DFG and FTL because (1) we don't want to copy this string tables collected from
each inlined CodeBlock into a new DFG / FTL CodeBlock and (2) we cannot ref/deref StringImpl inside DFG / FTL compilers so copying
these tables in the compiler threads need additional "DesiredStringSwitchJumpTable" etc.

In this patch, we stop copying StringSwitchJumpTable. We decouple CodeLocation pointers from the hashtable so that we can use
UnlinkedStringJumpTable in UnlinkedCodeBlock. UnlinkedStringJumpTable's hashtable inclues m_indexInTable in each entry so that
we can have array of CodeLocation pointers in CodeBlock's JITData to have JIT jump targets separately. This design prevents us
from copying unnecessary hashtables, and even this paves the way to inlining switch_string in DFG and FTL.

* bytecode/BytecodeDumper.cpp:
(JSC::CodeBlockBytecodeDumper<Block>::dumpStringSwitchJumpTables):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::stringSwitchJumpTable):
(JSC::CodeBlock::numberOfUnlinkedStringSwitchJumpTables const):
(JSC::CodeBlock::unlinkedStringSwitchJumpTable):
(JSC::CodeBlock::numberOfStringSwitchJumpTables const): Deleted.
* bytecode/JumpTable.h:
(JSC::StringJumpTable::ctiForValue const):
(JSC::StringJumpTable::offsetForValue): Deleted.
(JSC::StringJumpTable::ctiForValue): Deleted.
(JSC::StringJumpTable::clear): Deleted.
* bytecode/PreciseJumpTargetsInlines.h:
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedStringJumpTable::offsetForValue const):
(JSC::UnlinkedCodeBlock::numberOfUnlinkedStringSwitchJumpTables const):
(JSC::UnlinkedCodeBlock::unlinkedStringSwitchJumpTable):
(JSC::UnlinkedStringJumpTable::offsetForValue): Deleted.
(JSC::UnlinkedCodeBlock::numberOfStringSwitchJumpTables const): Deleted.
(JSC::UnlinkedCodeBlock::stringSwitchJumpTable): Deleted.
* bytecode/UnlinkedCodeBlockGenerator.cpp:
(JSC::UnlinkedCodeBlockGenerator::finalize):
* bytecode/UnlinkedCodeBlockGenerator.h:
(JSC::UnlinkedCodeBlockGenerator::numberOfUnlinkedStringSwitchJumpTables const):
(JSC::UnlinkedCodeBlockGenerator::addUnlinkedStringSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::unlinkedStringSwitchJumpTable):
(JSC::UnlinkedCodeBlockGenerator::numberOfStringSwitchJumpTables const): Deleted.
(JSC::UnlinkedCodeBlockGenerator::addStringSwitchJumpTable): Deleted.
(JSC::UnlinkedCodeBlockGenerator::stringSwitchJumpTable): Deleted.
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::beginSwitch):
(JSC::prepareJumpTableForStringSwitch):
(JSC::BytecodeGenerator::endSwitch):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::switchStringSlow):
* ftl/FTLOperations.cpp:
(JSC::FTL::JSC_DEFINE_JIT_OPERATION):
* jit/JIT.cpp:
(JSC::JIT::link):
* jit/JIT.h:
(JSC::SwitchRecord::SwitchRecord):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_switch_string):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_switch_string):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/CachedTypes.cpp:
(JSC::CachedStringJumpTable::encode):
(JSC::CachedStringJumpTable::decode const):
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):

Canonical link: https://commits.webkit.org/236408@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275840 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-12 22:01:09 +00:00
Mark Lam 342fdbaa97 Enable VMTraps checks in RETURN_IF_EXCEPTION.
https://bugs.webkit.org/show_bug.cgi?id=224078
rdar://75037057

Reviewed by Keith Miller.

JSTests:

* stress/watchdog-fire-while-in-forEachInIterable.js: Added.

Source/JavaScriptCore:

In pre-existing code, termination of a VM's execution can already be requested
asynchronously (with respect to the mutator thread).  For example, sources of such
a request can be a watchdog timer firing, or a request to stop execution issued
from a main web thread to a worker thread.

This request is made by firing the VMTraps::NeedTermination event on VMTraps.
Firing the event here only means setting a flag to indicate the presence of the
request.  We still have to wait till the mutator thread reaches one of the
pre-designated polling check points to call VMTraps::handleTraps() in order to
service the request.  As a result of this need to wait for a polling check point,
if the mutator is executing in a long running C++ loop, then a termination request
may not be serviced for a long time.

However, we observed that a lot of our C++ loops already have RETURN_IF_EXCEPTION
checks.  Hence, if we can check VMTraps::needHandling() there, we can service the
VMTraps events more frequently even in a lot of C++ loops, and get a better response.

Full details of what this patch changes:

1. Shorten some type and methods names in the VMTraps class to make code easier to
   read e.g. EventType => Event, needTrapHandling => needHandling.

2. Remove the VMTraps::Mask class.  Mask was introduced so that we can express a
   concatenation of multiple VMTraps events to form a bit mask in a simple way.
   In the end, it isn't flexible enough but makes the code more complicated than
   necessary.  It is now replaced by the simpler solution of using macros to define
   the Events as bit fields.  Having Events as bit fields intrinsically make them
   easy to concatenate (bitwise or) or filter (bitwise and).

   Also removed the unused VMTraps::Error class.

3. Make VMTraps::BitField a uint32_t.  There was always unused padding in VMTraps
   to allow for this.  So, we'll just extend it to a full 32-bit to make it easier
   to add more events in the future for other uses.

4. Add NeedExceptionHandling as a VMTrap::Event.

5. Make VMTraps::m_trapBits Atomic.  This makes it easier to set and clear the
   NeedExceptionHandling bit from the mutator without a lock.

6. RETURN_IF_EXCEPTION now checks VMTraps::m_trapBits (via VMTraps::needHandling())
   instead of checking VM::m_exception.  If the VMTraps::m_trapBits is non-null,
   the macro will call VM:hasExceptionsAfterHandlingTraps() to service VMTraps
   events as appropriate before returning whether an exception is being thrown.
   The result of VM:hasExceptionsAfterHandlingTraps() will determine if
   RETURN_IF_EXCEPTION returns or not.

   VM:hasExceptionsAfterHandlingTraps() is intentionally designed to take a minimum
   of arguments (just the VM as this pointer).  This is because RETURN_IF_EXCEPTION
   is called from many places, and we would like to minimize code size bloating
   from this change.

7. Simplify paramaters of VMTraps::handleTraps().

   NeedDebuggerBreak's callFrame argument was always vm.topCallFrame anyway.
   So, the patch makes it explicit, and removes the callFrame parameter.

   NeedWatchdogCheck's globalObject argument should have always been
   vm.entryScope->globalObject(), and we can remove the globalObject parameter.

   Before this, we pass in whichever globalObject was convenient to grab hold of.
   However, the idea of the watchdog is to time out the current script executing
   on the stack.  Hence, it makes sense to identify thay script by the globalObject
   in use at VM entry.

   So far, the only clients that uses the watchdog mechanism only operates in
   scenarios with only one globalObject anyway.  So this formalization to use
   VMEntryScope's globalObject does not change the expected behavior.

8. Make the execution of termination more robust.  Before reading this, please
   read the description of the Events in VMTraps.h first, especially the section
   on NeedTermination.

   Here's the life cycle of a termination:

   a. a client requests termination of the current execution stack by calling
      VM::notifyNeedTermination().  notifyNeedTermination() does 2 things:

       i. fire the NeedTermination event on VMTraps.
      ii. set the VM::m_terminationInProgress flag.

   b. Firing the NeedTermination event on VMTraps means setting the NeedTermination
      bit on VMTraps::m_trapBits.  This bit will be polled by the mutator thread
      later at various designated points (including RETURN_IF_EXCEPTION, which we
      added in this patch).

      Once the mutator sees the NeedTermination bit is set, it will clear the bit
      and throw the TerminationException (see VMTraps::handleTraps()).  This is
      unless the mutator thread is currently in a DeferTermination scope (see (8)
      below).  If in a DeferTermination scope, then it will not throw the
      TerminationException.

      Since the NeedTermination bit is cleared, the VM will no longer call
      VMTraps::handleTraps() to service the event.  If the mutator thread is in
      a DeferTermination scope, then on exiting the scope (at scope destruction),
      the scope will see that VM::m_terminationInProgress is set, and throw the
      deferred TerminationException then.

   c. The TerminationException will trigger unwinding out of the current stack
      until we get to the outermost VMEntryScope.

   d. At the the outermost VMEntryScope, we will clear VM::m_terminationInProgress
      if the NeedTermination bit in VMtraps::m_trapBits is cleared.

      If the NeedTermination bit is set, then that means we haven't thrown the
      TerminationException yet.  Currently, clients expect that we must throw the
      TerminationException if NeedTermination was requested (again, read comments
      at the top of VMTraps.h).

      If the NeedTermination bit is set, we'll leave VM::m_terminationInProgress
      set until the next time we re-enter the VM and exit to the outermost
      VMEntryScope.

   e. The purpose of VM::m_terminationInProgress is to provide a summary of the
      fact that the VM is in a state of trying to terminate the current stack.

      Note that this state is first indicated by the NeedTermination bit being set
      in VMTraps::m_trapBits.  Then, in VMTraps::handleTraps(), the state is
      handed of with the NeedTermination bit being cleared, and the
      TerminationException being thrown.

      While the VM is in this termination state, we need to prevent new DFG/FTL
      JIT code from being compiled and run.  The reason is the firing of the
      NeedTermination event has invalidated DFG/FTL code on the stack, thereby
      allowing their baseline / LLInt versions which have VMTraps polling checks
      to run.  We don't want to compile new DFG / FTL code and possibly get stuck
      in loops in there before the termination is complete.

      In operationOptimize(), we check if VM::m_terminationInProgress is set, and
      prevent new DFG (and therefore FTL) code from being compiled if needed.
      Note: it is easier to check a single flag, VM::m_terminationInProgress,
      then to check both if the NeedTermination bit is set or if the
      TerminationException is being being thrown.

9. One complication of being able to service VMTraps in RETURN_IF_EXCEPTION checks
   is that some of our code (usually for lengthier initializations and bootstrapping)
   currently does not handle exceptions well, e.g. JSGlobalObject::init().  They
   rely on the code crashing if an exception is thrown while still initializing.

   However, for a worker thread, a TerminationException (requested by the main
   thread) may arrive before the initialization is complete.  This can lead to
   crashes because part of the initialization may be aborted in the presence of
   an exception, while other parts still expect everything prior to have been
   initialized correctly.  For resource exhaustion cases (which is abnormal), it
   is OK to crash.  For the TerminationException (which can be part of normal
   operation), we should not be crashing.

   To work around this, we introduce a DeferTermination RAII scope object that we
   deploy in this type of initialization code.  With the scope in effect,

   a. if a TerminationException arrives but hasn't been thrown yet, it will be
      deferred till the scope ends before being thrown.
   b. if a TerminationException has already been thrown, the scope will stash
      the exception, clear it from the VM so that the initialization code can
      run to completion, and then re-throw the exception when the scope ends.

   Currently, we only need to use the DeferTermination scope in a few places
   where we know that initialization code will only run for a short period of time.

   DeferTermination should not be used for code that can block waiting on an
   external event for a long time.  Obviously, doing so will prevent the VM
   termination mechanism from working.

       10. Replaced llint_slow_path_check_if_exception_is_uncatchable_and_notify_profiler
   and operationCheckIfExceptionIsUncatchableAndNotifyProfiler with
   llint_slow_path_retrieve_and_clear_exception_if_catchable and
   operationRetrieveAndClearExceptionIfCatchable.

   The 2 runtime functions doesn't actually do anything to notify a profiler.
   So, we drop that part of the name.

   After returning from these runtime functions respectively, the previous LLInt
   and JIT code, which calls these runtimes functions, would go on to load
   VM::m_exception, and then store a nullptr there to clear it.  This is wasteful.

   This patch changes the runtime function to clear and return the Exception
   instead.  As a result, the calling LLInt and JIT code is simplified a bit.

   Note also that clearing an exception now also entails clearing the
   NeedExceptionHandling bit in VMTraps::m_trapBits in an atomic way.  The above
   change makes it easy to do this clearing with C++ code.

       11. Fix ScriptFunctionCall::call() to handle exceptions correctly.  Previously,
   it had one case where it propagates an exception, while another eats it.
   Change this function to eat the exception in both cases.  This is approproiate
   because ScriptFunctionCall is only used to execute some Inspector instrumentation
   calls.  It doesn't make sense to propagate the exception back to user code.

       12. Fix the lazy initialization of JSGlobalObject::m_defaultCollator to be able to
   handle the TerminationException.

       13. Not related to TerminationException, but this patch also fixes
   MarkedArgumentBuffer::expandCapacity() to use Gigacage::tryMalloc() instead of
   Gigacage::malloc().  This is needed as one of the fixes to make the
   accompanying test case work.

This patch increases code size by 320K (144K for JSC, 176K for WebCore) measured
on x86_64.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::branchTest32):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::branchTest32):
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::branchTest32):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::branchTest32):
* bindings/ScriptFunctionCall.cpp:
(Deprecated::ScriptFunctionCall::call):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckTraps):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCheckTraps):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeModuleProgram):
* interpreter/InterpreterInlines.h:
(JSC::Interpreter::execute):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_catch):
(JSC::JIT::emit_op_check_traps):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_catch):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ArgList.cpp:
(JSC::MarkedArgumentBuffer::expandCapacity):
* runtime/DeferTermination.h: Added.
(JSC::DeferTermination::DeferTermination):
(JSC::DeferTermination::~DeferTermination):
* runtime/ExceptionScope.h:
(JSC::ExceptionScope::exception const):
(JSC::ExceptionScope::exception): Deleted.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::finishCreation):
* runtime/LazyPropertyInlines.h:
(JSC::ElementType>::callFunc):
* runtime/StringPrototype.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/VM.cpp:
(JSC::VM::hasExceptionsAfterHandlingTraps):
(JSC::VM::clearException):
(JSC::VM::setException):
(JSC::VM::throwTerminationException):
(JSC::VM::throwException):
* runtime/VM.h:
(JSC::VM::terminationInProgress const):
(JSC::VM::setTerminationInProgress):
(JSC::VM::notifyNeedTermination):
(JSC::VM::DeferExceptionScope::DeferExceptionScope):
(JSC::VM::DeferExceptionScope::~DeferExceptionScope):
(JSC::VM::handleTraps): Deleted.
(JSC::VM::needTrapHandling): Deleted.
(JSC::VM::needTrapHandlingAddress): Deleted.
(JSC::VM::setException): Deleted.
(JSC::VM::clearException): Deleted.
* runtime/VMEntryScope.cpp:
(JSC::VMEntryScope::~VMEntryScope):
* runtime/VMTraps.cpp:
(JSC::VMTraps::tryInstallTrapBreakpoints):
(JSC::VMTraps::fireTrap):
(JSC::VMTraps::handleTraps):
(JSC::VMTraps::takeTopPriorityTrap):
(JSC::VMTraps::deferTermination):
(JSC::VMTraps::undoDeferTermination):
* runtime/VMTraps.h:
(JSC::VMTraps::onlyContainsAsyncEvents):
(JSC::VMTraps::needHandling const):
(JSC::VMTraps::trapBitsAddress):
(JSC::VMTraps::isDeferringTermination const):
(JSC::VMTraps::notifyGrabAllLocks):
(JSC::VMTraps::hasTrapBit):
(JSC::VMTraps::clearTrapBit):
(JSC::VMTraps::setTrapBit):
(JSC::VMTraps::Mask::Mask): Deleted.
(JSC::VMTraps::Mask::allEventTypes): Deleted.
(JSC::VMTraps::Mask::bits const): Deleted.
(JSC::VMTraps::Mask::init): Deleted.
(JSC::VMTraps::interruptingTraps): Deleted.
(JSC::VMTraps::needTrapHandling): Deleted.
(JSC::VMTraps::needTrapHandlingAddress): Deleted.
(JSC::VMTraps::hasTrapForEvent): Deleted.
(JSC::VMTraps::setTrapForEvent): Deleted.
(JSC::VMTraps::clearTrapForEvent): Deleted.

Source/WebCore:

1. Add DeferTermination in WorkerOrWorkletScriptController::initScript().
   This allows us to avoid having to make all exception checking in
   WorkerOrWorkletScriptController::initScript() very thorough and complete.
   Currently, they aren't.

2. Fix WorkerOrWorkletScriptController::evaluate() to handle the TerminationException.

3. Fix JSEventListener::handleEvent() to handle the TerminationException correctly.
   Previously, in one case, it was checking scope.exception() for the exception,
   but the exception has already been taken out of there.

* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* workers/WorkerOrWorkletScriptController.cpp:
(WebCore::WorkerOrWorkletScriptController::evaluate):
(WebCore::WorkerOrWorkletScriptController::initScript):



Canonical link: https://commits.webkit.org/236368@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275797 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-10 16:12:19 +00:00
Mark Lam c80365976b Rename and make the TerminationException a singleton.
https://bugs.webkit.org/show_bug.cgi?id=224295

Reviewed by Keith Miller.

Source/JavaScriptCore:

We previously call it the TerminatedExecutionException, which is a mouthful but
adds no meaningful information.  It's now renamed to TerminationException.

We can make it a singleton because the TerminationException is just a VM internal
mechanism for implementing the termination of the current execution stack.  It
should never be exposed to user JS code, and therefore, there is no value in
making it a JS object.  Making it a singleton simplifies the code.

A TerminationException is now implemented as an Exception cell which holds a
Symbol with the name "TerminationError".  The TerminationException is only created
if needed e.g. if the JSC watchdog is created, or if the VM is for a Worker thread
which needs to be able to handle termination requests.

We'll also stop notifying the debugger when we throw the TerminationException.
This is because the TerminationException is not like ordinary exceptions that
should be reported to the debugger. The fact that the TerminationException uses
the exception handling mechanism is just a VM internal implementation detail.
It is not meaningful to report it to the debugger as an exception.

* API/JSContext.mm:
(-[JSContext evaluateJSScript:]):
* API/tests/ExecutionTimeLimitTest.cpp:
(testExecutionTimeLimit):
* bindings/ScriptFunctionCall.cpp:
(Deprecated::ScriptFunctionCall::call):
* heap/Heap.cpp:
(JSC::Heap::addCoreConstraints):
* inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::injectedScriptFor):
* inspector/JSGlobalObjectInspectorController.cpp:
(Inspector::JSGlobalObjectInspectorController::reportAPIException):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::unwind):
(JSC::Interpreter::notifyDebuggerOfExceptionToBeThrown):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jsc.cpp:
(checkException):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* runtime/ExceptionHelpers.cpp:
(JSC::TerminatedExecutionError::defaultValue): Deleted.
(JSC::createTerminatedExecutionException): Deleted.
(JSC::isTerminatedExecutionException): Deleted.
(JSC::throwTerminatedExecutionException): Deleted.
* runtime/ExceptionHelpers.h:
(): Deleted.
* runtime/JSObject.h:
(JSC::JSObject::get const):
* runtime/JSPromise.cpp:
(JSC::JSPromise::rejectWithCaughtException):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::ensureWatchdog):
(JSC::VM::ensureTerminationException):
(JSC::VM::throwTerminationException):
(JSC::VM::throwException):
* runtime/VM.h:
(JSC::VM::terminationException const):
(JSC::VM::isTerminationException const):
* runtime/VMTraps.cpp:
(JSC::VMTraps::handleTraps):

Source/WebCore:

In the WorkerOrWorkletScriptController constructor, we ensure the TerminationException
because workers need to support termination requests.

* bindings/js/JSDOMExceptionHandling.cpp:
(WebCore::reportException):
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSC_DEFINE_HOST_FUNCTION):
(WebCore::handleResponseOnStreamingAction):
* bindings/js/JSDOMPromise.cpp:
(WebCore::DOMPromise::whenPromiseIsSettled):
* bindings/js/JSDOMPromiseDeferred.cpp:
(WebCore::DeferredPromise::reject):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/ReadableStream.cpp:
(WebCore::invokeReadableStreamFunction):
(WebCore::ReadableStream::lock):
(WebCore::checkReadableStream):
* bindings/js/ReadableStreamDefaultController.cpp:
(WebCore::invokeReadableStreamDefaultControllerFunction):
(WebCore::ReadableStreamDefaultController::error):
(WebCore::ReadableStreamDefaultController::enqueue):
* workers/WorkerOrWorkletScriptController.cpp:
(WebCore::WorkerOrWorkletScriptController::WorkerOrWorkletScriptController):
(WebCore::WorkerOrWorkletScriptController::evaluate):
(WebCore::WorkerOrWorkletScriptController::linkAndEvaluateModule):
(WebCore::WorkerOrWorkletScriptController::loadAndEvaluateModule):


Canonical link: https://commits.webkit.org/236284@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275648 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-08 00:30:15 +00:00
Yusuke Suzuki 9f3bc2b47a [JSC] Use FixedVector more in bytecode dir and JumpTable
https://bugs.webkit.org/show_bug.cgi?id=224275

Reviewed by Michael Saboff and Mark Lam.

Source/JavaScriptCore:

1. Use FixedVector more in bytecode/ directory's long-living data structures.
2. Use FixedVector in SimpleJumpTable. This involves LLInt changes because we need to access FixedVector data from LLInt.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* bytecode/InlineCallFrame.cpp:
(JSC::InlineCallFrame::dumpInContext const):
* bytecode/InlineCallFrame.h:
* bytecode/JumpTable.h:
(JSC::SimpleJumpTable::clear):
* bytecode/ObjectPropertyConditionSet.cpp:
(JSC::ObjectPropertyConditionSet::mergedWith const):
(JSC::ObjectPropertyConditionSet::dumpInContext const):
(JSC::ObjectPropertyConditionSet::isValidAndWatchable const):
* bytecode/ObjectPropertyConditionSet.h:
(JSC::ObjectPropertyConditionSet::create):
(JSC::ObjectPropertyConditionSet::isValid const):
(JSC::ObjectPropertyConditionSet::size const):
(JSC::ObjectPropertyConditionSet::begin const):
(JSC::ObjectPropertyConditionSet::end const):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::findArgumentPositionForLocal):
(JSC::DFG::ByteCodeParser::flushImpl):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGCommonData.cpp:
(JSC::DFG::CommonData::validateReferences):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::isLiveInBytecode):
* dfg/DFGGraph.h:
* dfg/DFGPreciseLocalClobberize.h:
(JSC::DFG::PreciseLocalClobberizeAdaptor::readTop):
* dfg/DFGStackLayoutPhase.cpp:
(JSC::DFG::StackLayoutPhase::run):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetMyArgumentByVal):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::argumentsStart):
* jit/SetupVarargsFrame.cpp:
(JSC::emitSetupVarargsFrameFastCase):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ClonedArguments.cpp:
(JSC::ClonedArguments::createWithInlineFrame):

Source/WTF:

* wtf/FixedVector.h:
(WTF::FixedVector::offsetOfStorage):
* wtf/RefCountedArray.h:
(WTF::RefCountedArray::Header::size):
(WTF::RefCountedArray::Header::offsetOfLength):

Canonical link: https://commits.webkit.org/236271@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275626 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-07 21:14:57 +00:00
Yusuke Suzuki dd5ddd4b76 JSTests:
[JSC] WasmMemory caging should care about nullptr
https://bugs.webkit.org/show_bug.cgi?id=224268
<rdar://problem/74654838>

Reviewed by Mark Lam.

* wasm/stress/4g-memory-cage.js: Added.
(async test):
* wasm/stress/more-than-4g-offset-access-oom.js: Added.
(async test):
* wasm/stress/null-memory-cage-explicit.js: Added.
(async test):
* wasm/stress/null-memory-cage.js: Added.
(async test):

Source/JavaScriptCore:
[JSC] WasmMemory caging should care about nullptr
https://bugs.webkit.org/show_bug.cgi?id=224268
<rdar://problem/74654838>

Reviewed by Mark Lam.

1. Fix Wasm::MemoryHandle::boundsCheckingSize. We should just return m_mappedCapacity here since UINT32_MAX is not 4GB.
   This checking size can include redzone for fast-memory, but this is OK: bounds-check pass in LLInt (in upper tiers, we
   do not use bounds-check for fast-memory), and access to redzone, then fault occurs and signal handler can make it error
   since signal handler is checking whether the access is within Memory::fastMappedBytes which includes redzone.
2. Fix caging of wasm memory-base pointer in LLInt. We should use pointer sized length since it can be larger than 4GB.
   And we should handle nullptr case correctly: Wasm::MemoryHandle's memory can be nullptr when mapped size is zero.
   caging needs to handle this case as we do in CagedPtr::getMayBeNull.

* assembler/MacroAssemblerARM64E.h:
(JSC::MacroAssemblerARM64E::untagArrayPtrLength32):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::cageTypedArrayStorage):
* llint/LowLevelInterpreter64.asm:
* llint/WebAssembly.asm:
* offlineasm/arm64e.rb:
* offlineasm/ast.rb:
* offlineasm/instructions.rb:
* runtime/CagedBarrierPtr.h:
(JSC::CagedBarrierPtr::CagedBarrierPtr):
(JSC::CagedBarrierPtr::set):
(JSC::CagedBarrierPtr::get const):
(JSC::CagedBarrierPtr::getMayBeNull const):
(JSC::CagedBarrierPtr::at const):
(JSC::CagedBarrierPtr::setWithoutBarrier):
* wasm/WasmInstance.h:
(JSC::Wasm::Instance::updateCachedMemory):
* wasm/WasmMemory.cpp:
(JSC::Wasm::MemoryHandle::MemoryHandle):
* wasm/WasmMemory.h:

Source/WTF:
[JSC] WasmMemory caging should care nullptr
https://bugs.webkit.org/show_bug.cgi?id=224268
<rdar://problem/74654838>

Reviewed by Mark Lam.

Accept size_t since Wasm::Memory's length can be larger than 4GB.

* wtf/CagedPtr.h:
(WTF::CagedPtr::CagedPtr):
(WTF::CagedPtr::get const):
(WTF::CagedPtr::getMayBeNull const):
(WTF::CagedPtr::at const):
(WTF::CagedPtr::recage):
* wtf/CagedUniquePtr.h:
(WTF::CagedUniquePtr::CagedUniquePtr):
(WTF::CagedUniquePtr::create):
(WTF::CagedUniquePtr::tryCreate):

Canonical link: https://commits.webkit.org/236242@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275597 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-07 09:28:49 +00:00
Yusuke Suzuki fe1e3608aa [WTF] Introduce FixedVector and use it for FixedOperands
https://bugs.webkit.org/show_bug.cgi?id=224171

Reviewed by Mark Lam.

Source/JavaScriptCore:

Define FixedOperands<T> which uses FixedVector for its storage. We use FixedOperands in FTL::OSRExitDescriptor.
We also replace RefCountedArray<T> with FixedVector<T> if they are not requiring RefCountedArray<T>'s ref-counting
semantics.

* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::run):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantRegisters):
(JSC::CodeBlock::setNumParameters):
(JSC::CodeBlock::setRareCaseProfiles):
(JSC::CodeBlock::insertBasicBlockBoundariesForControlFlowProfiler):
* bytecode/CodeBlock.h:
* bytecode/Operands.h:
(JSC::Operands::Operands):
* bytecode/OperandsInlines.h:
(JSC::U>::dumpInContext const):
(JSC::U>::dump const):
(JSC::Operands<T>::dumpInContext const): Deleted.
(JSC::Operands<T>::dump const): Deleted.
* bytecode/PolyProtoAccessChain.h:
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
* bytecode/PolymorphicAccess.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::dumpExpressionRangeInfo):
(JSC::UnlinkedCodeBlock::expressionRangeForBytecodeIndex const):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::expressionInfo):
(JSC::UnlinkedCodeBlock::identifiers const):
(JSC::UnlinkedCodeBlock::constantRegisters):
(JSC::UnlinkedCodeBlock::constantsSourceCodeRepresentation):
(JSC::UnlinkedCodeBlock::constantIdentifierSets):
(JSC::UnlinkedCodeBlock::opProfileControlFlowBytecodeOffsets const):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::prepareJumpTableForSwitch):
* dfg/DFGJITCode.h:
* dfg/DFGPlan.h:
(JSC::DFG::Plan::tierUpInLoopHierarchy):
* ftl/FTLOSRExit.h:
* jit/GCAwareJITStubRoutine.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompileSlowCases):
* jit/PolymorphicCallStubRoutine.h:
* llint/LLIntOffsetsExtractor.cpp:
* llint/LowLevelInterpreter.asm:
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::parseClassFieldInitializerSourceElements):
* parser/Parser.h:
(JSC::Parser<LexerType>::parse):
(JSC::parse):
* runtime/CachedTypes.cpp:
(JSC::CachedVector::encode):
(JSC::CachedVector::decode const):
* wasm/js/JSWebAssemblyInstance.h:

Source/WTF:

This FixedVector<T> is a wrapper around RefCountedArray<T>, but this offers Vector-like copy / move semantics,
so that we can use this FixedVector<T> as a drop-in-replacement for fixed-sized Vector fields. The purpose
of that is saving memory by removing unnecessary storage (FixedVector is fixed-sized allocated) and putting size
into the allocated memory.

* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/FastBitVector.h:
(WTF::FastBitVector::FastBitVector):
* wtf/FixedVector.h: Added.
(WTF::FixedVector::FixedVector):
(WTF::FixedVector::operator=):
(WTF::FixedVector::size const):
(WTF::FixedVector::isEmpty const):
(WTF::FixedVector::byteSize const):
(WTF::FixedVector::data):
(WTF::FixedVector::begin):
(WTF::FixedVector::end):
(WTF::FixedVector::data const):
(WTF::FixedVector::begin const):
(WTF::FixedVector::end const):
(WTF::FixedVector::rbegin):
(WTF::FixedVector::rend):
(WTF::FixedVector::rbegin const):
(WTF::FixedVector::rend const):
(WTF::FixedVector::at):
(WTF::FixedVector::at const):
(WTF::FixedVector::operator[]):
(WTF::FixedVector::operator[] const):
(WTF::FixedVector::first):
(WTF::FixedVector::first const):
(WTF::FixedVector::last):
(WTF::FixedVector::last const):
(WTF::FixedVector::fill):
(WTF::FixedVector::operator== const):
(WTF::FixedVector::swap):
(WTF::swap):
* wtf/RefCountedArray.h:
(WTF::RefCountedArray::RefCountedArray):
(WTF::RefCountedArray::fill):
(WTF::RefCountedArray::swap):

Tools:

* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/FixedVector.cpp: Added.
(TestWebKitAPI::TEST):
(TestWebKitAPI::DestructorObserver::DestructorObserver):
(TestWebKitAPI::DestructorObserver::~DestructorObserver):
(TestWebKitAPI::DestructorObserver::operator=):

Canonical link: https://commits.webkit.org/236198@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275542 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-06 19:47:47 +00:00
Yusuke Suzuki 78f3a75eef REGRESSION(r274724): JITCage trampoline needs to be adjusted
https://bugs.webkit.org/show_bug.cgi?id=224065

Reviewed by Saam Barati.

r274724 introduced a new parameter to custom setters, but it didn't change the parameter recognization of JITCage trampolines for custom accessors.
As a result, we are jumping with the wrong pointer, and crash when custom setter is called with JITCage.

This patch fixes the above bug.

1. Now, custom getter and custom setter have different number of parameters. We should have two different trampolines to invoke it. We remove vmEntryCustomAccessor, and
   add vmEntryCustomGetter/vmEntryCustomSetter.
2. vmEntryCustomSetter should use a4 parameter as a executable address for trampoline.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCallDOMGetter):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileCallDOMGetter):
* llint/LLIntThunks.cpp:
* llint/LLIntThunks.h:
* llint/LowLevelInterpreter.asm:
* offlineasm/arm64.rb:
* offlineasm/registers.rb:
* runtime/PropertySlot.h:

Canonical link: https://commits.webkit.org/236056@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275392 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-01 23:06:51 +00:00
Alexey Shvayka d89995f9ef Align JSGlobalObject::defineOwnProperty() with the spec and other runtimes
https://bugs.webkit.org/show_bug.cgi?id=203456

Reviewed by Robin Morisset.

JSTests:

* microbenchmarks/global-var-put-to-scope.js: Added.
* stress/eval-func-decl-in-frozen-global.js:
Object.freeze() redefines all global variables as ReadOnly, including hoisted `var error`.
Aligns with V8.

* stress/global-object-define-own-property-put-to-scope.js: Added.
* stress/global-object-define-own-property.js: Added.
* stress/to-this-before-arrow-function-closes-over-this-that-starts-as-lexical-environment.js:
Fix unwanted name conflict, which was an error in the original test, not an intended part of it.
Also, remove misleading comment on `defineProperty` and assert accessors are created on global object.
Aligns with V8.

LayoutTests/imported/w3c:

* web-platform-tests/html/browsers/the-windowproxy-exotic-object/windowproxy-define-own-property-unforgeable-same-origin-expected.txt: Added.
* web-platform-tests/html/browsers/the-windowproxy-exotic-object/windowproxy-define-own-property-unforgeable-same-origin.html: Added.

Source/JavaScriptCore:

Per spec, top-level `var` bindings are non-configurable properties of the global
object [1], while `undefined` / `NaN` / `Infinity` are also non-writable [2].

Prior to this change, redefining global `var` binding with accessor descriptor
failed silently (rather than throwing a TypeError); redefining with data or
generic descriptor created a structure property, which took precedence over
symbol table entry in JSGlobalObject::getOwnPropertySlot(), effectively
destroying live binding between `global.foo` and `var foo`.

This patch re-engineers JSGlobalObject::defineOwnProperty(), fixing both issues
mentioned above. If defineOwnProperty() override is removed, there is no way
a live binding can be maintained.

In a follow-up change, JSGlobalObject::getOwnPropertySlot() will be updated to
search symbol table first, aligning it with the spec [3], put(), and
defineOwnProperty(). Apart from consistency, this will bring a mild speed-up.

To accomodate global `var` binding reassignment right after it becomes read-only
(in the same scope), this patch introduces a watchpoint that can be fired by
JSGlobalObject::defineOwnProperty(). put_to_scope performance is neutral.

Also, this patch removes unused symbolTableGet() overload and orphaned
JSGlobalObject::defineGetter() / JSGlobalObject::defineSetter() declarations.

[1]: https://tc39.es/ecma262/#sec-object-environment-records-createmutablebinding-n-d
[2]: https://tc39.es/ecma262/#sec-value-properties-of-the-global-object
[3]: https://tc39.es/ecma262/#sec-global-environment-records-getbindingvalue-n-s

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::needsDynamicLookup):
(JSC::DFG::ByteCodeParser::parseBlock):
* jit/JIT.cpp:
(JSC::JIT::emitVarReadOnlyCheck):
* jit/JIT.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_put_to_scope):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_put_to_scope):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::defineOwnProperty):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::varReadOnlyWatchpoint):
* runtime/JSSymbolTableObject.h:
(JSC::symbolTableGet):

Source/WebCore:

This patch removes `location` special-casing, which a) incorrectly returned
`false` if new descriptor was the same as the current one and b) failed
silently otherwise (rather than throwing a TypeError).

However, this change introduces `window` / `document` special-casing because
they exist on the structure and as symbol table entries (for performance reasons).
Aligns WebKit with Blink and partly with Gecko.

Test: imported/w3c/web-platform-tests/html/browsers/the-windowproxy-exotic-object/windowproxy-define-own-property-unforgeable-same-origin.html

* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::JSDOMWindow::defineOwnProperty):

LayoutTests:

* fast/dom/Window/Location/window-override-location-using-defineGetter-expected.txt:
* fast/dom/Window/Location/window-override-location-using-defineGetter.html:
* fast/dom/Window/Location/window-override-window-using-defineGetter-expected.txt:
* fast/dom/Window/Location/window-override-window-using-defineGetter.html:
* fast/dom/getter-on-window-object2-expected.txt:
* fast/dom/getter-on-window-object2.html:


Canonical link: https://commits.webkit.org/235202@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@274308 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-12 00:08:05 +00:00
Daniel Kolesa 27c427e0b0 [JSC] Fix segfaults on 32-bit big endian systems
https://bugs.webkit.org/show_bug.cgi?id=221710

Patch by Daniel Kolesa <dkolesa@igalia.com> on 2021-02-18
Reviewed by Yusuke Suzuki.

In these cases, we are loading values from memory into registers.
Seemingly, these values are present at an offset on 32-bit big
endian targets; therefore, add PayloadOffset, which is 4 on BE
and 0 on LE (same behavior as right now) and is already present
in other similar accesses in the file.

* llint/LowLevelInterpreter32_64.asm:

Canonical link: https://commits.webkit.org/234302@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@273104 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-18 23:20:43 +00:00
Yusuke Suzuki c60cbacb4b WebAssembly: implement non-trapping float to int conversion
https://bugs.webkit.org/show_bug.cgi?id=173471

Patch by Yusuke Suzuki  <ysuzuki@apple.com> and Sergey Rubanov <chi187@gmail.com> on 2021-02-16
Reviewed by Tadeu Zagallo.

JSTests:

* wasm/spec-tests/binary-leb128.wast.js:
* wasm/spec-tests/conversions.wast.js:
* wasm/wasm.json:

Source/JavaScriptCore:

This patch implements trunc-saturated opcodes in Wasm. This does not trap, and instead it generates
saturated-truncated integer results from floats.

    1. If the input is NaN, then return 0.
    2. If the input is higher than the maximum value, then return the maximum value (e.g. INT_32MAX).
    3. If the input is lower than the minimum value, then return the minimum value (e.g. INT_32MIN).

These wasm opcodes are defined as two-byte opcodes. Currently, we do not have a mechanism to define
this kind of opcodes automatically, so we manually define them. We will clean up in the future patch.

We rename ExtTableOpType to Ext1OpType since it is no longer limited to table opcodes.

* generator/Wasm.rb:
* llint/WebAssembly.asm:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::truncSaturated):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::truncSaturated):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::truncSaturated):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::truncSaturated):
* wasm/generateWasm.py:
(isNormal):
* wasm/generateWasmOpsHeader.py:
(opcodeWithTypesMacroizer):
(saturatedTruncMacroizer):
(saturatedTruncMacroizer.modifier):
(Ext1OpType):
(ExtTableOpType): Deleted.
* wasm/wasm.json:

Canonical link: https://commits.webkit.org/234166@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272933 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-16 23:28:32 +00:00
Michael Saboff ba70933209 [ARM64e] Harden Mach exception handling
https://bugs.webkit.org/show_bug.cgi?id=221841

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Split wasm_throw_from_fault_handler_trampoline into two trampolines to eliminate the
need to pass a register argument to signify if we are using FastTLS.  With this change
we don't need to modify registers besides the PC when handling exceptions.
Added sanity checks to make sure handlers are being called for the exceptions they
were registered for.

* bytecode/BytecodeList.rb:
* llint/WebAssembly.asm:
* runtime/VMTraps.cpp:
* signal: Added.
* tools/SigillCrashAnalyzer.cpp:
(JSC::installCrashHandler):
* wasm/WasmFaultSignalHandler.cpp:
(JSC::Wasm::trapHandler):

Source/WTF:

For Darwin ARM64e platforms, we check to make sure that all thread state besides the PC hasn't
been modified by an exception handler.

* wtf/threads/Signals.cpp:
(WTF::hashThreadState):

Tools:

Updated test to check that the exception type matches the one we registered for.

* TestWebKitAPI/Tests/WTF/Signals.cpp:
(TEST):


Canonical link: https://commits.webkit.org/234059@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272823 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-13 00:32:01 +00:00
Mark Lam a615b67e91 We should not static_assert on an ENABLE() macro.
https://bugs.webkit.org/show_bug.cgi?id=221714
rdar://74197896

Reviewed by Yusuke Suzuki.

This is because the ENABLE() macro reduces to a macro expression
`(defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE)` which is not a C++
expression that a static_assert can evaluate.

* llint/LLIntData.cpp:
* llint/LLIntData.h:
(JSC::LLInt::getCodePtr):
(JSC::LLInt::getWide16CodePtr):
(JSC::LLInt::getWide32CodePtr):



Canonical link: https://commits.webkit.org/233936@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272685 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-10 22:00:54 +00:00
Caio Araujo Neponoceno de Lima 0cf83189d9 [ESNext] Implement private methods
https://bugs.webkit.org/show_bug.cgi?id=194434

Reviewed by Filip Pizlo.

JSTests:

* stress/private-brand-installed-after-super-call-from-arrow-function.js: Added.
* stress/private-brand-installed-after-super-call-from-eval.js: Added.
* stress/private-method-brand-check.js: Added.
* stress/private-method-change-attribute-from-branded-structure.js: Added.
* stress/private-method-change-prototype-from-branded-structure.js: Added.
* stress/private-method-check-private-brand-ic.js: Added.
* stress/private-method-check-structure-miss.js: Added.
* stress/private-method-comparison.js: Added.
* stress/private-method-delete-property-from-branded-structure.js: Added.
* stress/private-method-extends-brand-check.js: Added.
* stress/private-method-get-and-call.js: Added.
* stress/private-method-invalid-multiple-brand-installation.js: Added.
* stress/private-method-invalidate-compiled-with-constant-symbol.js: Added.
* stress/private-method-nested-class.js: Added.
* stress/private-method-on-sealed-objects.js: Added.
* stress/private-method-on-uncacheable-dictionary.js: Added.
* stress/private-method-polymorphic-with-constant-symbol.js: Added.
* stress/private-method-set-brand-should-have-write-barrier.js: Added.
* stress/private-method-untyped-use.js: Added.
* stress/private-method-with-uncacheable-dictionary-transition.js: Added.
* stress/private-methods-inline-cache.js: Added.
* stress/private-methods-megamorphic-ic.js: Added.
* stress/private-methods-on-proxy.js: Added.
* stress/private-methods-poly-ic-multiple-classes.js: Added.
* stress/private-methods-poly-ic-single-class.js: Added.
* stress/private-names-available-on-direct-eval.js: Added.
* test262/config.yaml:

Source/JavaScriptCore:

This patch is adding support to private methods following the
specification on https://tc39.es/proposal-private-methods/.
This is introducing a new way to declare private methods on
class syntax. Private methods are only accessible within
classes they were declared, and only can be called from
objects that are instance of these classes.
To guarantee such rules, the proposal presents the concept of
Brand Check. During class evaluation, if a private method is present,
a `brand` is installed in this class. Every instance of such class
then gets this brand installed during `[[Construct]]` operation. It
means that an object can have multiple brands (e.g when there is also
private methods declared on super class). Before accessing a private
method, there is a check to validate if the target of the call has the
brand of callee method.
The brand check mechanism is implemented using a `@privateBrand`
stored on class scope. Here is a representation of how this mechanism
works:

```
class C {
    #m() { return 3; }
    method() { return this.#m(); }
}

let c = new C();
console.log(c.method()); // prints 3
```

Generated bytecode for the following representation:
```
{ // class lexical scope
    const @privateBrand = @createPrivateSymbol();
    const #m = function () { return 3; }
    C.prototype.method = function() {
        @check_private_brand(this, @privateBrand);
        return #m.call(this);
    }
    C = function() {
        @set_private_brand(this, @privateBrand);
    }
}

let c = new C();
console.log(c.method()); // prints 3
```

# Resolving correct brand to check

In the case of shadowing or nested scope, we need to emit brand
checks to the right private brand. See code below:

```
class C {
    #m() { return 3; }
    method() { return this.#m();}

    A = class {
        #m2() { return 3; }
        foo(o) { return o.#m(); }
    }
}
```

The call of "#m" in `foo` refers to "C::#m". In such case, we need to
check C's private brand, instead of A's private brand.
To perform the proper check, we first resolve scope of "#m" and then
check the private brand of this scope (the scope where the private
method and brand are stored is the same).
So the bytecode to lookup the right brand is:

```
mov loc9, arg1
resolve_scope loc10, "#m"
get_from_scope loc11, loc10, "@privateBrand"
check_private_brand loc9, loc11
get_from_scope loc11, loc10, "#m"
// setup call frame
call loc11, ...
// ...
```

# Brand check mechanism

We are introducing in this patch 2 new bytecodes to allow brand check
of objects: `op_set_brand` and `op_check_brand`.
`op_set_brand` sets a new brand in an object, so we can perform the brand
check later when accessing private methods. This operations throws when
trying to add the same brand twice in an Object.
`op_check_brand` checks if the given object contains the brand we are
looking for. It traverses the brand chain to verify if the brand is
present, and throws `TypeError` otherwise.

We are also introducing a subclass for Structure called BrandedStructure.
It is used to store brands and to allow brand check mechanism. BrandedStructure
stores a brand and a parent pointer to another BrandedStructure that allow
us traverse the brand chain. With `BrandedStructure`, we can then
infer that a given object has the brand we are looking for just
checking its structureId. This is a very good optimization, since we can
reduce most of brand checks to structure checks.

We created a new kind of transition called `SetBrand` that happens when
`op_set_brand` is executed. This allow us to cache such kind of
trasitions on trasition table using the key `<brand->uid, 0,
TransitionKind::SetBrand>`. During this transition, we take previous
structure and apply one of the following rules:

    1. If it's a BrandedStructure, we then set it to `m_parentBrand`,
    to allow proper brand chain check.

    2. If it's not a BrandedStructure, we set `m_parentBrand` to `nullptr`,
    meaning that this is the first brand being added to the object
    with this structure.

For now, we are using the flag `isBrandedStructure` to identify that a
given Structure is a BrandedStructure. This is done to avoid changes
on places where we are checking for `vm.structureStructure()`.
However, if we ever need space on Structure, this flag is a good
candidate to be deleted and we can move to a solution that uses
`vm.brandedStructureStructure()`;

 # JIT Support

This patch also includes initial JIT support for `set_private_brand`
and `check_private_brand`. On Baseline JIT, we are using
`JITPravateBrandAccessGenerator` to support IC for both operands.
On `DFGByteCodeParser` we are trying to inline brand access whenever
possible, and fallbacking to `SetPrivateBrand` and
`CheckPrivateBrand` otherwise. Those nodes are not being optimized at
their full potential, but the code generated by them is also relying on
`JITPrivateBrandAccessGenerator` to have IC support for both DFG and
FTL. During DFG parsing, we try to reduce those access  to `CheckIsConstant`
and `CheckStructure` (with `PutStructure` for `set_private_brand` cases)
based on available profiled data. This is meant to make brand checks
almost free on DFG/FTL tiers when we have a single evaluation of a
class, since the `CheckIsConstant` can be eliminated by the constant-folded
scope load, and the `CheckStructure` is very likely to be redundant
to any other `CheckStructure` that can be performed on receiver
when we have a finite structure set.
For instance, when we have a brand check on a path-of-no-return to
a `GetByOffset` sequence on the same receiver, the `CheckStructure`
for the brand check will enable CSE of the `CheckStructure` that
would happen for that `GetByOffset`. Such design is possible because brand
checks supports polymorphic access very similr to what we have for
`GetByOffset` sequences.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutable):
* builtins/BuiltinExecutables.h:

We are adding a new parameter `PrivateBrandRequirement` to propagate
when a default constructor needs to emit code to setup private brand
on instances.

* builtins/BuiltinNames.h:

Adding `@privateBrand` that  we use to store private brand on
class's scope.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::createCheckPrivateBrand):
(JSC::AccessCase::createSetPrivateBrand):
(JSC::AccessCase::requiresIdentifierNameMatch const):
(JSC::AccessCase::requiresInt32PropertyCheck const):
(JSC::AccessCase::needsScratchFPR const):
(JSC::AccessCase::forEachDependentCell const):
(JSC::AccessCase::doesCalls const):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
(JSC::AccessCase::structure const):
(JSC::AccessCase::newStructure const):
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/CheckPrivateBrandStatus.cpp: Added.
(JSC::CheckPrivateBrandStatus::appendVariant):
(JSC::CheckPrivateBrandStatus::computeForBaseline):
(JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
(JSC::CheckPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::CheckPrivateBrandStatus::computeFor):
(JSC::CheckPrivateBrandStatus::slowVersion const):
(JSC::CheckPrivateBrandStatus::merge):
(JSC::CheckPrivateBrandStatus::filter):
(JSC::CheckPrivateBrandStatus::singleIdentifier const):
(JSC::CheckPrivateBrandStatus::visitAggregate):
(JSC::CheckPrivateBrandStatus::markIfCheap):
(JSC::CheckPrivateBrandStatus::finalize):
(JSC::CheckPrivateBrandStatus::dump const):
* bytecode/CheckPrivateBrandStatus.h: Added.
* bytecode/CheckPrivateBrandVariant.cpp: Added.
(JSC::CheckPrivateBrandVariant::CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::~CheckPrivateBrandVariant):
(JSC::CheckPrivateBrandVariant::attemptToMerge):
(JSC::CheckPrivateBrandVariant::markIfCheap):
(JSC::CheckPrivateBrandVariant::finalize):
(JSC::CheckPrivateBrandVariant::visitAggregate):
(JSC::CheckPrivateBrandVariant::dump const):
(JSC::CheckPrivateBrandVariant::dumpInContext const):
* bytecode/CheckPrivateBrandVariant.h: Added.
(JSC::CheckPrivateBrandVariant::structureSet const):
(JSC::CheckPrivateBrandVariant::structureSet):
(JSC::CheckPrivateBrandVariant::identifier const):
(JSC::CheckPrivateBrandVariant::overlaps):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::privateBrandRequirement const):
* bytecode/PolymorphicAccess.cpp:
(JSC::PolymorphicAccess::regenerate):
(WTF::printInternal):
* bytecode/RecordedStatuses.cpp:
(JSC::RecordedStatuses::operator=):
(JSC::RecordedStatuses::addCheckPrivateBrandStatus):
(JSC::RecordedStatuses::addSetPrivateBrandStatus):
(JSC::RecordedStatuses::visitAggregate):
(JSC::RecordedStatuses::markIfCheap):
* bytecode/RecordedStatuses.h:
(JSC::RecordedStatuses::forEachVector):
* bytecode/SetPrivateBrandStatus.cpp: Added.
(JSC::SetPrivateBrandStatus::appendVariant):
(JSC::SetPrivateBrandStatus::computeForBaseline):
(JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
(JSC::SetPrivateBrandStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::SetPrivateBrandStatus::computeFor):
(JSC::SetPrivateBrandStatus::slowVersion const):
(JSC::SetPrivateBrandStatus::merge):
(JSC::SetPrivateBrandStatus::filter):
(JSC::SetPrivateBrandStatus::singleIdentifier const):
(JSC::SetPrivateBrandStatus::visitAggregate):
(JSC::SetPrivateBrandStatus::markIfCheap):
(JSC::SetPrivateBrandStatus::finalize):
(JSC::SetPrivateBrandStatus::dump const):
* bytecode/SetPrivateBrandStatus.h: Added.
* bytecode/SetPrivateBrandVariant.cpp: Added.
(JSC::SetPrivateBrandVariant::SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::~SetPrivateBrandVariant):
(JSC::SetPrivateBrandVariant::attemptToMerge):
(JSC::SetPrivateBrandVariant::markIfCheap):
(JSC::SetPrivateBrandVariant::finalize):
(JSC::SetPrivateBrandVariant::visitAggregate):
(JSC::SetPrivateBrandVariant::dump const):
(JSC::SetPrivateBrandVariant::dumpInContext const):
* bytecode/SetPrivateBrandVariant.h: Added.
(JSC::SetPrivateBrandVariant::oldStructure const):
(JSC::SetPrivateBrandVariant::newStructure const):
(JSC::SetPrivateBrandVariant::identifier const):
(JSC::SetPrivateBrandVariant::overlaps):
* bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::reset):
* bytecode/StructureStubInfo.h:
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::privateBrandRequirement const):
* bytecode/UnlinkedCodeBlockGenerator.h:
(JSC::UnlinkedCodeBlockGenerator::privateBrandRequirement const):
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):

We changed BytecodeGenerator for FunctionNode and EvalNode to
propagate parentScope PrivateNameEnvironment. These environments stores
private name entries that are visible into the scope of the
function/eval.
This is required to identify the kind of access a private name is
referring to, since it can be a private field or a private method.

(JSC::BytecodeGenerator::instantiateLexicalVariables):
(JSC::BytecodeGenerator::emitGetPrivateName):
(JSC::BytecodeGenerator::emitCreatePrivateBrand):

The process to create a private brand is as follows:
    1. Create a PrivateSymbol using `@createPrivateSymbol`.
    2. Store this symbol into a given scope (i.e class lexical scope)
       on `@privateBrand` variable.

(JSC::BytecodeGenerator::emitInstallPrivateBrand):
(JSC::BytecodeGenerator::emitGetPrivateBrand):

We added `m_privateNamesStack` to BytecodeGenerator to represent the
scope chain of available private names while generating bytecode.

(JSC::BytecodeGenerator::emitCheckPrivateBrand):
(JSC::BytecodeGenerator::isPrivateMethod):
(JSC::BytecodeGenerator::pushPrivateAccessNames):
(JSC::BytecodeGenerator::popPrivateAccessNames):
(JSC::BytecodeGenerator::getAvailablePrivateAccessNames):
(JSC::BytecodeGenerator::emitNewDefaultConstructor):
(JSC::BytecodeGenerator::emitNewClassFieldInitializerFunction):
(JSC::BytecodeGenerator::emitDirectGetByVal): Deleted.
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::privateBrandRequirement const):
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::makeFunction):

This change is required to properly propagate PrivateBrandRequirement
to arrow functions that can potentially call `super()`.

* bytecompiler/NodesCodegen.cpp:
(JSC::PropertyListNode::emitDeclarePrivateFieldNames):
(JSC::PropertyListNode::emitBytecode):
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BaseDotNode::emitGetPropertyValue):

Adding support to properly access private method. Since we store
private methods on class lexical scope, we need a different set of
instructions to access a private method.

(JSC::BaseDotNode::emitPutProperty):

In the case of we trying to write in a private method, we need to
throw a TypeError according to specification
(https://tc39.es/proposal-private-methods/#sec-privatefieldset).

(JSC::FunctionCallValueNode::emitBytecode):
(JSC::PostfixNode::emitDot):
(JSC::PrefixNode::emitDot):
(JSC::ClassExprNode::emitBytecode):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::evaluateWithScopeExtension):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
(JSC::DFG::AbstractInterpreter<AbstractStateType>::filterICStatus):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.h:
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::addPrivateBrandAccess):
* dfg/DFGMayExit.cpp:
* dfg/DFGNode.h:
(JSC::DFG::Node::hasCheckPrivateBrandStatus):
(JSC::DFG::Node::checkPrivateBrandStatus):
(JSC::DFG::Node::hasSetPrivateBrandStatus):
(JSC::DFG::Node::setPrivateBrandStatus):
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileCheckPrivateBrand):
(JSC::DFG::SpeculativeJIT::compileSetPrivateBrand):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compilePrivateBrandAccess):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckPrivateBrand):
(JSC::FTL::DFG::LowerDFGToB3::compileSetPrivateBrand):
* interpreter/Interpreter.cpp:
(JSC::eval):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::link):
* jit/JIT.h:
* jit/JITInlineCacheGenerator.cpp:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::generateFastPath):
(JSC::JITPrivateBrandAccessGenerator::finalize):
* jit/JITInlineCacheGenerator.h:
(JSC::JITPrivateBrandAccessGenerator::JITPrivateBrandAccessGenerator):
(JSC::JITPrivateBrandAccessGenerator::slowPathJump const):
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
(JSC::getPrivateName):
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_set_private_brand):
(JSC::JIT::emitSlow_op_set_private_brand):
(JSC::JIT::emit_op_check_private_brand):
(JSC::JIT::emitSlow_op_check_private_brand):
* jit/Repatch.cpp:
(JSC::tryCacheCheckPrivateBrand):
(JSC::repatchCheckPrivateBrand):
(JSC::tryCacheSetPrivateBrand):
(JSC::repatchSetPrivateBrand):
(JSC::resetCheckPrivateBrand):
(JSC::resetSetPrivateBrand):
* jit/Repatch.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* parser/Nodes.cpp:
(JSC::FunctionMetadataNode::FunctionMetadataNode):
* parser/Nodes.h:
(JSC::BaseDotNode::isPrivateMember const):
(JSC::BaseDotNode::isPrivateField const): Deleted.
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseMemberExpression):
* parser/Parser.h:
(JSC::Scope::declarePrivateMethod):
(JSC::Scope::declarePrivateField):
(JSC::Parser<LexerType>::parse):
(JSC::parse):
(JSC::Scope::declarePrivateName): Deleted.
* parser/ParserModes.h:
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createDotAccess):
* parser/VariableEnvironment.cpp:
(JSC::VariableEnvironment::declarePrivateMethod):
* parser/VariableEnvironment.h:
(JSC::VariableEnvironmentEntry::isPrivateField const):
(JSC::VariableEnvironmentEntry::isPrivateMethod const):
(JSC::VariableEnvironmentEntry::setIsPrivateField):
(JSC::VariableEnvironmentEntry::setIsPrivateMethod):
(JSC::PrivateNameEntry::isMethod const):
(JSC::PrivateNameEntry::isPrivateMethodOrAcessor const):
(JSC::VariableEnvironment::addPrivateName):
(JSC::VariableEnvironment::declarePrivateField):
(JSC::VariableEnvironment::declarePrivateMethod):
(JSC::VariableEnvironment::privateNameEnvironment const):
(JSC::VariableEnvironment::hasPrivateMethodOrAccessor const):
(JSC::VariableEnvironment::addPrivateNamesFrom):
(JSC::VariableEnvironmentEntry::isPrivateName const): Deleted.
(JSC::VariableEnvironmentEntry::setIsPrivateName): Deleted.
(JSC::VariableEnvironment::declarePrivateName): Deleted.
* runtime/CachedTypes.cpp:
(JSC::CachedCodeBlockRareData::encode):
(JSC::CachedCodeBlockRareData::decode const):
(JSC::CachedFunctionExecutableRareData::encode):
(JSC::CachedFunctionExecutableRareData::decode const):
(JSC::CachedFunctionExecutable::privateBrandRequirement const):
(JSC::CachedCodeBlock::derivedContextType const):
(JSC::CachedFunctionExecutable::encode):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::CachedCodeBlock::needsClassFieldInitializer const): Deleted.
* runtime/CodeCache.cpp:
(JSC::generateUnlinkedCodeBlockImpl):
(JSC::generateUnlinkedCodeBlock):
(JSC::generateUnlinkedCodeBlockForDirectEval):
(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):
* runtime/CodeCache.h:
* runtime/DirectEvalExecutable.cpp:
(JSC::DirectEvalExecutable::create):
(JSC::DirectEvalExecutable::DirectEvalExecutable):
* runtime/DirectEvalExecutable.h:
* runtime/EvalExecutable.cpp:
(JSC::EvalExecutable::EvalExecutable):
* runtime/EvalExecutable.h:
(JSC::EvalExecutable::executableInfo const):
(JSC::EvalExecutable::privateBrandRequirement const):
* runtime/ExceptionHelpers.cpp:
(JSC::createInvalidPrivateNameError):
* runtime/IndirectEvalExecutable.cpp:
(JSC::IndirectEvalExecutable::IndirectEvalExecutable):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::checkPrivateBrand):
(JSC::JSObject::setPrivateBrand):
* runtime/JSScope.cpp:
(JSC::JSScope::collectClosureVariablesUnderTDZ):
* runtime/JSScope.h:
* runtime/ModuleProgramExecutable.h:
* runtime/Options.cpp:
(JSC::Options::recomputeDependentOptions):
* runtime/OptionsList.h:
* runtime/ProgramExecutable.h:
* runtime/Structure.cpp:
(JSC::Structure::materializePropertyTable):
(JSC::BrandedStructure::BrandedStructure):
(JSC::BrandedStructure::create):
(JSC::BrandedStructure::checkBrand):
(JSC::Structure::setBrandTransitionFromExistingStructureImpl):
(JSC::Structure::setBrandTransitionFromExistingStructureConcurrently):
(JSC::Structure::setBrandTransition):
* runtime/Structure.h:
(JSC::Structure::finishCreation):
* runtime/StructureInlines.h:
(JSC::Structure::create):
(JSC::Structure::forEachPropertyConcurrently):
* runtime/StructureTransitionTable.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::cloneScopePart):
* runtime/SymbolTable.h:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:


Canonical link: https://commits.webkit.org/233852@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-09 16:30:24 +00:00
Yusuke Suzuki f2d5c65ae2 [AppleWin 32bit][LLInt] LLIntData.h(104) : warning C4172: returning address of local variable or temporary: id
https://bugs.webkit.org/show_bug.cgi?id=220714

Reviewed by Mark Lam.

This patch fixes LLInt build when ENABLE(COMPUTED_GOTO_OPCODES) is false.

* llint/LLIntData.h:
(JSC::LLInt::getOpcode):
(JSC::LLInt::getOpcodeWide16):
(JSC::LLInt::getOpcodeWide32):
(JSC::LLInt::getOpcodeAddress):
(JSC::LLInt::getOpcodeWide16Address):
(JSC::LLInt::getOpcodeWide32Address):
(JSC::LLInt::getCodePtr):
(JSC::LLInt::getWide16CodePtr):
(JSC::LLInt::getWide32CodePtr):


Canonical link: https://commits.webkit.org/233658@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272330 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-03 18:40:55 +00:00
Yusuke Suzuki 5a13e56ddd [JSC] Implement BigInt64Array and BigUint64Array
https://bugs.webkit.org/show_bug.cgi?id=190800

Reviewed by Ross Kirsling.

JSTests:

Through this patch, we encounter two test262 failures and found that these tests have issues.

* stress/bigint-typed-array-array-modes-profile.js: Added.
(foo):
* stress/bigint-typed-array-byte-offset.js: Added.
(foo):
* stress/bigint-typed-array-canonical-numeric-index-string.js: Added.
(makeTest.assert):
(makeTest):
(const.testInvalidIndices.makeTest.set assert):
(const.testInvalidIndices.makeTest):
(const.testValidIndices.makeTest.set assert):
(const.testValidIndices.makeTest):
* stress/bigint-typed-array-constructor-undefined.js: Added.
* stress/bigint-typed-array-get-by-val-profiling.js: Added.
(testArray.testCode):
(testArray):
* stress/bigint-typed-array-lastIndexOf-exception-check.js: Added.
* stress/bigint-typed-array-put-by-val-profiling.js: Added.
(testArray.testCode):
(testArray):
* stress/bigint-typedarray-getownproperty.js: Added.
(assert):
(foo):
* stress/bigint64array-bytelength.js: Added.
(test1):
(test2):
(shouldBe):
* stress/bigint64array-get-by-val.js: Added.
(shouldBe):
(test1):
(test2):
* stress/bigint64array-put-by-val.js: Added.
(shouldBe):
(test11):
(test12):
(test21):
(test22):
* test262/config.yaml:
* test262/expectations.yaml:

Source/JavaScriptCore:

This patch implements BigInt64Array and BigUint64Array.

    1. In this patch, we do not support BigInt64Array/BigUint64Array + Atomics yet.
    2. We make canGetIndexQuickly false for BigInt64Array and BigUint64Array. And we
       use generic path for getting values from BigInt64Array and BigUint64Array. We
       will optimize it in [1] and [2]. But possibly, this does not have super large
       impact on performance since getting value from BigInt64Array and BigUint64Array
       are already costly since we always need to allocate BigInt for results.
    3. DFG / FTL GetByVal etc. are using Array::Generic for BigInt64Array and BigUint64Array.
    4. But GetArrayLength, CheckArray, byteLength getter etc. are using Array::BigInt64Array / Array::BigUint64Array
       for optimization.
    5. Extend ArrayProfile's ArrayMode for BigInt64Array and BigUint64Array so that ArrayProfile
       can record BigInt64Array and BigUint64Array information.
    6. Implement DataView#{setBigInt64,setBigUint64,getBigInt64,getBigUint64}.
    7. Extend JSC APIs to support BigInt64Array and BigUint64Array.

[1]: https://bugs.webkit.org/show_bug.cgi?id=221181
[2]: https://bugs.webkit.org/show_bug.cgi?id=221183

* API/JSTypedArray.cpp:
(toJSTypedArrayType):
(toTypedArrayType):
(createTypedArray):
* API/JSValueRef.h:
* API/tests/TypedArrayCTest.cpp:
(forEachTypedArrayType):
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/BuiltinNames.h:
* builtins/TypedArrayPrototype.js:
(fill):
(map):
(filter):
* bytecode/ArrayProfile.cpp:
(JSC::dumpArrayModes):
* bytecode/ArrayProfile.h:
* bytecode/ByValInfo.h:
(JSC::jitArrayModeForClassInfo):
(JSC::jitArrayModePermitsPut):
(JSC::typedArrayTypeForJITArrayMode):
* bytecode/LinkTimeConstant.h:
* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
(JSC::speculationToAbbreviatedString):
(JSC::speculationFromTypedArrayType):
(JSC::typedArrayTypeFromSpeculation):
(JSC::speculationFromString):
* bytecode/SpeculatedType.h:
(JSC::isBigInt64ArraySpeculation):
(JSC::isBigUint64ArraySpeculation):
(JSC::isDirectArgumentsSpeculation):
(JSC::isScopedArgumentsSpeculation):
(JSC::isActionableIntMutableArraySpeculation): Deleted.
(JSC::isActionableFloatMutableArraySpeculation): Deleted.
(JSC::isActionableTypedMutableArraySpeculation): Deleted.
(JSC::isActionableMutableArraySpeculation): Deleted.
(JSC::isActionableArraySpeculation): Deleted.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::fromObserved):
(JSC::DFG::ArrayMode::refine const):
(JSC::DFG::ArrayMode::alreadyChecked const):
(JSC::DFG::arrayTypeToString):
(JSC::DFG::toTypedArrayType):
(JSC::DFG::toArrayType):
(JSC::DFG::permitsBoundsCheckLowering):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::supportsSelfLength const):
(JSC::DFG::ArrayMode::arrayModesThatPassFiltering const):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
(JSC::DFG::operationNewTypedArrayWithSizeForType):
(JSC::DFG::operationNewTypedArrayWithOneArgumentForType):
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileHasIndexedProperty):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
(JSC::FTL::DFG::LowerDFGToB3::compilePutByVal):
* inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::subtype):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::privateCompilePutByVal):
* jit/Repatch.cpp:
(JSC::tryCacheArrayGetByVal):
* llint/LowLevelInterpreter.asm:
* runtime/AtomicsObject.cpp:
* runtime/AtomicsObject.h:
* runtime/BigInt64Array.h: Copied from Source/JavaScriptCore/runtime/JSTypedArrayConstructors.cpp.
* runtime/BigUint64Array.h: Copied from Source/JavaScriptCore/runtime/JSTypedArrayConstructors.cpp.
* runtime/JSArrayBufferView.cpp:
(JSC::elementSize):
(JSC::validateTypedArray):
* runtime/JSArrayBufferView.h:
* runtime/JSBigInt.h:
* runtime/JSCell.h:
* runtime/JSDataView.h:
* runtime/JSDataViewPrototype.cpp:
(JSC::getData):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGenericTypedArrayViewConstructor.h:
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::setWithSpecificType):
(JSC::JSGenericTypedArrayView<Adaptor>::set):
(JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlotByIndex):
* runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::genericTypedArrayViewProtoFuncJoin):
(JSC::genericTypedArrayViewProtoFuncSlice):
(JSC::genericTypedArrayViewPrivateFuncSubarrayCreate):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/JSGlobalObjectFunctions.h:
* runtime/JSType.cpp:
(WTF::printInternal):
* runtime/JSType.h:
* runtime/JSTypedArrayConstructors.cpp:
* runtime/JSTypedArrayConstructors.h:
* runtime/JSTypedArrayPrototypes.cpp:
* runtime/JSTypedArrayPrototypes.h:
* runtime/JSTypedArrayViewPrototype.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/JSTypedArrayViewPrototype.h:
* runtime/JSTypedArrays.cpp:
* runtime/JSTypedArrays.h:
* runtime/ToNativeFromValue.h:
(JSC::toNativeFromValue):
(JSC::toNativeFromValueWithoutCoercion):
* runtime/TypedArrayAdaptors.h:
(JSC::IntegralTypedArrayAdaptor::toJSValue):
(JSC::FloatTypedArrayAdaptor::toJSValue):
(JSC::BigIntTypedArrayAdaptor::toJSValue):
(JSC::BigIntTypedArrayAdaptor::toNativeFromInt32):
(JSC::BigIntTypedArrayAdaptor::toNativeFromUint32):
(JSC::BigIntTypedArrayAdaptor::toNativeFromDouble):
(JSC::BigIntTypedArrayAdaptor::convertTo):
(JSC::Uint8ClampedAdaptor::toJSValue):
(JSC::IntegralTypedArrayAdaptor::toDouble): Deleted.
(JSC::FloatTypedArrayAdaptor::toDouble): Deleted.
(JSC::Uint8ClampedAdaptor::toDouble): Deleted.
* runtime/TypedArrayType.cpp:
(JSC::constructorClassInfoForType):
(WTF::printInternal):
* runtime/TypedArrayType.h:
(JSC::isBigIntTypedView):
(JSC::logElementSize):
(JSC::isBigInt):
(JSC::isSigned):
(JSC::contentType):
* runtime/TypedArrays.h:
* runtime/VM.cpp:
* runtime/VM.h:

Canonical link: https://commits.webkit.org/233548@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@272170 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-02-01 20:56:41 +00:00
Yusuke Suzuki 9d781c5232 [JSC] Avoid using DirectCall when executable is wasm function
https://bugs.webkit.org/show_bug.cgi?id=221055

Reviewed by Keith Miller.

This is a partial patch from https://bugs.webkit.org/show_bug.cgi?id=220339, which is reverted because of Facebook crash.
For now, we just avoid using DirectCall to wasm functions so that normal Call will be used, and it is efficient. This
patch avoids JetStream2 regression.

* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* jit/JITOperations.cpp:
(JSC::virtualForWithFunction):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* runtime/Intrinsic.cpp:
(JSC::intrinsicName):
* runtime/Intrinsic.h:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::create):


Canonical link: https://commits.webkit.org/233420@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271987 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-27 22:11:11 +00:00
Commit Queue 14c22be82e Unreviewed, reverting r271186.
https://bugs.webkit.org/show_bug.cgi?id=221051

Breaks Facebook on arm64e devices

Reverted changeset:

"[JSC] DFG/FTL DirectCall need to respect Wasm IC"
https://bugs.webkit.org/show_bug.cgi?id=220339
https://trac.webkit.org/changeset/271186

Canonical link: https://commits.webkit.org/233411@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271967 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-27 19:19:57 +00:00
Xan Lopez 0f083bbbfa [JSC] Allow to build WebAssembly without B3
https://bugs.webkit.org/show_bug.cgi?id=220365

Patch by Xan Lopez <xan@igalia.com> on 2021-01-23
Reviewed by Yusuke Suzuki.

.:

Make the WebAssembly feature depend on Baseline JIT, not B3
JIT. Also add a WEBASSEMBLY_B3JIT feature to enable or disable the
B3 tier in WebAssembly.

* Source/cmake/WebKitFeatures.cmake: disable on 32bit.

Source/JavaScriptCore:

Make all the B3 related code in WebAssembly a compile-time
option. When disabled WebAssembly will only use its LLInt tier.

* llint/LLIntOfflineAsmConfig.h: define WEBASSEMBLY_B3JIT for the
offline assembler.
* llint/WebAssembly.asm: guard B3 code inside WEBASSEMBLY_B3JTI ifdefs.
* wasm/WasmAirIRGenerator.cpp: ditto.
* wasm/WasmAirIRGenerator.h: ditto.
* wasm/WasmB3IRGenerator.cpp: ditto.
* wasm/WasmB3IRGenerator.h: ditto.
* wasm/WasmBBQPlan.cpp: ditto.
* wasm/WasmBBQPlan.h: ditto.
* wasm/WasmCallee.h: ditto.
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock): ditto.
* wasm/WasmCodeBlock.h:
(JSC::Wasm::CodeBlock::wasmEntrypointCalleeFromFunctionIndexSpace): ditto.
* wasm/WasmLLIntGenerator.h: ditto.
* wasm/WasmLLIntPlan.cpp: ditto.
* wasm/WasmOMGForOSREntryPlan.cpp: ditto.
* wasm/WasmOMGForOSREntryPlan.h: ditto.
* wasm/WasmOMGPlan.cpp: ditto.
* wasm/WasmOMGPlan.h: ditto.
* wasm/WasmOSREntryData.h: ditto.
* wasm/WasmOperations.cpp: ditto.
* wasm/WasmOperations.h: ditto.
* wasm/WasmPlan.cpp: ditto.
* wasm/WasmPlan.h: ditto.
* wasm/WasmSlowPaths.cpp: ditto.
* wasm/WasmSlowPaths.h: ditto.
* wasm/WasmThunks.cpp: ditto.
* wasm/WasmThunks.h: ditto.
* wasm/WasmTierUpCount.cpp: ditto.
* wasm/WasmTierUpCount.h: ditto.
* wasm/generateWasmOpsHeader.py: ditto.

Source/WTF:

* wtf/PlatformEnable.h: Disable WebAssembly on 32bit platforms,
enable WebAssembly B3JIT on PLATFORM(COCOA).

Tools:

* Scripts/webkitperl/FeatureList.pm: add WebAssembly B3 JIT option.

Canonical link: https://commits.webkit.org/233281@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271775 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-23 12:32:22 +00:00
Mark Lam 4a33d44bf6 [AppleWin 32bit] LLInt C Loop: LowLevelInterpreter.cpp(90,7): error C2653: 'WebConfig': is not a class or namespace name
https://bugs.webkit.org/show_bug.cgi?id=220405

Reviewed by Fujii Hironori.

Add a missing #if ENABLE(UNIFIED_AND_FREEZABLE_CONFIG_RECORD).

* llint/LowLevelInterpreter.cpp:


Canonical link: https://commits.webkit.org/233122@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271586 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-18 21:49:43 +00:00
Yusuke Suzuki 1dbf2021cf [JSC] JITCage's Gate mechanism is used in ARM64E even if JITCage is disable
https://bugs.webkit.org/show_bug.cgi?id=220500

Reviewed by Mark Lam.

We should ensure that Gate mechanism just works even if ENABLE(JIT_CAGE) is OFF in ARM64E since
in LLInt we are always using Gate even if ENABLE(JIT_CAGE) is OFF. It makes LLInt code
significantly simpler: we do not want to have multiple implementations for ARM64E for ENABLE(JIT_CAGE) ON/OFF
in LLInt if it is not necessary in terms of performance. And it didn't cause performance regression.
So for simplicity, we are always using Gate in LLInt.

However, when disabling ENABLE(JIT_CAGE), we accidentally disabled Gate mechanism too in LLInt.
It makes ARM64E broken if ENABLE(JIT_CAGE) is OFF. This patch makes Gate work even if ENABLE(JIT_CAGE) is OFF,
and this is the expected design.

* llint/LLIntData.cpp:
(JSC::LLInt::initialize):
* llint/LLIntEntrypoint.cpp:
(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
(JSC::LLInt::setModuleProgramEntrypoint):
* llint/LLIntThunks.cpp:
* llint/LLIntThunks.h:

Canonical link: https://commits.webkit.org/232917@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271352 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-11 05:40:00 +00:00
Yusuke Suzuki a125d08347 [JSC] DFG/FTL DirectCall need to respect Wasm IC
https://bugs.webkit.org/show_bug.cgi?id=220339

Reviewed by Saam Barati.

We found that Wasm IC for fast calls are not used in several places.

    1. LLInt calls
    2. DFG/FTL DirectCall
    3. Virtual calls

We noticed this because of r271112. r271112 made wasm function loading from exports constant-folded in DFG/FTL.
And it emits DirectCall instead of Call in DFG/FTL. Then, we missed Wasm IC and get large performance regression
in JetStream2 richard-wasm.

In this patch, we use Wasm IC as much as possible. The key thing of this wasm IC is that it relies on callee.
So, if the place is just checking Executable, then we should not go to that IC. Fortunately, the above three checks
callee before using code pointer obtained for Wasm IC.

    1. LLInt call fast path first checks callee.
    2. DFG/FTL DirectCall requires callee is constant for wasm functions.
    3. Virtual calls are not storing generated codePtr.

* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.cpp:
(JSC::virtualForWithFunction):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):

Canonical link: https://commits.webkit.org/232782@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271186 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-06 03:03:43 +00:00
Alexey Shvayka 9a400c097f Improve error message for uninitialized |this| in derived constructor
https://bugs.webkit.org/show_bug.cgi?id=220221

Reviewed by Yusuke Suzuki.

JSTests:

* stress/async-arrow-functions-lexical-binding-in-class.js:
* stress/async-arrow-functions-lexical-super-binding.js:
* stress/class-derived-from-null.js:
* stress/generator-eval-this.js:
* stress/super-property-access-tdz.js:

LayoutTests/imported/w3c:

* web-platform-tests/custom-elements/parser/parser-fallsback-to-unknown-element-expected.txt:

Source/JavaScriptCore:

Since class constructors perform `return this;` by default, and derived
constructors require `super()` to be called before |this| access, regular
TDZ error message is quite confusing, given the following code:

    `new (class extends Object { constructor() { } });`

Considering that currently op_check_tdz is called on thisRegister() only
in derived constructors, this patch modifies its slow path to throw a
helpful error message that covers |this| access and non-object returns.

V8 and SpiderMonkey have similar error messages, mentioning `super()`.

slow_path_throw_tdz_error is merged into slow_path_check_tdz, which is
invoked from baseline JIT, so we can reliably acquire the bytecode and
avoid code duplication.

* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* runtime/CommonSlowPaths.h:

LayoutTests:

* js/arrowfunction-supercall-expected.txt:
* js/arrowfunction-superproperty-expected.txt:
* js/class-syntax-extends-expected.txt:
* js/class-syntax-super-expected.txt:
* js/script-tests/arrowfunction-supercall.js:
* js/script-tests/arrowfunction-superproperty.js:
* js/script-tests/class-syntax-super.js:


Canonical link: https://commits.webkit.org/232717@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@271120 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-01-02 19:27:42 +00:00
Yusuke Suzuki 1532b55b89 [CSSJIT] Do not use trampoline if JITCage is disabled
https://bugs.webkit.org/show_bug.cgi?id=220004

Reviewed by Tadeu Zagallo.

Source/JavaScriptCore:

* llint/LLIntData.cpp:
* llint/LowLevelInterpreter.asm:

Source/WebCore:

This trampoline is not necessary if JITCage is not enabled.

* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::compile):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateReturn):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker):
* cssjit/SelectorCompiler.h:
(WebCore::SelectorCompiler::ruleCollectorSimpleSelectorChecker):
(WebCore::SelectorCompiler::querySelectorSimpleSelectorChecker):
(WebCore::SelectorCompiler::ruleCollectorSelectorCheckerWithCheckingContext):
(WebCore::SelectorCompiler::querySelectorSelectorCheckerWithCheckingContext):


Canonical link: https://commits.webkit.org/232589@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270967 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-12-18 10:27:00 +00:00
Dmitry Bezhetskov bae0f9de6b [WASM-References] Add support for memory.copy, memory.init and data.drop
https://bugs.webkit.org/show_bug.cgi?id=219943

Patch by Dmitry Bezhetskov <dbezhetskov@igalia.com> on 2020-12-17
Reviewed by Yusuke Suzuki.

JSTests:

Added ref-types spec tests for memory.copy, memory.init and data.drop:
https://github.com/WebAssembly/reference-types/tree/master/test/core.
Renamed table_instructions_parse_unreachable test into just
parse_unreachable to prevent confusion.

* wasm.yaml:
* wasm/references-spec-tests/memory_copy.wast.js: Added.
* wasm/references-spec-tests/memory_init.wast.js: Added.
* wasm/references/memory_copy.js: Added.
(async test):
* wasm/references/memory_copy_shared.js: Added.
(async test):
* wasm/references/parse_unreachable.js: Renamed from JSTests/wasm/references/table_instructions_parse_unreachable.js.
(invalidMemoryCopyUnreachable):
(invalidMemoryInitUnreachable):
(invalidDataDropUnreachable):
* wasm/wasm.json:

Source/JavaScriptCore:

Add support for memory.copy [dstAddress, srcAddress, length] -> []
that copies one  memory segment to another memory segment.
The memory.copy calls C memcpy function to utilize all possible optimization for copy.
This instruction speedup copying data segments in wasm because without it we need to use a lot
load/store instructions with loops in wasm.

Add support for memory.init data_segment_index [dstAddress, srcAddress, length] -> []
that copies data from a passive data segment into a memory segment.
This instruction is the same as memory.copy but for read-only data segments.
It also utilize C memcpy under the hood.

Add support for data.drop data_segment_index [] -> []
that resize given data segment to zero.
Data.drop makes redundant data segment and prevents usage of it in the next.
BTW, it is just a hint for the host runtime so we don't have to change data segment.

Add support for Data count section.
This section just stores the number of data segments.
We need this to validate memory.init instruction's data index because
Code section comes before Data section.

These instructions are needed to support reference types proposal and bulk proposal.

* bytecode/BytecodeList.rb:
* llint/WebAssembly.asm:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addMemoryCopy):
(JSC::Wasm::AirIRGenerator::addMemoryInit):
(JSC::Wasm::AirIRGenerator::addDataDrop):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::addMemoryInit):
(JSC::Wasm::B3IRGenerator::addMemoryCopy):
(JSC::Wasm::B3IRGenerator::addDataDrop):
* wasm/WasmFormat.cpp:
(JSC::Wasm::Segment::create):
* wasm/WasmFormat.h:
(JSC::Wasm::Segment::isActive const):
(JSC::Wasm::Segment::isPassive const):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseDataSegmentIndex):
(JSC::Wasm::FunctionParser<Context>::parseMemoryCopyImmediates):
(JSC::Wasm::FunctionParser<Context>::parseMemoryInitImmediates):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmInstance.cpp:
(JSC::Wasm::Instance::Instance):
(JSC::Wasm::Instance::memoryInit):
(JSC::Wasm::Instance::dataDrop):
* wasm/WasmInstance.h:
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::addMemoryInit):
(JSC::Wasm::LLIntGenerator::addDataDrop):
(JSC::Wasm::LLIntGenerator::addMemoryCopy):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::copy):
(JSC::Wasm::Memory::init):
* wasm/WasmMemory.h:
* wasm/WasmModuleInformation.h:
(JSC::Wasm::ModuleInformation::dataSegmentsCount const):
* wasm/WasmOperations.cpp:
(JSC::Wasm::JSC_DEFINE_JIT_OPERATION):
* wasm/WasmOperations.h:
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseElement):
(JSC::Wasm::SectionParser::parseI32InitExpr):
(JSC::Wasm::SectionParser::parseI32InitExprForElementSection):
(JSC::Wasm::SectionParser::parseI32InitExprForDataSection):
(JSC::Wasm::SectionParser::parseDataSegmentCoreSpec):
(JSC::Wasm::SectionParser::parseDataSegmentReferenceTypesSpec):
(JSC::Wasm::SectionParser::parseGlobalType):
(JSC::Wasm::SectionParser::parseData):
(JSC::Wasm::SectionParser::parseDataCount):
* wasm/WasmSectionParser.h:
* wasm/WasmSections.h:
(JSC::Wasm::validateOrder):
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/wasm.json:

Canonical link: https://commits.webkit.org/232571@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270948 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-12-17 22:25:20 +00:00
Yusuke Suzuki c2c6c030be [JSC] Not using JITCage trampoline for non JITCage JSC
https://bugs.webkit.org/show_bug.cgi?id=219974

Reviewed by Tadeu Zagallo.

We avoid using JITCage trampoline in YarrJIT if JSC is not using JITCage.

* llint/LowLevelInterpreter.asm:
* yarr/YarrJIT.cpp:
* yarr/YarrJIT.h:
(JSC::Yarr::YarrCodeBlock::execute):

Canonical link: https://commits.webkit.org/232551@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270928 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-12-17 07:20:31 +00:00
Alexey Shvayka 55e381346d Non-enumerable property fails to shadow inherited enumerable property from for-in
https://bugs.webkit.org/show_bug.cgi?id=38970

Reviewed by Keith Miller.

JSTests:

* stress/arguments-bizarre-behaviour-disable-enumerability.js:
* stress/for-in-redefine-enumerable.js: Added.
* stress/for-in-shadow-non-enumerable.js: Added.
* test262/expectations.yaml: Mark 4 test cases as passing.

Source/JavaScriptCore:

While for/in was initially specified with notion of "shadowing", it wasn't clarified
until ES5 that [[Enumerable]] attributes are ignored when determining if a property
has already been processed. Recently, for/in spec was expanded [1] to pin down common
case enumeration as it's currently implemented by V8 and SpiderMonkey.

Since keeping track of DontEnum properties is a massive slowdown for uncached runs
(with any data structure used), this patch simply adds [[Enumerable]] check to
has_{indexed,structure,generic}_property bytecode ops and does renaming chores.

Common code is now shared between HasIndexedProperty (emitted for `0 in arr`) and
HasEnumerableIndexedProperty DFG nodes via passing different slow path ops rather
than having OpInfo with PropertySlot::InternalMethodType, which is a nice refactor.

While this change aligns common case for/in enumeration with the spec and other
engines, it also introduces a few observable discrepancies from V8 and SpiderMonkey,
which are permitted by the spec [2]:
a) properties that have been redefined as DontEnum within loop body are skipped,
   which matches the spec [3] and seems like expected behavior;
b) "shadowing" is broken if a DontEnum property of already visited object is
   added / deleted / redefined within loop body, which (pretty much) never happens.

This patch introduces a new invariant: all properties getOwn*PropertyNames() returns
in DontEnumPropertiesMode::Exclude should be reported as [[Enumerable]] by
getOwnPropertySlot(). JSCallbackObject and RuntimeArray are fixed to follow it.

for/in and Object.keys microbenchmarks are neutral. This change does not affect
JSPropertyNameEnumerator caching, nor fast paths of its bytecodes.

[1]: https://github.com/tc39/ecma262/pull/1791
[2]: https://tc39.es/ecma262/#sec-enumerate-object-properties (last paragraph)
[3]: https://tc39.es/ecma262/#sec-%foriniteratorprototype%.next (step 7.b.iii)

* API/JSCallbackObjectFunctions.h:
(JSC::JSCallbackObject<Parent>::getOwnPropertySlot):
* API/tests/testapi.c:
* API/tests/testapiScripts/testapi.js:
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
(JSC::computeDefsForBytecodeIndexImpl):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
* bytecode/Opcode.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitHasEnumerableIndexedProperty):
(JSC::BytecodeGenerator::emitHasEnumerableStructureProperty):
(JSC::BytecodeGenerator::emitHasEnumerableProperty):
(JSC::BytecodeGenerator::emitHasGenericProperty): Deleted.
(JSC::BytecodeGenerator::emitHasIndexedProperty): Deleted.
(JSC::BytecodeGenerator::emitHasStructureProperty): Deleted.
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ForInNode::emitBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::convertToHasIndexedProperty):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasArrayMode):
(JSC::DFG::Node::hasInternalMethodType const): Deleted.
(JSC::DFG::Node::internalMethodType const): Deleted.
(JSC::DFG::Node::setInternalMethodType): Deleted.
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSSALoweringPhase.cpp:
(JSC::DFG::SSALoweringPhase::handleNode):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileHasEnumerableProperty):
(JSC::DFG::SpeculativeJIT::compileHasEnumerableStructureProperty):
(JSC::DFG::SpeculativeJIT::compileHasIndexedProperty):
(JSC::DFG::SpeculativeJIT::compileHasGenericProperty): Deleted.
(JSC::DFG::SpeculativeJIT::compileHasStructureProperty): Deleted.
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileHasIndexedProperty):
(JSC::FTL::DFG::LowerDFGToB3::compileHasEnumerableProperty):
(JSC::FTL::DFG::LowerDFGToB3::compileHasEnumerableStructureProperty):
(JSC::FTL::DFG::LowerDFGToB3::compileHasGenericProperty): Deleted.
(JSC::FTL::DFG::LowerDFGToB3::compileHasStructureProperty): Deleted.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_has_enumerable_structure_property):
(JSC::JIT::emit_op_has_enumerable_indexed_property):
(JSC::JIT::emitSlow_op_has_enumerable_indexed_property):
(JSC::JIT::emit_op_has_structure_property): Deleted.
(JSC::JIT::emit_op_has_indexed_property): Deleted.
(JSC::JIT::emitSlow_op_has_indexed_property): Deleted.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_has_enumerable_structure_property):
(JSC::JIT::emit_op_has_enumerable_indexed_property):
(JSC::JIT::emitSlow_op_has_enumerable_indexed_property):
(JSC::JIT::emit_op_has_structure_property): Deleted.
(JSC::JIT::emit_op_has_indexed_property): Deleted.
(JSC::JIT::emitSlow_op_has_indexed_property): Deleted.
* jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* jit/JITOperations.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* runtime/CommonSlowPaths.h:
* runtime/JSObject.cpp:
(JSC::JSObject::hasProperty const):
(JSC::JSObject::hasEnumerableProperty const):
(JSC::JSObject::hasPropertyGeneric const): Deleted.
* runtime/JSObject.h:

Source/WebCore:

Report RuntimeArray indices as [[Enumerable]].

Test: platform/mac/fast/dom/wrapper-classes-objc.html

* bridge/runtime_array.cpp:
(JSC::RuntimeArray::getOwnPropertySlot):
(JSC::RuntimeArray::getOwnPropertySlotByIndex):

LayoutTests:

* platform/mac/fast/dom/wrapper-classes-objc-expected.txt:
* platform/mac/fast/dom/wrapper-classes-objc.html:


Canonical link: https://commits.webkit.org/232510@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270874 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-12-16 00:33:34 +00:00
Dmitry Bezhetskov 36ccf4adaa [WASM-References] Add support for memory.fill
https://bugs.webkit.org/show_bug.cgi?id=219848

Patch by Dmitry Bezhetskov <dbezhetskov@igalia.com> on 2020-12-15
Reviewed by Yusuke Suzuki.

JSTests:

Added spec tests and unreachable tests for memory.fill.

* wasm.yaml:
* wasm/references-spec-tests/memory_fill.wast.js: Added.
* wasm/references/memory_fill_shared.js: Added.
(async test):
* wasm/references/table_instructions_parse_unreachable.js:
(invalidMemoryFillUnreachable):
* wasm/wasm.json:

Source/JavaScriptCore:

Add support for memory.fill from ref-types spec.
memory.fill sets all bytes in a memory region to a given byte:
https://webassembly.github.io/reference-types/core/syntax/instructions.html#memory-instructions.

* bytecode/BytecodeList.rb:
* llint/WebAssembly.asm:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addMemoryFill):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::addMemoryFill):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseMemoryFillImmediate):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::addMemoryFill):
* wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::fill):
(JSC::Wasm::Memory::doMemoryFill):
* wasm/WasmMemory.h:
* wasm/WasmOperations.cpp:
(JSC::Wasm::JSC_DEFINE_JIT_OPERATION):
* wasm/WasmOperations.h:
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/wasm.json:

Canonical link: https://commits.webkit.org/232496@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@270855 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-12-15 19:15:33 +00:00