[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:
- If it's a BrandedStructure, we then set it to
m_parentBrand
,
to allow proper brand chain check.
- 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.
Adding @privateBrand
that we use to store private brand on
class's scope.
(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):
(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):
(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:
- Create a PrivateSymbol using
@createPrivateSymbol
.
- 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):
(JSC::DFG::capabilityLevel):
(JSC::DFG::clobberize):
- dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
(JSC::DFG::doesGC):
(JSC::DFG::FixupPhase::fixupNode):
- dfg/DFGGraph.h:
- dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
(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):
(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):
(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):
(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):
(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):
(JSC::BaseDotNode::isPrivateMember const):
(JSC::BaseDotNode::isPrivateField const): Deleted.
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseMemberExpression):
(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.
(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.
(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):
(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):
(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):