⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 259463 in webkit


Ignore:
Timestamp:
Apr 3, 2020, 8:58:59 AM (6 years ago)
Author:
ysuzuki@apple.com
Message:

Unreviewed, partially reverting Structure change due to Speedometer2 regression
https://bugs.webkit.org/show_bug.cgi?id=207827

Not reverting WTF changes.

  • bytecode/AccessCase.cpp:

(JSC::AccessCase::createTransition):
(JSC::AccessCase::createDelete):
(JSC::AccessCase::propagateTransitions const):

  • bytecode/AccessCase.h:

(JSC::AccessCase::structure const):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileCheckSubClass):
(JSC::DFG::SpeculativeJIT::compileObjectKeys):
(JSC::DFG::SpeculativeJIT::compileCreateThis):
(JSC::DFG::SpeculativeJIT::compileCreatePromise):
(JSC::DFG::SpeculativeJIT::compileCreateInternalFieldObject):

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileObjectKeys):
(JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateInternalFieldObject):
(JSC::FTL::DFG::LowerDFGToB3::compileCheckSubClass):
(JSC::FTL::DFG::LowerDFGToB3::loadStructureClassInfo): Deleted.
(JSC::FTL::DFG::LowerDFGToB3::loadStructureCachedPrototypeChainOrRareData): Deleted.

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::emitLoadClassInfoFromStructure): Deleted.

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_create_this):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_create_this):

  • jit/Repatch.cpp:

(JSC::tryCachePutByID):
(JSC::tryCacheDeleteBy):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/ClonedArguments.cpp:

(JSC::ClonedArguments::createStructure):

  • runtime/ConcurrentJSLock.h:

(JSC::ConcurrentJSLockerBase::ConcurrentJSLockerBase):
(JSC::GCSafeConcurrentJSLocker::GCSafeConcurrentJSLocker):
(JSC::GCSafeConcurrentJSLocker::~GCSafeConcurrentJSLocker):
(JSC::ConcurrentJSLocker::ConcurrentJSLocker):
(JSC::GCSafeConcurrentJSLockerImpl::GCSafeConcurrentJSLockerImpl): Deleted.
(JSC::GCSafeConcurrentJSLockerImpl::~GCSafeConcurrentJSLockerImpl): Deleted.
(JSC::ConcurrentJSLockerImpl::ConcurrentJSLockerImpl): Deleted.

  • runtime/JSCell.h:
  • runtime/JSObject.cpp:

(JSC::JSObject::deleteProperty):
(JSC::JSObject::shiftButterflyAfterFlattening):

  • runtime/JSObject.h:

(JSC::JSObject::getDirectConcurrently const):

  • runtime/JSObjectInlines.h:

(JSC::JSObject::prepareToPutDirectWithoutTransition):

  • runtime/JSType.cpp:

(WTF::printInternal):

  • runtime/JSType.h:
  • runtime/Structure.cpp:

(JSC::StructureTransitionTable::contains const):
(JSC::StructureTransitionTable::get const):
(JSC::StructureTransitionTable::add):
(JSC::Structure::dumpStatistics):
(JSC::Structure::Structure):
(JSC::Structure::create):
(JSC::Structure::findStructuresAndMapForMaterialization):
(JSC::Structure::materializePropertyTable):
(JSC::Structure::addPropertyTransitionToExistingStructureImpl):
(JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
(JSC::Structure::addNewPropertyTransition):
(JSC::Structure::removePropertyTransitionFromExistingStructureConcurrently):
(JSC::Structure::removeNewPropertyTransition):
(JSC::Structure::changePrototypeTransition):
(JSC::Structure::attributeChangeTransition):
(JSC::Structure::toDictionaryTransition):
(JSC::Structure::takePropertyTableOrCloneIfPinned):
(JSC::Structure::nonPropertyTransitionSlow):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::pin):
(JSC::Structure::pinForCaching):
(JSC::Structure::allocateRareData):
(JSC::Structure::ensurePropertyReplacementWatchpointSet):
(JSC::Structure::copyPropertyTableForPinning):
(JSC::Structure::add):
(JSC::Structure::remove):
(JSC::Structure::visitChildren):
(JSC::Structure::canCachePropertyNameEnumerator const):

  • runtime/Structure.h:
  • runtime/StructureInlines.h:

(JSC::Structure::get):
(JSC::Structure::forEachPropertyConcurrently):
(JSC::Structure::transitivelyTransitionedFrom):
(JSC::Structure::prototypeChain const):
(JSC::Structure::propertyReplacementWatchpointSet):
(JSC::Structure::checkOffsetConsistency const):
(JSC::Structure::add):
(JSC::Structure::remove):
(JSC::Structure::removePropertyWithoutTransition):
(JSC::Structure::setPropertyTable):
(JSC::Structure::setPreviousID):
(JSC::Structure::ruleOutUnseenProperty const): Deleted.
(JSC::Structure::seenProperties const): Deleted.
(JSC::Structure::addPropertyHashAndSeenProperty): Deleted.
(JSC::Structure::cachedPrototypeChain const): Deleted.
(JSC::Structure::setCachedPrototypeChain): Deleted.
(JSC::Structure::clearPropertyTable): Deleted.
(JSC::Structure::setOutOfLineTypeFlags): Deleted.
(JSC::Structure::setInlineCapacity): Deleted.
(JSC::Structure::setClassInfo): Deleted.
(JSC::Structure::clearPreviousID): Deleted.

  • runtime/StructureRareData.cpp:

(JSC::StructureRareData::createStructure):
(JSC::StructureRareData::create):
(JSC::StructureRareData::StructureRareData):
(JSC::StructureRareData::visitChildren):

  • runtime/StructureRareData.h:
  • runtime/StructureRareDataInlines.h:

(JSC::StructureRareData::setPreviousID):
(JSC::StructureRareData::clearPreviousID):
(JSC::StructureRareData::setCachedPrototypeChain): Deleted.

  • runtime/StructureTransitionTable.h:
  • tools/JSDollarVM.cpp:

(JSC::JSDollarVMHelper::functionGetStructureTransitionList):

  • wasm/js/WebAssemblyFunction.cpp:

(JSC::WebAssemblyFunction::jsCallEntrypointSlow):

Location:
trunk/Source/JavaScriptCore
Files:
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r259444 r259463  
     12020-04-03  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Unreviewed, partially reverting Structure change due to Speedometer2 regression
     4        https://bugs.webkit.org/show_bug.cgi?id=207827
     5
     6        Not reverting WTF changes.
     7
     8        * bytecode/AccessCase.cpp:
     9        (JSC::AccessCase::createTransition):
     10        (JSC::AccessCase::createDelete):
     11        (JSC::AccessCase::propagateTransitions const):
     12        * bytecode/AccessCase.h:
     13        (JSC::AccessCase::structure const):
     14        * dfg/DFGSpeculativeJIT.cpp:
     15        (JSC::DFG::SpeculativeJIT::compileCheckSubClass):
     16        (JSC::DFG::SpeculativeJIT::compileObjectKeys):
     17        (JSC::DFG::SpeculativeJIT::compileCreateThis):
     18        (JSC::DFG::SpeculativeJIT::compileCreatePromise):
     19        (JSC::DFG::SpeculativeJIT::compileCreateInternalFieldObject):
     20        * ftl/FTLAbstractHeapRepository.h:
     21        * ftl/FTLLowerDFGToB3.cpp:
     22        (JSC::FTL::DFG::LowerDFGToB3::compileObjectKeys):
     23        (JSC::FTL::DFG::LowerDFGToB3::compileCreatePromise):
     24        (JSC::FTL::DFG::LowerDFGToB3::compileCreateInternalFieldObject):
     25        (JSC::FTL::DFG::LowerDFGToB3::compileCheckSubClass):
     26        (JSC::FTL::DFG::LowerDFGToB3::loadStructureClassInfo): Deleted.
     27        (JSC::FTL::DFG::LowerDFGToB3::loadStructureCachedPrototypeChainOrRareData): Deleted.
     28        * jit/AssemblyHelpers.h:
     29        (JSC::AssemblyHelpers::emitLoadClassInfoFromStructure): Deleted.
     30        * jit/JITOpcodes.cpp:
     31        (JSC::JIT::emit_op_create_this):
     32        * jit/JITOpcodes32_64.cpp:
     33        (JSC::JIT::emit_op_create_this):
     34        * jit/Repatch.cpp:
     35        (JSC::tryCachePutByID):
     36        (JSC::tryCacheDeleteBy):
     37        * llint/LLIntSlowPaths.cpp:
     38        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     39        * runtime/ClonedArguments.cpp:
     40        (JSC::ClonedArguments::createStructure):
     41        * runtime/ConcurrentJSLock.h:
     42        (JSC::ConcurrentJSLockerBase::ConcurrentJSLockerBase):
     43        (JSC::GCSafeConcurrentJSLocker::GCSafeConcurrentJSLocker):
     44        (JSC::GCSafeConcurrentJSLocker::~GCSafeConcurrentJSLocker):
     45        (JSC::ConcurrentJSLocker::ConcurrentJSLocker):
     46        (JSC::GCSafeConcurrentJSLockerImpl::GCSafeConcurrentJSLockerImpl): Deleted.
     47        (JSC::GCSafeConcurrentJSLockerImpl::~GCSafeConcurrentJSLockerImpl): Deleted.
     48        (JSC::ConcurrentJSLockerImpl::ConcurrentJSLockerImpl): Deleted.
     49        * runtime/JSCell.h:
     50        * runtime/JSObject.cpp:
     51        (JSC::JSObject::deleteProperty):
     52        (JSC::JSObject::shiftButterflyAfterFlattening):
     53        * runtime/JSObject.h:
     54        (JSC::JSObject::getDirectConcurrently const):
     55        * runtime/JSObjectInlines.h:
     56        (JSC::JSObject::prepareToPutDirectWithoutTransition):
     57        * runtime/JSType.cpp:
     58        (WTF::printInternal):
     59        * runtime/JSType.h:
     60        * runtime/Structure.cpp:
     61        (JSC::StructureTransitionTable::contains const):
     62        (JSC::StructureTransitionTable::get const):
     63        (JSC::StructureTransitionTable::add):
     64        (JSC::Structure::dumpStatistics):
     65        (JSC::Structure::Structure):
     66        (JSC::Structure::create):
     67        (JSC::Structure::findStructuresAndMapForMaterialization):
     68        (JSC::Structure::materializePropertyTable):
     69        (JSC::Structure::addPropertyTransitionToExistingStructureImpl):
     70        (JSC::Structure::addPropertyTransitionToExistingStructureConcurrently):
     71        (JSC::Structure::addNewPropertyTransition):
     72        (JSC::Structure::removePropertyTransitionFromExistingStructureConcurrently):
     73        (JSC::Structure::removeNewPropertyTransition):
     74        (JSC::Structure::changePrototypeTransition):
     75        (JSC::Structure::attributeChangeTransition):
     76        (JSC::Structure::toDictionaryTransition):
     77        (JSC::Structure::takePropertyTableOrCloneIfPinned):
     78        (JSC::Structure::nonPropertyTransitionSlow):
     79        (JSC::Structure::flattenDictionaryStructure):
     80        (JSC::Structure::pin):
     81        (JSC::Structure::pinForCaching):
     82        (JSC::Structure::allocateRareData):
     83        (JSC::Structure::ensurePropertyReplacementWatchpointSet):
     84        (JSC::Structure::copyPropertyTableForPinning):
     85        (JSC::Structure::add):
     86        (JSC::Structure::remove):
     87        (JSC::Structure::visitChildren):
     88        (JSC::Structure::canCachePropertyNameEnumerator const):
     89        * runtime/Structure.h:
     90        * runtime/StructureInlines.h:
     91        (JSC::Structure::get):
     92        (JSC::Structure::forEachPropertyConcurrently):
     93        (JSC::Structure::transitivelyTransitionedFrom):
     94        (JSC::Structure::prototypeChain const):
     95        (JSC::Structure::propertyReplacementWatchpointSet):
     96        (JSC::Structure::checkOffsetConsistency const):
     97        (JSC::Structure::add):
     98        (JSC::Structure::remove):
     99        (JSC::Structure::removePropertyWithoutTransition):
     100        (JSC::Structure::setPropertyTable):
     101        (JSC::Structure::setPreviousID):
     102        (JSC::Structure::ruleOutUnseenProperty const): Deleted.
     103        (JSC::Structure::seenProperties const): Deleted.
     104        (JSC::Structure::addPropertyHashAndSeenProperty): Deleted.
     105        (JSC::Structure::cachedPrototypeChain const): Deleted.
     106        (JSC::Structure::setCachedPrototypeChain): Deleted.
     107        (JSC::Structure::clearPropertyTable): Deleted.
     108        (JSC::Structure::setOutOfLineTypeFlags): Deleted.
     109        (JSC::Structure::setInlineCapacity): Deleted.
     110        (JSC::Structure::setClassInfo): Deleted.
     111        (JSC::Structure::clearPreviousID): Deleted.
     112        * runtime/StructureRareData.cpp:
     113        (JSC::StructureRareData::createStructure):
     114        (JSC::StructureRareData::create):
     115        (JSC::StructureRareData::StructureRareData):
     116        (JSC::StructureRareData::visitChildren):
     117        * runtime/StructureRareData.h:
     118        * runtime/StructureRareDataInlines.h:
     119        (JSC::StructureRareData::setPreviousID):
     120        (JSC::StructureRareData::clearPreviousID):
     121        (JSC::StructureRareData::setCachedPrototypeChain): Deleted.
     122        * runtime/StructureTransitionTable.h:
     123        * tools/JSDollarVM.cpp:
     124        (JSC::JSDollarVMHelper::functionGetStructureTransitionList):
     125        * wasm/js/WebAssemblyFunction.cpp:
     126        (JSC::WebAssemblyFunction::jsCallEntrypointSlow):
     127
    11282020-04-02  Alexey Shvayka  <shvaikalesh@gmail.com>
    2129
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp

    r259175 r259463  
    113113    const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    114114{
    115     RELEASE_ASSERT(oldStructure == newStructure->previousID(vm));
     115    RELEASE_ASSERT(oldStructure == newStructure->previousID());
    116116
    117117    // Skip optimizing the case where we need a realloc, if we don't have
     
    129129    VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure)
    130130{
    131     RELEASE_ASSERT(oldStructure == newStructure->previousID(vm));
     131    RELEASE_ASSERT(oldStructure == newStructure->previousID());
    132132    // We do not cache this case so that we do not need to check the jscell, e.g. TypedArray cells require a check for neutering status.
    133133    // See the Delete code below.
     
    743743    case Transition:
    744744    case Delete:
    745         if (visitor.vm().heap.isMarked(m_structure->previousID(visitor.vm())))
     745        if (visitor.vm().heap.isMarked(m_structure->previousID()))
    746746            visitor.appendUnbarriered(m_structure.get());
    747747        else
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.h

    r257399 r259463  
    164164    {
    165165        if (m_type == Transition || m_type == Delete)
    166             return m_structure->previousID(m_structure->vm());
     166            return m_structure->previousID();
    167167        return m_structure.get();
    168168    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r259320 r259463  
    95699569
    95709570        m_jit.emitLoadStructure(vm(), baseGPR, otherGPR, specifiedGPR);
    9571         m_jit.emitLoadClassInfoFromStructure(otherGPR, otherGPR);
     9571        m_jit.loadPtr(CCallHelpers::Address(otherGPR, Structure::classInfoOffset()), otherGPR);
    95729572        m_jit.move(CCallHelpers::TrustedImmPtr(node->classInfo()), specifiedGPR);
    95739573
     
    1266212662            CCallHelpers::JumpList slowCases;
    1266312663            m_jit.emitLoadStructure(vm(), objectGPR, structureGPR, scratchGPR);
    12664             m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::offsetOfCachedPrototypeChainOrRareData()), scratchGPR);
    12665 #if CPU(ADDRESS64)
    12666             m_jit.andPtr(CCallHelpers::TrustedImmPtr(Structure::cachedPrototypeChainOrRareDataMask), scratchGPR);
    12667 #endif
     12664            m_jit.loadPtr(CCallHelpers::Address(structureGPR, Structure::previousOrRareDataOffset()), scratchGPR);
    1266812665
    1266912666            slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, scratchGPR));
    12670             slowCases.append(m_jit.branch32(CCallHelpers::NotEqual, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(vm().structureRareDataStructure->structureID()))));
     12667            slowCases.append(m_jit.branch32(CCallHelpers::Equal, CCallHelpers::Address(scratchGPR, JSCell::structureIDOffset()), TrustedImm32(bitwise_cast<int32_t>(vm().structureStructure->structureID()))));
    1267112668
    1267212669            m_jit.loadPtr(CCallHelpers::Address(scratchGPR, StructureRareData::offsetOfCachedOwnKeys()), scratchGPR);
     
    1280612803    emitAllocateJSObject(resultGPR, JITAllocator::variable(), allocatorGPR, structureGPR, butterfly, scratchGPR, slowPath);
    1280712804
    12808     m_jit.load8(JITCompiler::Address(structureGPR, Structure::offsetOfInlineCapacity()), inlineCapacityGPR);
     12805    m_jit.load8(JITCompiler::Address(structureGPR, Structure::inlineCapacityOffset()), inlineCapacityGPR);
    1280912806    m_jit.emitInitializeInlineStorage(resultGPR, inlineCapacityGPR);
    1281012807    m_jit.mutatorFence(vm());
     
    1284412841    m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure() - JSFunction::rareDataTag), structureGPR);
    1284512842    slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR));
    12846     m_jit.emitLoadClassInfoFromStructure(structureGPR, scratch1GPR);
    12847     slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())));
     12843    m_jit.move(TrustedImmPtr(node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info()), scratch1GPR);
     12844    slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset())));
    1284812845    m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR);
    1284912846    slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset())));
     
    1289212889    m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure() - JSFunction::rareDataTag), structureGPR);
    1289312890    slowCases.append(m_jit.branchTestPtr(CCallHelpers::Zero, structureGPR));
    12894     m_jit.emitLoadClassInfoFromStructure(structureGPR, scratch1GPR);
    12895     slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, TrustedImmPtr(JSClass::info())));
     12891    m_jit.move(TrustedImmPtr(JSClass::info()), scratch1GPR);
     12892    slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::classInfoOffset())));
    1289612893    m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), globalObject), scratch1GPR);
    1289712894    slowCases.append(m_jit.branchPtr(CCallHelpers::NotEqual, scratch1GPR, CCallHelpers::Address(structureGPR, Structure::globalObjectOffset())));
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r257201 r259463  
    140140    macro(StringImpl_hashAndFlags, StringImpl::flagsOffset()) \
    141141    macro(StringImpl_length, StringImpl::lengthMemoryOffset()) \
    142     macro(Structure_classInfo, Structure::offsetOfClassInfo()) \
     142    macro(Structure_classInfo, Structure::classInfoOffset()) \
    143143    macro(Structure_globalObject, Structure::globalObjectOffset()) \
    144144    macro(Structure_indexingModeIncludingHistory, Structure::indexingModeIncludingHistoryOffset()) \
    145     macro(Structure_inlineCapacity, Structure::offsetOfInlineCapacity()) \
    146     macro(Structure_cachedPrototypeChainOrRareData, Structure::offsetOfCachedPrototypeChainOrRareData()) \
     145    macro(Structure_inlineCapacity, Structure::inlineCapacityOffset()) \
     146    macro(Structure_previousOrRareData, Structure::previousOrRareDataOffset()) \
    147147    macro(Structure_prototype, Structure::prototypeOffset()) \
    148148    macro(Structure_structureID, Structure::structureIDOffset()) \
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r259320 r259463  
    62526252                LValue object = lowObject(m_node->child1());
    62536253                LValue structure = loadStructure(object);
    6254                 LValue cachedPrototypeChainOrRareData = loadStructureCachedPrototypeChainOrRareData(structure);
    6255                 m_out.branch(m_out.notNull(cachedPrototypeChainOrRareData), unsure(notNullCase), unsure(slowCase));
     6254                LValue previousOrRareData = m_out.loadPtr(structure, m_heaps.Structure_previousOrRareData);
     6255                m_out.branch(m_out.notNull(previousOrRareData), unsure(notNullCase), unsure(slowCase));
    62566256
    62576257                LBasicBlock lastNext = m_out.appendTo(notNullCase, rareDataCase);
    62586258                m_out.branch(
    6259                     m_out.equal(m_out.load32(cachedPrototypeChainOrRareData, m_heaps.JSCell_structureID), m_out.constInt32(m_graph.m_vm.structureRareDataStructure->structureID())),
     6259                    m_out.notEqual(m_out.load32(previousOrRareData, m_heaps.JSCell_structureID), m_out.constInt32(m_graph.m_vm.structureStructure->structureID())),
    62606260                    unsure(rareDataCase), unsure(slowCase));
    62616261
    62626262                m_out.appendTo(rareDataCase, useCacheCase);
    62636263                ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedOwnKeysSentinel()) == 1);
    6264                 LValue cachedOwnKeys = m_out.loadPtr(cachedPrototypeChainOrRareData, m_heaps.StructureRareData_cachedOwnKeys);
     6264                LValue cachedOwnKeys = m_out.loadPtr(previousOrRareData, m_heaps.StructureRareData_cachedOwnKeys);
    62656265                m_out.branch(m_out.belowOrEqual(cachedOwnKeys, m_out.constIntPtr(bitwise_cast<void*>(StructureRareData::cachedOwnKeysSentinel()))), unsure(slowCase), unsure(useCacheCase));
    62666266
     
    68366836
    68376837        m_out.appendTo(hasStructure, checkGlobalObjectCase);
    6838         LValue classInfo = loadStructureClassInfo(structure);
    6839         m_out.branch(m_out.equal(classInfo, m_out.constIntPtr(m_node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())), usually(checkGlobalObjectCase), rarely(slowCase));
     6838        m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(m_node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())), usually(checkGlobalObjectCase), rarely(slowCase));
    68406839
    68416840        m_out.appendTo(checkGlobalObjectCase, fastAllocationCase);
     
    68926891
    68936892        m_out.appendTo(hasStructure, checkGlobalObjectCase);
    6894         LValue classInfo = loadStructureClassInfo(structure);
    6895         m_out.branch(m_out.equal(classInfo, m_out.constIntPtr(JSClass::info())), usually(checkGlobalObjectCase), rarely(slowCase));
     6893        m_out.branch(m_out.equal(m_out.loadPtr(structure, m_heaps.Structure_classInfo), m_out.constIntPtr(JSClass::info())), usually(checkGlobalObjectCase), rarely(slowCase));
    68966894
    68976895        m_out.appendTo(checkGlobalObjectCase, fastAllocationCase);
     
    1338313381
    1338413382            LValue structure = loadStructure(cell);
    13385             LValue classInfo = loadStructureClassInfo(structure);
     13383            LValue classInfo = m_out.loadPtr(structure, m_heaps.Structure_classInfo);
    1338613384            ValueFromBlock otherAtStart = m_out.anchor(classInfo);
    1338713385            m_out.jump(loop);
     
    1839918397    }
    1840018398
    18401     LValue loadStructureClassInfo(LValue structure)
    18402     {
    18403         LValue result = m_out.loadPtr(structure, m_heaps.Structure_classInfo);
    18404 #if CPU(ADDRESS64)
    18405         return m_out.bitAnd(m_out.constIntPtr(Structure::classInfoMask), result);
    18406 #else
    18407         return result;
    18408 #endif
    18409     }
    18410 
    18411     LValue loadStructureCachedPrototypeChainOrRareData(LValue structure)
    18412     {
    18413         LValue result = m_out.loadPtr(structure, m_heaps.Structure_cachedPrototypeChainOrRareData);
    18414 #if CPU(ADDRESS64)
    18415         return m_out.bitAnd(m_out.constIntPtr(Structure::cachedPrototypeChainOrRareDataMask), result);
    18416 #else
    18417         return result;
    18418 #endif
    18419     }
    18420 
    1842118399    LValue weakPointer(JSCell* pointer)
    1842218400    {
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r258952 r259463  
    15351535   
    15361536    void emitLoadStructure(VM&, RegisterID source, RegisterID dest, RegisterID scratch);
    1537 
    1538     void emitLoadClassInfoFromStructure(RegisterID structure, RegisterID dst)
    1539     {
    1540         loadPtr(Address(structure, Structure::offsetOfClassInfo()), dst);
    1541 #if CPU(ADDRESS64)
    1542         andPtr(TrustedImmPtr(bitwise_cast<void*>(Structure::classInfoMask)), dst);
    1543 #endif
    1544     }
    15451537
    15461538    void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID)
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r258874 r259463  
    980980    auto butterfly = TrustedImmPtr(nullptr);
    981981    emitAllocateJSObject(resultReg, JITAllocator::variable(), allocatorReg, structureReg, butterfly, scratchReg, slowCases);
    982     load8(Address(structureReg, Structure::offsetOfInlineCapacity()), scratchReg);
     982    load8(Address(structureReg, Structure::inlineCapacityOffset()), scratchReg);
    983983    emitInitializeInlineStorage(resultReg, scratchReg);
    984984    addSlowCase(slowCases);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r258874 r259463  
    10941094    auto butterfly = TrustedImmPtr(nullptr);
    10951095    emitAllocateJSObject(resultReg, JITAllocator::variable(), allocatorReg, structureReg, butterfly, scratchReg, slowCases);
    1096     load8(Address(structureReg, Structure::offsetOfInlineCapacity()), scratchReg);
     1096    load8(Address(structureReg, Structure::inlineCapacityOffset()), scratchReg);
    10971097    emitInitializeInlineStorage(resultReg, scratchReg);
    10981098    addSlowCase(slowCases);
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r259357 r259463  
    619619                    return GiveUpOnCache;
    620620
    621                 ASSERT(newStructure->previousID(vm) == oldStructure);
     621                ASSERT(newStructure->previousID() == oldStructure);
    622622                ASSERT(!newStructure->isDictionary());
    623623                ASSERT(newStructure->isObject());
     
    767767                return GiveUpOnCache;
    768768            ASSERT(newOffset == slot.cachedOffset());
    769             ASSERT(newStructure->previousID(vm) == oldStructure);
     769            ASSERT(newStructure->previousID() == oldStructure);
    770770            ASSERT(newStructure->isPropertyDeletionTransition());
    771771            ASSERT(newStructure->isObject());
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r257399 r259463  
    856856                Structure* b = baseValue.asCell()->structure(vm);
    857857                if (slot.type() == PutPropertySlot::NewProperty)
    858                     b = b->previousID(vm);
     858                    b = b->previousID();
    859859
    860860                if (Structure::shouldConvertToPolyProto(a, b)) {
     
    877877            if (slot.type() == PutPropertySlot::NewProperty) {
    878878                GCSafeConcurrentJSLocker locker(codeBlock->m_lock, vm.heap);
    879                 if (!newStructure->isDictionary() && newStructure->previousID(vm)->outOfLineCapacity() == newStructure->outOfLineCapacity()) {
    880                     ASSERT(oldStructure == newStructure->previousID(vm));
    881                     if (oldStructure == newStructure->previousID(vm)) {
     879                if (!newStructure->isDictionary() && newStructure->previousID()->outOfLineCapacity() == newStructure->outOfLineCapacity()) {
     880                    ASSERT(oldStructure == newStructure->previousID());
     881                    if (oldStructure == newStructure->previousID()) {
    882882                        ASSERT(oldStructure->transitionWatchpointSetHasBeenInvalidated());
    883883
  • trunk/Source/JavaScriptCore/runtime/ClonedArguments.cpp

    r257399 r259463  
    154154    structure->addPropertyWithoutTransition(
    155155        vm, vm.propertyNames->length, static_cast<unsigned>(PropertyAttribute::DontEnum),
    156         [&](const GCSafeConcurrentJSCellLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
     156        [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
    157157            RELEASE_ASSERT(offset == clonedArgumentsLengthPropertyOffset);
    158158            structure->setMaxOffset(vm, newMaxOffset);
  • trunk/Source/JavaScriptCore/runtime/ConcurrentJSLock.h

    r257201 r259463  
    3434
    3535using ConcurrentJSLock = Lock;
     36using ConcurrentJSLockerImpl = LockHolder;
    3637
    37 static_assert(sizeof(ConcurrentJSLock) == 1, "Regardless of status of concurrent JS flag, size of ConcurrentJSLock is always one byte.");
     38static_assert(sizeof(ConcurrentJSLock) == 1, "Regardless of status of concurrent JS flag, size of ConurrentJSLock is always one byte.");
    3839
    39 template<typename Lock>
    4040class ConcurrentJSLockerBase : public AbstractLocker {
    4141    WTF_MAKE_NONCOPYABLE(ConcurrentJSLockerBase);
    4242public:
    43     explicit ConcurrentJSLockerBase(Lock& lockable)
     43    explicit ConcurrentJSLockerBase(ConcurrentJSLock& lockable)
    4444        : m_locker(&lockable)
    4545    {
    4646    }
    47     explicit ConcurrentJSLockerBase(Lock* lockable)
     47    explicit ConcurrentJSLockerBase(ConcurrentJSLock* lockable)
    4848        : m_locker(lockable)
    4949    {
     
    6565
    6666private:
    67     Locker<Lock> m_locker;
     67    ConcurrentJSLockerImpl m_locker;
    6868};
    6969
    70 template<typename Lock>
    71 class GCSafeConcurrentJSLockerImpl : public ConcurrentJSLockerBase<Lock> {
     70class GCSafeConcurrentJSLocker : public ConcurrentJSLockerBase {
    7271public:
    73     GCSafeConcurrentJSLockerImpl(Lock& lockable, Heap& heap)
    74         : ConcurrentJSLockerBase<Lock>(lockable)
     72    GCSafeConcurrentJSLocker(ConcurrentJSLock& lockable, Heap& heap)
     73        : ConcurrentJSLockerBase(lockable)
    7574        , m_deferGC(heap)
    7675    {
    7776    }
    7877
    79     GCSafeConcurrentJSLockerImpl(Lock* lockable, Heap& heap)
    80         : ConcurrentJSLockerBase<Lock>(lockable)
     78    GCSafeConcurrentJSLocker(ConcurrentJSLock* lockable, Heap& heap)
     79        : ConcurrentJSLockerBase(lockable)
    8180        , m_deferGC(heap)
    8281    {
    8382    }
    8483
    85     ~GCSafeConcurrentJSLockerImpl()
     84    ~GCSafeConcurrentJSLocker()
    8685    {
    8786        // We have to unlock early due to the destruction order of base
     
    8988        // DeferGC object before unlocking the lock which could cause a GC
    9089        // and resulting deadlock.
    91         ConcurrentJSLockerBase<Lock>::unlockEarly();
     90        unlockEarly();
    9291    }
    9392
     
    9695};
    9796
    98 template<typename Lock>
    99 class ConcurrentJSLockerImpl : public ConcurrentJSLockerBase<Lock> {
     97class ConcurrentJSLocker : public ConcurrentJSLockerBase {
    10098public:
    101     ConcurrentJSLockerImpl(Lock& lockable)
    102         : ConcurrentJSLockerBase<Lock>(lockable)
     99    ConcurrentJSLocker(ConcurrentJSLock& lockable)
     100        : ConcurrentJSLockerBase(lockable)
    103101#if !defined(NDEBUG)
    104102        , m_disallowGC(std::in_place)
     
    107105    }
    108106
    109     ConcurrentJSLockerImpl(Lock* lockable)
    110         : ConcurrentJSLockerBase<Lock>(lockable)
     107    ConcurrentJSLocker(ConcurrentJSLock* lockable)
     108        : ConcurrentJSLockerBase(lockable)
    111109#if !defined(NDEBUG)
    112110        , m_disallowGC(std::in_place)
     
    115113    }
    116114
    117     ConcurrentJSLockerImpl(NoLockingNecessaryTag)
    118         : ConcurrentJSLockerBase<Lock>(NoLockingNecessary)
     115    ConcurrentJSLocker(NoLockingNecessaryTag)
     116        : ConcurrentJSLockerBase(NoLockingNecessary)
    119117#if !defined(NDEBUG)
    120118        , m_disallowGC(WTF::nullopt)
     
    123121    }
    124122   
    125     ConcurrentJSLockerImpl(int) = delete;
     123    ConcurrentJSLocker(int) = delete;
    126124
    127125#if !defined(NDEBUG)
     
    131129};
    132130
    133 using ConcurrentJSLocker = ConcurrentJSLockerImpl<ConcurrentJSLock>;
    134 using GCSafeConcurrentJSLocker = GCSafeConcurrentJSLockerImpl<ConcurrentJSLock>;
    135 
    136131} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r258386 r259463  
    2525#include "CallData.h"
    2626#include "CellState.h"
    27 #include "ConcurrentJSLock.h"
    2827#include "ConstructData.h"
    2928#include "EnumerationMode.h"
     
    291290};
    292291
    293 using ConcurrentJSCellLocker = ConcurrentJSLockerImpl<JSCellLock>;
    294 using GCSafeConcurrentJSCellLocker = GCSafeConcurrentJSLockerImpl<JSCellLock>;
    295 
    296292// FIXME: Refer to Subspace by reference.
    297293// https://bugs.webkit.org/show_bug.cgi?id=166988
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r258170 r259463  
    20082008        PropertyOffset offset = invalidOffset;
    20092009        if (structure->isUncacheableDictionary())
    2010             offset = structure->removePropertyWithoutTransition(vm, propertyName, [](const GCSafeConcurrentJSCellLocker&, PropertyOffset, PropertyOffset) { });
     2010            offset = structure->removePropertyWithoutTransition(vm, propertyName, [] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset) { });
    20112011        else {
    20122012            structure = Structure::removePropertyTransition(vm, structure, propertyName, offset, &deferredWatchpointFire);
     
    37773777}
    37783778
    3779 void JSObject::shiftButterflyAfterFlattening(const GCSafeConcurrentJSCellLocker&, VM& vm, Structure* structure, size_t outOfLineCapacityAfter)
     3779void JSObject::shiftButterflyAfterFlattening(const GCSafeConcurrentJSLocker&, VM& vm, Structure* structure, size_t outOfLineCapacityAfter)
    37803780{
    37813781    // This could interleave visitChildren because some old structure could have been a non
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r258059 r259463  
    811811        structure(vm)->flattenDictionaryStructure(vm, this);
    812812    }
    813     void shiftButterflyAfterFlattening(const GCSafeConcurrentJSCellLocker&, VM&, Structure*, size_t outOfLineCapacityAfter);
     813    void shiftButterflyAfterFlattening(const GCSafeConcurrentJSLocker&, VM&, Structure* structure, size_t outOfLineCapacityAfter);
    814814
    815815    JSGlobalObject* globalObject() const
     
    13271327inline JSValue JSObject::getDirectConcurrently(Structure* structure, PropertyOffset offset) const
    13281328{
    1329     ConcurrentJSCellLocker locker(structure->cellLock());
     1329    ConcurrentJSLocker locker(structure->lock());
    13301330    if (!structure->isValidOffset(offset))
    13311331        return { };
  • trunk/Source/JavaScriptCore/runtime/JSObjectInlines.h

    r258059 r259463  
    217217    structure->addPropertyWithoutTransition(
    218218        vm, propertyName, attributes,
    219         [&](const GCSafeConcurrentJSCellLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
     219        [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
    220220            unsigned newOutOfLineCapacity = Structure::outOfLineCapacity(newMaxOffset);
    221221            if (newOutOfLineCapacity != oldOutOfLineCapacity) {
  • trunk/Source/JavaScriptCore/runtime/JSType.cpp

    r257201 r259463  
    4545    CASE(SymbolType)
    4646    CASE(BigIntType)
    47     CASE(StructureRareDataType)
    4847    CASE(CustomGetterSetterType)
    4948    CASE(APIValueWrapperType)
  • trunk/Source/JavaScriptCore/runtime/JSType.h

    r257270 r259463  
    3131    SymbolType,
    3232
    33     StructureRareDataType,
    3433    GetterSetterType,
    3534    CustomGetterSetterType,
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r257399 r259463  
    9292    if (isUsingSingleSlot()) {
    9393        Structure* transition = singleTransition();
    94         return transition && transition->transitionPropertyName() == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition;
     94        return transition && transition->m_transitionPropertyName == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition;
    9595    }
    9696    return map()->get(StructureTransitionTable::Hash::Key(rep, attributes, isAddition));
     
    101101    if (isUsingSingleSlot()) {
    102102        Structure* transition = singleTransition();
    103         return (transition && transition->transitionPropertyName() == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition) ? transition : nullptr;
     103        return (transition && transition->m_transitionPropertyName == rep && transition->transitionPropertyAttributes() == attributes && transition->isPropertyDeletionTransition() == !isAddition) ? transition : 0;
    104104    }
    105105    return map()->get(StructureTransitionTable::Hash::Key(rep, attributes, isAddition));
     
    124124
    125125    // Add the structure to the map.
    126     map()->set(StructureTransitionTable::Hash::Key(structure->transitionPropertyName(), structure->transitionPropertyAttributes(), !structure->isPropertyDeletionTransition()), structure);
     126    map()->set(StructureTransitionTable::Hash::Key(structure->m_transitionPropertyName.get(), structure->transitionPropertyAttributes(), !structure->isPropertyDeletionTransition()), structure);
    127127}
    128128
     
    143143            case 0:
    144144                ++numberLeaf;
    145                 if (!structure->previousID(structure->vm()))
     145                if (!structure->previousID())
    146146                    ++numberSingletons;
    147147                break;
     
    152152        }
    153153
    154         if (PropertyTable* table = structure->propertyTableUnsafeOrNull()) {
     154        if (PropertyTable* table = structure->propertyTableOrNull()) {
    155155            ++numberWithPropertyMaps;
    156156            totalPropertyMapsSize += table->sizeInMemory();
     
    175175    : JSCell(vm, vm.structureStructure.get())
    176176    , m_blob(vm.heap.structureIDTable().allocateID(this), indexingType, typeInfo)
     177    , m_outOfLineTypeFlags(typeInfo.outOfLineTypeFlags())
     178    , m_inlineCapacity(inlineCapacity)
     179    , m_bitField(0)
    177180    , m_globalObject(vm, this, globalObject, WriteBarrier<JSGlobalObject>::MayBeNull)
    178181    , m_prototype(vm, this, prototype)
     182    , m_classInfo(classInfo)
    179183    , m_transitionWatchpointSet(IsWatched)
    180 {
    181     setInlineCapacity(inlineCapacity);
    182     setClassInfo(classInfo);
     184    , m_propertyHash(0)
     185{
    183186    setDictionaryKind(NoneDictionaryKind);
    184187    setIsPinnedPropertyTable(false);
     
    198201    setTransitionOffset(vm, invalidOffset);
    199202    setMaxOffset(vm, invalidOffset);
    200     setOutOfLineTypeFlags(typeInfo.outOfLineTypeFlags());
    201 
     203 
    202204    ASSERT(inlineCapacity <= JSFinalObject::maxInlineCapacity());
    203205    ASSERT(static_cast<PropertyOffset>(inlineCapacity) < firstOutOfLineOffset);
    204206    ASSERT(!hasRareData());
    205     ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !this->classInfo()->hasStaticSetterOrReadonlyProperties());
    206     ASSERT(hasGetterSetterProperties() || !this->classInfo()->hasStaticSetterOrReadonlyProperties());
    207     ASSERT(!this->typeInfo().overridesGetCallData() || this->classInfo()->methodTable.getCallData != &JSCell::getCallData);
     207    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
     208    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
     209    ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData);
    208210}
    209211
     
    212214Structure::Structure(VM& vm)
    213215    : JSCell(CreatingEarlyCell)
     216    , m_inlineCapacity(0)
     217    , m_bitField(0)
    214218    , m_prototype(vm, this, jsNull())
     219    , m_classInfo(info())
    215220    , m_transitionWatchpointSet(IsWatched)
    216 {
    217     setInlineCapacity(0);
    218     setClassInfo(info());
     221    , m_propertyHash(0)
     222{
    219223    setDictionaryKind(NoneDictionaryKind);
    220224    setIsPinnedPropertyTable(false);
    221     setHasGetterSetterProperties(classInfo()->hasStaticSetterOrReadonlyProperties());
     225    setHasGetterSetterProperties(m_classInfo->hasStaticSetterOrReadonlyProperties());
    222226    setHasCustomGetterSetterProperties(false);
    223     setHasReadOnlyOrGetterSetterPropertiesExcludingProto(classInfo()->hasStaticSetterOrReadonlyProperties());
     227    setHasReadOnlyOrGetterSetterPropertiesExcludingProto(m_classInfo->hasStaticSetterOrReadonlyProperties());
    224228    setHasUnderscoreProtoPropertyExcludingOriginalProto(false);
    225229    setIsQuickPropertyAccessAllowedForEnumeration(true);
     
    237241    TypeInfo typeInfo = TypeInfo(CellType, StructureFlags);
    238242    m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), 0, typeInfo);
    239     setOutOfLineTypeFlags(typeInfo.outOfLineTypeFlags());
    240 
    241     ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !classInfo()->hasStaticSetterOrReadonlyProperties());
    242     ASSERT(hasGetterSetterProperties() || !classInfo()->hasStaticSetterOrReadonlyProperties());
    243     ASSERT(!this->typeInfo().overridesGetCallData() || classInfo()->methodTable.getCallData != &JSCell::getCallData);
     243    m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
     244
     245    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
     246    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
     247    ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData);
    244248}
    245249
    246250Structure::Structure(VM& vm, Structure* previous, DeferredStructureTransitionWatchpointFire* deferred)
    247251    : JSCell(vm, vm.structureStructure.get())
    248 #if CPU(ADDRESS64)
    249     , m_propertyHashAndSeenProperties(previous->m_propertyHashAndSeenProperties)
    250 #else
     252    , m_inlineCapacity(previous->m_inlineCapacity)
     253    , m_bitField(0)
     254    , m_prototype(vm, this, previous->m_prototype.get())
     255    , m_classInfo(previous->m_classInfo)
     256    , m_transitionWatchpointSet(IsWatched)
    251257    , m_propertyHash(previous->m_propertyHash)
    252258    , m_seenProperties(previous->m_seenProperties)
    253 #endif
    254     , m_prototype(vm, this, previous->m_prototype.get())
    255     , m_transitionWatchpointSet(IsWatched)
    256 {
    257     setInlineCapacity(previous->inlineCapacity());
    258     setClassInfo(previous->classInfo());
     259{
    259260    setDictionaryKind(previous->dictionaryKind());
    260261    setIsPinnedPropertyTable(false);
     
    277278    TypeInfo typeInfo = previous->typeInfo();
    278279    m_blob = StructureIDBlob(vm.heap.structureIDTable().allocateID(this), previous->indexingModeIncludingHistory(), typeInfo);
    279     setOutOfLineTypeFlags(typeInfo.outOfLineTypeFlags());
     280    m_outOfLineTypeFlags = typeInfo.outOfLineTypeFlags();
    280281
    281282    ASSERT(!previous->typeInfo().structureIsImmortal());
     
    289290    if (previous->m_globalObject)
    290291        m_globalObject.set(vm, this, previous->m_globalObject.get());
    291     ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !classInfo()->hasStaticSetterOrReadonlyProperties());
    292     ASSERT(hasGetterSetterProperties() || !classInfo()->hasStaticSetterOrReadonlyProperties());
    293     ASSERT(!this->typeInfo().overridesGetCallData() || classInfo()->methodTable.getCallData != &JSCell::getCallData);
     292    ASSERT(hasReadOnlyOrGetterSetterPropertiesExcludingProto() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
     293    ASSERT(hasGetterSetterProperties() || !m_classInfo->hasStaticSetterOrReadonlyProperties());
     294    ASSERT(!this->typeInfo().overridesGetCallData() || m_classInfo->methodTable.getCallData != &JSCell::getCallData);
    294295}
    295296
     
    313314    result->addPropertyWithoutTransition(
    314315        vm, vm.propertyNames->builtinNames().polyProtoName(), static_cast<unsigned>(PropertyAttribute::DontEnum),
    315         [&](const GCSafeConcurrentJSCellLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
     316        [&] (const GCSafeConcurrentJSLocker&, PropertyOffset offset, PropertyOffset newMaxOffset) {
    316317            RELEASE_ASSERT(Structure::outOfLineCapacity(newMaxOffset) == oldOutOfLineCapacity);
    317318            RELEASE_ASSERT(offset == knownPolyProtoOffset);
     
    329330}
    330331
    331 void Structure::findStructuresAndMapForMaterialization(VM& vm, Vector<Structure*, 8>& structures, Structure*& structure, PropertyTable*& table)
     332void Structure::findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*& structure, PropertyTable*& table)
    332333{
    333334    ASSERT(structures.isEmpty());
    334     table = nullptr;
    335 
    336     for (structure = this; structure; structure = structure->previousID(vm)) {
    337         structure->cellLock().lock();
     335    table = 0;
     336
     337    for (structure = this; structure; structure = structure->previousID()) {
     338        structure->m_lock.lock();
    338339       
    339         table = structure->propertyTableUnsafeOrNull();
     340        table = structure->propertyTableOrNull();
    340341        if (table) {
    341342            // Leave the structure locked, so that the caller can do things to it atomically
     
    345346       
    346347        structures.append(structure);
    347         structure->cellLock().unlock();
     348        structure->m_lock.unlock();
    348349    }
    349350   
     
    363364    PropertyTable* table;
    364365   
    365     findStructuresAndMapForMaterialization(vm, structures, structure, table);
    366    
    367     unsigned capacity = numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity());
     366    findStructuresAndMapForMaterialization(structures, structure, table);
     367   
     368    unsigned capacity = numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity);
    368369    if (table) {
    369370        table = table->copy(vm, capacity);
    370         structure->cellLock().unlock();
     371        structure->m_lock.unlock();
    371372    } else
    372373        table = PropertyTable::create(vm, capacity);
     
    375376    // property map. We don't want getConcurrently() to see the property map in a half-baked
    376377    // state.
    377     GCSafeConcurrentJSCellLocker locker(cellLock(), vm.heap);
     378    GCSafeConcurrentJSLocker locker(m_lock, vm.heap);
    378379    if (setPropertyTable)
    379380        this->setPropertyTable(vm, table);
     
    381382    for (size_t i = structures.size(); i--;) {
    382383        structure = structures[i];
    383         UniquedStringImpl* transitionPropertyName = structure->transitionPropertyName();
    384         if (!transitionPropertyName)
     384        if (!structure->m_transitionPropertyName)
    385385            continue;
    386386        if (structure->isPropertyDeletionTransition()) {
    387             auto item = table->find(transitionPropertyName);
     387            auto item = table->find(structure->m_transitionPropertyName.get());
    388388            ASSERT(item.first);
    389389            table->remove(item);
     
    391391            continue;
    392392        }
    393         PropertyMapEntry entry(transitionPropertyName, structure->transitionOffset(), structure->transitionPropertyAttributes());
     393        PropertyMapEntry entry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes());
    394394        auto nextOffset = table->nextOffset(structure->inlineCapacity());
    395395        ASSERT_UNUSED(nextOffset, nextOffset == structure->transitionOffset());
     
    426426    }
    427427
    428     return nullptr;
     428    return 0;
    429429}
    430430
     
    437437Structure* Structure::addPropertyTransitionToExistingStructureConcurrently(Structure* structure, UniquedStringImpl* uid, unsigned attributes, PropertyOffset& offset)
    438438{
    439     ConcurrentJSCellLocker locker(structure->cellLock());
     439    ConcurrentJSLocker locker(structure->m_lock);
    440440    return addPropertyTransitionToExistingStructureImpl(structure, uid, attributes, offset);
    441441}
     
    498498   
    499499    Structure* transition = create(vm, structure, deferred);
    500     transition->setCachedPrototypeChain(vm, structure->cachedPrototypeChain());
     500
     501    transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
    501502   
    502503    // While we are adding the property, rematerializing the property table is super weird: we already
     
    510511    // protectPropertyTableWhileTransitioning before we set it to true, and then blow the table away after.
    511512    {
    512         ConcurrentJSCellLocker locker(transition->cellLock());
     513        ConcurrentJSLocker locker(transition->m_lock);
    513514        transition->setProtectPropertyTableWhileTransitioning(true);
    514         transition->setTransitionPropertyName(locker, propertyName.uid());
    515515    }
    516516
    517517    transition->m_blob.setIndexingModeIncludingHistory(structure->indexingModeIncludingHistory() & ~CopyOnWrite);
     518    transition->m_transitionPropertyName = propertyName.uid();
    518519    transition->setTransitionPropertyAttributes(attributes);
    519520    transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm));
     
    530531    checkOffset(transition->transitionOffset(), transition->inlineCapacity());
    531532    {
    532         GCSafeConcurrentJSCellLocker locker(structure->cellLock(), vm.heap);
     533        GCSafeConcurrentJSLocker locker(structure->m_lock, vm.heap);
    533534        structure->m_transitionTable.add(vm, transition);
    534535    }
     
    578579    if (structure->getConcurrently(propertyName.uid(), attributes) == invalidOffset)
    579580        return nullptr;
    580     ConcurrentJSCellLocker locker(structure->cellLock());
     581    ConcurrentJSLocker locker(structure->m_lock);
    581582    return removePropertyTransitionFromExistingStructureImpl(structure, propertyName, attributes, offset);
    582583}
     
    591592
    592593    int transitionCount = 0;
    593     for (auto* s = structure; s && transitionCount <= s_maxTransitionLength; s = s->previousID(vm))
     594    for (auto* s = structure; s && transitionCount <= s_maxTransitionLength; s = s->previousID())
    594595        ++transitionCount;
    595596
     
    603604
    604605    Structure* transition = create(vm, structure, deferred);
    605     transition->setCachedPrototypeChain(vm, structure->cachedPrototypeChain());
     606    transition->m_cachedPrototypeChain.setMayBeNull(vm, transition, structure->m_cachedPrototypeChain.get());
    606607
    607608    // While we are deleting the property, we need to make sure the table is not cleared.
    608609    {
    609         ConcurrentJSCellLocker locker(transition->cellLock());
     610        ConcurrentJSLocker locker(transition->m_lock);
    610611        transition->setProtectPropertyTableWhileTransitioning(true);
    611         transition->setTransitionPropertyName(locker, propertyName.uid());
    612612    }
    613613
    614614    transition->m_blob.setIndexingModeIncludingHistory(structure->indexingModeIncludingHistory() & ~CopyOnWrite);
     615    transition->m_transitionPropertyName = propertyName.uid();
    615616    transition->setPropertyTable(vm, structure->takePropertyTableOrCloneIfPinned(vm));
    616617    transition->setMaxOffset(vm, structure->maxOffset());
     
    628629    checkOffset(transition->transitionOffset(), transition->inlineCapacity());
    629630    {
    630         GCSafeConcurrentJSCellLocker locker(structure->cellLock(), vm.heap);
     631        GCSafeConcurrentJSLocker locker(structure->m_lock, vm.heap);
    631632        structure->m_transitionTable.add(vm, transition);
    632633    }
     
    646647
    647648    PropertyTable* table = structure->copyPropertyTableForPinning(vm);
    648     transition->pin(holdLock(transition->cellLock()), vm, table);
     649    transition->pin(holdLock(transition->m_lock), vm, table);
    649650    transition->setMaxOffset(vm, structure->maxOffset());
    650651   
     
    659660
    660661        PropertyTable* table = structure->copyPropertyTableForPinning(vm);
    661         transition->pin(holdLock(transition->cellLock()), vm, table);
     662        transition->pin(holdLock(transition->m_lock), vm, table);
    662663        transition->setMaxOffset(vm, structure->maxOffset());
    663664       
     
    681682
    682683    PropertyTable* table = structure->copyPropertyTableForPinning(vm);
    683     transition->pin(holdLock(transition->cellLock()), vm, table);
     684    transition->pin(holdLock(transition->m_lock), vm, table);
    684685    transition->setMaxOffset(vm, structure->maxOffset());
    685686    transition->setDictionaryKind(kind);
     
    717718PropertyTable* Structure::takePropertyTableOrCloneIfPinned(VM& vm)
    718719{
    719     // This function must always return a property table. It can't return null.
    720     PropertyTable* result = propertyTableUnsafeOrNull();
     720    // This must always return a property table. It can't return null.
     721    PropertyTable* result = propertyTableOrNull();
    721722    if (result) {
    722723        if (isPinnedPropertyTable())
    723724            return result->copy(vm, result->size() + 1);
    724         ConcurrentJSCellLocker locker(cellLock());
     725        ConcurrentJSLocker locker(m_lock);
    725726        setPropertyTable(vm, nullptr);
    726727        return result;
     
    759760
    760761        PropertyTable* table = structure->copyPropertyTableForPinning(vm);
    761         transition->pinForCaching(holdLock(transition->cellLock()), vm, table);
     762        transition->pinForCaching(holdLock(transition->m_lock), vm, table);
    762763        transition->setMaxOffset(vm, structure->maxOffset());
    763764       
    764         table = transition->propertyTableUnsafeOrNull();
     765        table = transition->propertyTableOrNull();
    765766        RELEASE_ASSERT(table);
    766767        for (auto& entry : *table) {
     
    777778   
    778779    if (setsReadOnlyOnNonAccessorProperties(transitionKind)
    779         && !transition->propertyTableUnsafeOrNull()->isEmpty())
     780        && !transition->propertyTableOrNull()->isEmpty())
    780781        transition->setHasReadOnlyOrGetterSetterPropertiesExcludingProto(true);
    781782   
    782783    if (structure->isDictionary()) {
    783784        PropertyTable* table = transition->ensurePropertyTable(vm);
    784         transition->pin(holdLock(transition->cellLock()), vm, table);
     785        transition->pin(holdLock(transition->m_lock), vm, table);
    785786    } else {
    786         auto locker = holdLock(structure->cellLock());
     787        auto locker = holdLock(structure->m_lock);
    787788        structure->m_transitionTable.add(vm, transition);
    788789    }
     
    836837    ASSERT(object->structure(vm) == this);
    837838   
    838     GCSafeConcurrentJSCellLocker locker(cellLock(), vm.heap);
     839    GCSafeConcurrentJSLocker locker(m_lock, vm.heap);
    839840   
    840841    object->setStructureIDDirectly(nuke(id()));
     
    843844    size_t beforeOutOfLineCapacity = this->outOfLineCapacity();
    844845    if (isUncacheableDictionary()) {
    845         PropertyTable* table = propertyTableUnsafeOrNull();
     846        PropertyTable* table = propertyTableOrNull();
    846847        ASSERT(table);
    847848
     
    857858        for (PropertyTable::iterator iter = table->begin(); iter != end; ++iter, ++i) {
    858859            values[i] = object->getDirect(iter->offset);
    859             offset = iter->offset = offsetForPropertyNumber(i, inlineCapacity());
     860            offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity);
    860861        }
    861862        setMaxOffset(vm, offset);
     
    864865        // Copies in our values to their compacted locations.
    865866        for (unsigned i = 0; i < propertyCount; i++)
    866             object->putDirect(vm, offsetForPropertyNumber(i, inlineCapacity()), values[i]);
     867            object->putDirect(vm, offsetForPropertyNumber(i, m_inlineCapacity), values[i]);
    867868
    868869        table->clearDeletedOffsets();
     
    910911}
    911912
    912 void Structure::pin(const AbstractLocker& locker, VM& vm, PropertyTable* table)
     913void Structure::pin(const AbstractLocker&, VM& vm, PropertyTable* table)
    913914{
    914915    setIsPinnedPropertyTable(true);
    915916    setPropertyTable(vm, table);
    916917    clearPreviousID();
    917     setTransitionPropertyName(locker, nullptr);
    918 }
    919 
    920 void Structure::pinForCaching(const AbstractLocker& locker, VM& vm, PropertyTable* table)
     918    m_transitionPropertyName = nullptr;
     919}
     920
     921void Structure::pinForCaching(const AbstractLocker&, VM& vm, PropertyTable* table)
    921922{
    922923    setIsPinnedPropertyTable(true);
    923924    setPropertyTable(vm, table);
    924     setTransitionPropertyName(locker, nullptr);
     925    m_transitionPropertyName = nullptr;
    925926}
    926927
     
    928929{
    929930    ASSERT(!hasRareData());
    930     StructureRareData* rareData = StructureRareData::create(vm, cachedPrototypeChain());
     931    StructureRareData* rareData = StructureRareData::create(vm, previousID());
    931932    WTF::storeStoreFence();
    932 #if CPU(ADDRESS64)
    933     m_inlineCapacityAndCachedPrototypeChainOrRareData.setPointer(rareData);
    934     vm.heap.writeBarrier(this, rareData);
    935 #else
    936     m_cachedPrototypeChainOrRareData.set(vm, this, rareData);
    937 #endif
     933    m_previousOrRareData.set(vm, this, rareData);
    938934    ASSERT(hasRareData());
    939935}
     
    949945    if (!hasRareData())
    950946        allocateRareData(vm);
    951     ConcurrentJSCellLocker locker(cellLock());
     947    ConcurrentJSLocker locker(m_lock);
    952948    StructureRareData* rareData = this->rareData();
    953949    if (!rareData->m_replacementWatchpointSets) {
     
    10191015PropertyTable* Structure::copyPropertyTableForPinning(VM& vm)
    10201016{
    1021     if (PropertyTable* table = propertyTableUnsafeOrNull())
     1017    if (PropertyTable* table = propertyTableOrNull())
    10221018        return PropertyTable::clone(vm, *table);
    10231019    bool setPropertyTable = false;
     
    10591055    return add<ShouldPin::No>(
    10601056        vm, propertyName, attributes,
    1061         [this, &vm](const GCSafeConcurrentJSCellLocker&, PropertyOffset, PropertyOffset newMaxOffset) {
     1057        [this, &vm] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset newMaxOffset) {
    10621058            setMaxOffset(vm, newMaxOffset);
    10631059        });
     
    10661062PropertyOffset Structure::remove(VM& vm, PropertyName propertyName)
    10671063{
    1068     return remove<ShouldPin::No>(vm, propertyName, [this, &vm](const GCSafeConcurrentJSCellLocker&, PropertyOffset, PropertyOffset newMaxOffset) {
     1064    return remove<ShouldPin::No>(vm, propertyName, [this, &vm] (const GCSafeConcurrentJSLocker&, PropertyOffset, PropertyOffset newMaxOffset) {
    10691065        setMaxOffset(vm, newMaxOffset);
    10701066    });
     
    11371133    Base::visitChildren(thisObject, visitor);
    11381134   
    1139     ConcurrentJSCellLocker locker(thisObject->cellLock());
     1135    ConcurrentJSLocker locker(thisObject->m_lock);
    11401136   
    11411137    visitor.append(thisObject->m_globalObject);
    1142     visitor.append(thisObject->m_prototype);
    1143     visitor.appendUnbarriered(thisObject->previousID(visitor.vm()));
    1144     visitor.appendUnbarriered(thisObject->cachedPrototypeChainOrRareData());
     1138    if (!thisObject->isObject())
     1139        thisObject->m_cachedPrototypeChain.clear();
     1140    else {
     1141        visitor.append(thisObject->m_prototype);
     1142        visitor.append(thisObject->m_cachedPrototypeChain);
     1143    }
     1144    visitor.append(thisObject->m_previousOrRareData);
    11451145
    11461146    if (thisObject->isPinnedPropertyTable() || thisObject->protectPropertyTableWhileTransitioning()) {
    11471147        // NOTE: This can interleave in pin(), in which case it may see a null property table.
    11481148        // That's fine, because then the barrier will fire and we will scan this again.
    1149         visitor.appendUnbarriered(thisObject->propertyTableUnsafeOrNull());
     1149        visitor.append(thisObject->m_propertyTableUnsafe);
    11501150    } else if (visitor.isAnalyzingHeap())
    1151         visitor.appendUnbarriered(thisObject->propertyTableUnsafeOrNull());
    1152     else if (thisObject->propertyTableUnsafeOrNull())
    1153         thisObject->clearPropertyTable();
     1151        visitor.append(thisObject->m_propertyTableUnsafe);
     1152    else if (thisObject->m_propertyTableUnsafe)
     1153        thisObject->m_propertyTableUnsafe.clear();
    11541154}
    11551155
     
    13071307        return false;
    13081308
    1309     StructureChain* structureChain = cachedPrototypeChain();
     1309    StructureChain* structureChain = m_cachedPrototypeChain.get();
    13101310    ASSERT(structureChain);
    13111311    StructureID* currentStructureID = structureChain->head();
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r258427 r259463  
    4444#include "Watchpoint.h"
    4545#include "WriteBarrierInlines.h"
    46 #include <wtf/CompactRefPtrTuple.h>
    4746#include <wtf/PrintStream.h>
    4847
     
    262261        return typeInfo().getOwnPropertySlotIsImpure();
    263262    }
    264 
    265     TypeInfo::OutOfLineTypeFlags outOfLineTypeFlags() const
    266     {
    267 #if CPU(ADDRESS64)
    268         return m_outOfLineTypeFlagsAndPropertyTableUnsafe.type();
    269 #else
    270         return m_outOfLineTypeFlags;
    271 #endif
    272     }
    273263   
    274264    // Type accessors.
    275     TypeInfo typeInfo() const { return m_blob.typeInfo(outOfLineTypeFlags()); }
     265    TypeInfo typeInfo() const { return m_blob.typeInfo(m_outOfLineTypeFlags); }
    276266    bool isObject() const { return typeInfo().isObject(); }
    277267
     
    328318    bool hasRareData() const
    329319    {
    330         return isRareData(cachedPrototypeChainOrRareData());
     320        return isRareData(m_previousOrRareData.get());
    331321    }
    332322
     
    334324    {
    335325        ASSERT(hasRareData());
    336         return static_cast<StructureRareData*>(cachedPrototypeChainOrRareData());
     326        return static_cast<StructureRareData*>(m_previousOrRareData.get());
    337327    }
    338328
     
    340330    {
    341331        ASSERT(hasRareData());
    342         return static_cast<const StructureRareData*>(cachedPrototypeChainOrRareData());
     332        return static_cast<const StructureRareData*>(m_previousOrRareData.get());
    343333    }
    344334
    345335    const StructureRareData* rareDataConcurrently() const
    346336    {
    347         JSCell* cell = cachedPrototypeChainOrRareData();
     337        JSCell* cell = m_previousOrRareData.get();
    348338        if (isRareData(cell))
    349339            return static_cast<StructureRareData*>(cell);
     
    358348    }
    359349   
    360     Structure* previousID(VM& vm) const
    361     {
    362         if (!m_previousID)
    363             return nullptr;
    364         return vm.getStructure(m_previousID);
     350    Structure* previousID() const
     351    {
     352        ASSERT(structure()->classInfo() == info());
     353        // This is so written because it's used concurrently. We only load from m_previousOrRareData
     354        // once, and this load is guaranteed atomic.
     355        JSCell* cell = m_previousOrRareData.get();
     356        if (isRareData(cell))
     357            return static_cast<StructureRareData*>(cell)->previousID();
     358        return static_cast<Structure*>(cell);
    365359    }
    366360    bool transitivelyTransitionedFrom(Structure* structureToFind);
     
    368362    PropertyOffset maxOffset() const
    369363    {
    370 #if CPU(ADDRESS64)
    371         uint16_t maxOffset = m_maxOffsetAndTransitionPropertyName.type();
    372 #else
    373364        uint16_t maxOffset = m_maxOffset;
    374 #endif
    375365        if (maxOffset == shortInvalidOffset)
    376366            return invalidOffset;
     
    382372    void setMaxOffset(VM& vm, PropertyOffset offset)
    383373    {
    384         ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
    385         auto commit = [&](uint16_t value) {
    386 #if CPU(ADDRESS64)
    387             m_maxOffsetAndTransitionPropertyName.setType(value);
    388 #else
    389             m_maxOffset = value;
    390 #endif
    391         };
    392 
    393         if (offset == invalidOffset) {
    394             commit(shortInvalidOffset);
    395             return;
     374        if (offset == invalidOffset)
     375            m_maxOffset = shortInvalidOffset;
     376        else if (offset < useRareDataFlag && offset < shortInvalidOffset)
     377            m_maxOffset = offset;
     378        else if (m_maxOffset == useRareDataFlag)
     379            rareData()->m_maxOffset = offset;
     380        else {
     381            ensureRareData(vm)->m_maxOffset = offset;
     382            WTF::storeStoreFence();
     383            m_maxOffset = useRareDataFlag;
    396384        }
    397         if (offset < useRareDataFlag && offset < shortInvalidOffset) {
    398             commit(offset);
    399             return;
    400         }
    401 #if CPU(ADDRESS64)
    402         uint16_t maxOffset = m_maxOffsetAndTransitionPropertyName.type();
    403 #else
    404         uint16_t maxOffset = m_maxOffset;
    405 #endif
    406         if (maxOffset == useRareDataFlag) {
    407             rareData()->m_maxOffset = offset;
    408             return;
    409         }
    410 
    411         ensureRareData(vm)->m_maxOffset = offset;
    412         WTF::storeStoreFence();
    413         commit(useRareDataFlag);
    414385    }
    415386
    416387    PropertyOffset transitionOffset() const
    417388    {
    418 #if CPU(ADDRESS64)
    419         uint16_t transitionOffset = m_transitionOffsetAndClassInfo.type();
    420 #else
    421389        uint16_t transitionOffset = m_transitionOffset;
    422 #endif
    423390        if (transitionOffset == shortInvalidOffset)
    424391            return invalidOffset;
     
    430397    void setTransitionOffset(VM& vm, PropertyOffset offset)
    431398    {
    432         ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
    433         auto commit = [&](uint16_t value) {
    434 #if CPU(ADDRESS64)
    435             m_transitionOffsetAndClassInfo.setType(value);
    436 #else
    437             m_transitionOffset = value;
    438 #endif
    439         };
    440 
    441         if (offset == invalidOffset) {
    442             commit(shortInvalidOffset);
    443             return;
     399        if (offset == invalidOffset)
     400            m_transitionOffset = shortInvalidOffset;
     401        else if (offset < useRareDataFlag && offset < shortInvalidOffset)
     402            m_transitionOffset = offset;
     403        else if (m_transitionOffset == useRareDataFlag)
     404            rareData()->m_transitionOffset = offset;
     405        else {
     406            ensureRareData(vm)->m_transitionOffset = offset;
     407            WTF::storeStoreFence();
     408            m_transitionOffset = useRareDataFlag;
    444409        }
    445         if (offset < useRareDataFlag && offset < shortInvalidOffset) {
    446             commit(offset);
    447             return;
    448         }
    449 #if CPU(ADDRESS64)
    450         uint16_t transitionOffset = m_transitionOffsetAndClassInfo.type();
    451 #else
    452         uint16_t transitionOffset = m_transitionOffset;
    453 #endif
    454         if (transitionOffset == useRareDataFlag) {
    455             rareData()->m_transitionOffset = offset;
    456             return;
    457         }
    458 
    459         ensureRareData(vm)->m_transitionOffset = offset;
    460         WTF::storeStoreFence();
    461         commit(useRareDataFlag);
    462410    }
    463411
     
    495443        return outOfLineSize(maxOffset());
    496444    }
    497     bool hasInlineStorage() const { return !!inlineCapacity(); }
     445    bool hasInlineStorage() const
     446    {
     447        return !!m_inlineCapacity;
     448    }
    498449    unsigned inlineCapacity() const
    499450    {
    500 #if CPU(ADDRESS64)
    501         return static_cast<uint8_t>(m_inlineCapacityAndCachedPrototypeChainOrRareData.type());
    502 #else
    503451        return m_inlineCapacity;
    504 #endif
    505452    }
    506453    unsigned inlineSize() const
    507454    {
    508         return std::min<unsigned>(maxOffset() + 1, inlineCapacity());
     455        return std::min<unsigned>(maxOffset() + 1, m_inlineCapacity);
    509456    }
    510457    unsigned totalStorageCapacity() const
     
    518465        return JSC::isValidOffset(offset)
    519466            && offset <= maxOffset()
    520             && (offset < static_cast<int>(inlineCapacity()) || offset >= firstOutOfLineOffset);
     467            && (offset < m_inlineCapacity || offset >= firstOutOfLineOffset);
    521468    }
    522469
    523470    bool hijacksIndexingHeader() const
    524471    {
    525         return isTypedView(classInfo()->typedArrayStorageType);
     472        return isTypedView(m_classInfo->typedArrayStorageType);
    526473    }
    527474   
     
    593540    void setObjectToStringValue(JSGlobalObject*, VM&, JSString* value, PropertySlot toStringTagSymbolSlot);
    594541
    595     const ClassInfo* classInfo() const
    596     {
    597 #if CPU(ADDRESS64)
    598         return m_transitionOffsetAndClassInfo.pointer();
    599 #else
    600         return m_classInfo;
    601 #endif
    602     }
     542    const ClassInfo* classInfo() const { return m_classInfo; }
    603543
    604544    static ptrdiff_t structureIDOffset()
     
    617557    }
    618558
    619     static ptrdiff_t offsetOfClassInfo()
    620     {
    621 #if CPU(ADDRESS64)
    622         return OBJECT_OFFSETOF(Structure, m_transitionOffsetAndClassInfo);
    623 #else
     559    static ptrdiff_t classInfoOffset()
     560    {
    624561        return OBJECT_OFFSETOF(Structure, m_classInfo);
    625 #endif
    626     }
    627 
     562    }
     563       
    628564    static ptrdiff_t indexingModeIncludingHistoryOffset()
    629565    {
    630566        return OBJECT_OFFSETOF(Structure, m_blob) + StructureIDBlob::indexingModeIncludingHistoryOffset();
    631567    }
    632 
    633 #if CPU(LITTLE_ENDIAN)
    634     static ptrdiff_t offsetOfInlineCapacity()
    635     {
    636 #if CPU(ADDRESS64)
    637         return OBJECT_OFFSETOF(Structure, m_inlineCapacityAndCachedPrototypeChainOrRareData) + CompactPointerTuple<JSCell*, uint16_t>::offsetOfType();
    638 #else
     568   
     569    static ptrdiff_t propertyTableUnsafeOffset()
     570    {
     571        return OBJECT_OFFSETOF(Structure, m_propertyTableUnsafe);
     572    }
     573
     574    static ptrdiff_t inlineCapacityOffset()
     575    {
    639576        return OBJECT_OFFSETOF(Structure, m_inlineCapacity);
    640 #endif
    641 
    642     }
    643 #endif
    644 
    645     static ptrdiff_t offsetOfCachedPrototypeChainOrRareData()
    646     {
    647 #if CPU(ADDRESS64)
    648         return OBJECT_OFFSETOF(Structure, m_inlineCapacityAndCachedPrototypeChainOrRareData);
    649 #else
    650         return OBJECT_OFFSETOF(Structure, m_cachedPrototypeChainOrRareData);
    651 #endif
     577    }
     578
     579    static ptrdiff_t previousOrRareDataOffset()
     580    {
     581        return OBJECT_OFFSETOF(Structure, m_previousOrRareData);
    652582    }
    653583
     
    728658    static void dumpContextHeader(PrintStream&);
    729659   
     660    ConcurrentJSLock& lock() { return m_lock; }
     661
     662    unsigned propertyHash() const { return m_propertyHash; }
     663
    730664    static bool shouldConvertToPolyProto(const Structure* a, const Structure* b);
    731 
    732     UniquedStringImpl* transitionPropertyName() const
    733     {
    734 #if CPU(ADDRESS64)
    735         return m_maxOffsetAndTransitionPropertyName.pointer();
    736 #else
    737         return m_transitionPropertyName.get();
    738 #endif
    739     }
    740665
    741666    struct PropertyHashEntry {
     
    748673
    749674private:
    750     bool ruleOutUnseenProperty(UniquedStringImpl*) const;
    751 #if CPU(ADDRESS64)
    752     // As a propertyHash, 64bit environment uses 16bit property-hash + seenProperties set.
    753     uintptr_t propertyHash() const { return m_propertyHashAndSeenProperties.data(); }
    754 #else
    755     uint32_t propertyHash() const { return m_propertyHash; }
    756 #endif
    757     TinyBloomFilter seenProperties() const;
    758     void addPropertyHashAndSeenProperty(unsigned, UniquedStringImpl*);
    759 
    760     void setTransitionPropertyName(const AbstractLocker&, UniquedStringImpl* transitionPropertyName)
    761     {
    762 #if CPU(ADDRESS64)
    763         m_maxOffsetAndTransitionPropertyName.setPointer(transitionPropertyName);
    764 #else
    765         m_transitionPropertyName = transitionPropertyName;
    766 #endif
    767     }
    768 
    769675    typedef enum {
    770676        NoneDictionaryKind = 0,
     
    783689        m_bitField &= ~(s_##lowerName##Mask << offset);\
    784690        m_bitField |= (newValue & s_##lowerName##Mask) << offset;\
    785         ASSERT(newValue == lowerName());\
    786691    }
    787692
     
    791696    DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4);
    792697    DEFINE_BITFIELD(bool, isQuickPropertyAccessAllowedForEnumeration, IsQuickPropertyAccessAllowedForEnumeration, 1, 5);
    793     DEFINE_BITFIELD(unsigned, transitionPropertyAttributes, TransitionPropertyAttributes, 8, 6);
    794     DEFINE_BITFIELD(bool, didPreventExtensions, DidPreventExtensions, 1, 14);
    795     DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 15);
    796     DEFINE_BITFIELD(bool, staticPropertiesReified, StaticPropertiesReified, 1, 16);
    797     DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 17);
    798     DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 18);
    799     DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 19);
    800     DEFINE_BITFIELD(bool, transitionWatchpointIsLikelyToBeFired, TransitionWatchpointIsLikelyToBeFired, 1, 20);
    801     DEFINE_BITFIELD(bool, hasBeenDictionary, HasBeenDictionary, 1, 21);
    802     DEFINE_BITFIELD(bool, protectPropertyTableWhileTransitioning, ProtectPropertyTableWhileTransitioning, 1, 22);
    803     DEFINE_BITFIELD(bool, hasUnderscoreProtoPropertyExcludingOriginalProto, HasUnderscoreProtoPropertyExcludingOriginalProto, 1, 23);
    804     DEFINE_BITFIELD(bool, isPropertyDeletionTransition, IsPropertyDeletionTransition, 1, 24);
     698    DEFINE_BITFIELD(unsigned, transitionPropertyAttributes, TransitionPropertyAttributes, 14, 6);
     699    DEFINE_BITFIELD(bool, didPreventExtensions, DidPreventExtensions, 1, 20);
     700    DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 21);
     701    DEFINE_BITFIELD(bool, staticPropertiesReified, StaticPropertiesReified, 1, 22);
     702    DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 23);
     703    DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 24);
     704    DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 25);
     705    DEFINE_BITFIELD(bool, transitionWatchpointIsLikelyToBeFired, TransitionWatchpointIsLikelyToBeFired, 1, 26);
     706    DEFINE_BITFIELD(bool, hasBeenDictionary, HasBeenDictionary, 1, 27);
     707    DEFINE_BITFIELD(bool, protectPropertyTableWhileTransitioning, ProtectPropertyTableWhileTransitioning, 1, 28);
     708    DEFINE_BITFIELD(bool, hasUnderscoreProtoPropertyExcludingOriginalProto, HasUnderscoreProtoPropertyExcludingOriginalProto, 1, 29);
     709    DEFINE_BITFIELD(bool, isPropertyDeletionTransition, IsPropertyDeletionTransition, 1, 30);
    805710
    806711    static_assert(s_bitWidthOfTransitionPropertyAttributes <= sizeof(TransitionPropertyAttributes) * 8);
     
    822727    // non-null structure, it will also lock the structure that it returns; it is your job
    823728    // to unlock it.
    824     void findStructuresAndMapForMaterialization(VM&, Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);
     729    void findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);
    825730   
    826731    static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind, DeferredStructureTransitionWatchpointFire* = nullptr);
     
    839744    PropertyTable* ensurePropertyTableIfNotEmpty(VM& vm)
    840745    {
    841         if (PropertyTable* result = propertyTableUnsafeOrNull())
     746        if (PropertyTable* result = m_propertyTableUnsafe.get())
    842747            return result;
    843         if (!previousID(vm))
     748        if (!previousID())
    844749            return nullptr;
    845750        return materializePropertyTable(vm);
     
    849754    PropertyTable* ensurePropertyTable(VM& vm)
    850755    {
    851         if (PropertyTable* result = propertyTableUnsafeOrNull())
     756        if (PropertyTable* result = m_propertyTableUnsafe.get())
    852757            return result;
    853758        return materializePropertyTable(vm);
    854759    }
    855760   
    856     PropertyTable* propertyTableUnsafeOrNull() const
    857     {
    858 #if CPU(ADDRESS64)
    859         return m_outOfLineTypeFlagsAndPropertyTableUnsafe.pointer();
    860 #else
     761    PropertyTable* propertyTableOrNull() const
     762    {
    861763        return m_propertyTableUnsafe.get();
    862 #endif
    863764    }
    864765   
     
    867768   
    868769    void setPropertyTable(VM& vm, PropertyTable* table);
    869     void clearPropertyTable();
    870770   
    871771    PropertyTable* takePropertyTableOrCloneIfPinned(VM&);
     
    873773
    874774    void setPreviousID(VM&, Structure*);
    875     void clearPreviousID();
     775
     776    void clearPreviousID()
     777    {
     778        if (hasRareData())
     779            rareData()->clearPreviousID();
     780        else
     781            m_previousOrRareData.clear();
     782    }
    876783
    877784    int transitionCountEstimate() const
     
    879786        // Since the number of transitions is often the same as the last offset (except if there are deletes)
    880787        // we keep the size of Structure down by not storing both.
    881         return numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity());
     788        return numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity);
    882789    }
    883790
     
    890797    bool isRareData(JSCell* cell) const
    891798    {
    892         return cell && cell->type() == StructureRareDataType;
     799        return cell && cell->structureID() != structureID();
    893800    }
    894801
     
    901808    void startWatchingInternalProperties(VM&);
    902809
    903     StructureChain* cachedPrototypeChain() const;
    904     void setCachedPrototypeChain(VM&, StructureChain*);
    905 
    906     void setOutOfLineTypeFlags(TypeInfo::OutOfLineTypeFlags);
    907     void setClassInfo(const ClassInfo*);
    908     void setInlineCapacity(uint8_t);
    909 
    910     JSCell* cachedPrototypeChainOrRareData() const
    911     {
    912 #if CPU(ADDRESS64)
    913         return m_inlineCapacityAndCachedPrototypeChainOrRareData.pointer();
    914 #else
    915         return m_cachedPrototypeChainOrRareData.get();
    916 #endif
    917     }
    918 
    919810    static constexpr int s_maxTransitionLength = 64;
    920811    static constexpr int s_maxTransitionLengthForNonEvalPutById = 512;
     
    923814    // part of the object.
    924815    StructureIDBlob m_blob;
    925 
    926     // The property table pointer should be accessed through ensurePropertyTable(). During GC, m_propertyTableUnsafe field part may be set to 0 by another thread.
    927     // During a Heap Snapshot GC we avoid clearing the table so it is safe to use.
    928 #if CPU(ADDRESS64)
    929 public:
    930     static constexpr uintptr_t classInfoMask = CompactPointerTuple<const ClassInfo*, uint16_t>::pointerMask;
    931     static constexpr uintptr_t cachedPrototypeChainOrRareDataMask = CompactPointerTuple<JSCell*, uint16_t>::pointerMask;
    932 private:
    933     // Structure is one of the most frequently allocated data structure. Moreover, Structure tends to be alive a long time!
    934     // This motivates extra complicated hack which optimizes sizeof(Structure).
    935     //
    936     // We combine 16bit data and 64bit pointer into one pointer-size field to (1) save memory while (2) not losing atomic load/store.
    937     // The key here is analyzing data access patterns carefully. They are categoriezed into three types.
    938     //     1. ImmutableAfterConstruction
    939     //     2. MutableFromAnyThread
    940     //     3. MutableFromMainThread
    941     //  We assume that loading happens from any threads. Under this assumption, MutableFromAnyThread + (MutableFromMainThread / MutableFromAnyThread) is the pair which is racy.
    942     //  Other pairs works well. We carefully put assertions to setters, analyze access patterns and pick appropriate pairs in Structure fields.
    943     CompactPointerTuple<PropertyTable*, TypeInfo::OutOfLineTypeFlags> m_outOfLineTypeFlagsAndPropertyTableUnsafe; // ImmutableAfterConstruction(m_outOfLineTypeFlags) and MutableFromAnyThread(m_propertyTableUnsafe).
    944     CompactRefPtrTuple<UniquedStringImpl, uint16_t> m_maxOffsetAndTransitionPropertyName; // MutableFromMainThread(m_maxOffset) and MutableFromMainThread(m_transitionPropertyName).
    945     CompactPointerTuple<const ClassInfo*, uint16_t> m_transitionOffsetAndClassInfo; // MutableFromMainThread(m_transitionOffset) and ImmutableAfterConstruction(m_classInfo).
    946     CompactPointerTuple<JSCell*, uint16_t> m_inlineCapacityAndCachedPrototypeChainOrRareData; // ImmutableAfterConstruction(m_inlineCapacity) and MutableFromMainThread(m_cachedPrototypeChainOrRareData).
    947     CompactPointerTuple<UniquedStringImpl*, uint16_t> m_propertyHashAndSeenProperties; // MutableFromMainThread(m_propertyHash) and MutableFromMainThread(m_seenProperties).
    948 #else
    949     TypeInfo::OutOfLineTypeFlags m_outOfLineTypeFlags { 0 };
    950     uint8_t m_inlineCapacity { 0 };
    951     uint32_t m_propertyHash { 0 };
    952     uint16_t m_transitionOffset { 0 };
    953     uint16_t m_maxOffset { 0 };
    954     WriteBarrier<PropertyTable> m_propertyTableUnsafe;
    955     const ClassInfo* m_classInfo { nullptr };
    956     WriteBarrier<JSCell> m_cachedPrototypeChainOrRareData;
    957     uintptr_t m_seenProperties { 0 };
    958     RefPtr<UniquedStringImpl> m_transitionPropertyName;
    959 #endif
    960     StructureID m_previousID { 0 };
    961     uint32_t m_bitField { 0 };
    962 
    963     StructureTransitionTable m_transitionTable;
     816    TypeInfo::OutOfLineTypeFlags m_outOfLineTypeFlags;
     817
     818    uint8_t m_inlineCapacity;
     819
     820    ConcurrentJSLock m_lock;
     821
     822    uint32_t m_bitField;
     823
    964824    WriteBarrier<JSGlobalObject> m_globalObject;
    965825    WriteBarrier<Unknown> m_prototype;
     826    mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
     827
     828    WriteBarrier<JSCell> m_previousOrRareData;
     829
     830    RefPtr<UniquedStringImpl> m_transitionPropertyName;
     831
     832    const ClassInfo* m_classInfo;
     833
     834    StructureTransitionTable m_transitionTable;
     835
     836    // Should be accessed through ensurePropertyTable(). During GC, it may be set to 0 by another thread.
     837    // During a Heap Snapshot GC we avoid clearing the table so it is safe to use.
     838    WriteBarrier<PropertyTable> m_propertyTableUnsafe;
    966839
    967840    mutable InlineWatchpointSet m_transitionWatchpointSet;
    968841
    969842    COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
     843
     844    uint16_t m_transitionOffset;
     845    uint16_t m_maxOffset;
     846
     847    uint32_t m_propertyHash;
     848    TinyBloomFilter m_seenProperties;
    970849
    971850    friend class VMInspector;
    972851    friend class JSDollarVMHelper;
    973852};
    974 #if CPU(ADDRESS64)
    975 static_assert(sizeof(Structure) <= 96, "Do not increase sizeof(Structure), it immediately causes memory regression");
    976 #endif
    977853
    978854} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/StructureInlines.h

    r259355 r259463  
    145145    ASSERT(structure(vm)->classInfo() == info());
    146146
    147     if (ruleOutUnseenProperty(propertyName.uid()))
     147    if (m_seenProperties.ruleOut(bitwise_cast<uintptr_t>(propertyName.uid())))
    148148        return invalidOffset;
    149149
     
    160160}
    161161
    162 inline bool Structure::ruleOutUnseenProperty(UniquedStringImpl* uid) const
    163 {
    164     ASSERT(uid);
    165     return seenProperties().ruleOut(bitwise_cast<uintptr_t>(uid));
    166 }
    167 
    168 inline TinyBloomFilter Structure::seenProperties() const
    169 {
    170 #if CPU(ADDRESS64)
    171     return TinyBloomFilter(bitwise_cast<uintptr_t>(m_propertyHashAndSeenProperties.pointer()));
    172 #else
    173     return TinyBloomFilter(m_seenProperties);
    174 #endif
    175 }
    176 
    177 inline void Structure::addPropertyHashAndSeenProperty(unsigned hash, UniquedStringImpl* pointer)
    178 {
    179 #if CPU(ADDRESS64)
    180     m_propertyHashAndSeenProperties.setType(m_propertyHashAndSeenProperties.type() ^ hash);
    181     m_propertyHashAndSeenProperties.setPointer(bitwise_cast<UniquedStringImpl*>(bitwise_cast<uintptr_t>(m_propertyHashAndSeenProperties.pointer()) | bitwise_cast<uintptr_t>(pointer)));
    182 #else
    183     m_propertyHash = m_propertyHash ^ hash;
    184     m_seenProperties = bitwise_cast<uintptr_t>(pointer) | m_seenProperties;
    185 #endif
    186 }
    187 
    188162template<typename Functor>
    189163void Structure::forEachPropertyConcurrently(const Functor& functor)
     
    192166    Structure* tableStructure;
    193167    PropertyTable* table;
    194     VM& vm = this->vm();
    195    
    196     findStructuresAndMapForMaterialization(vm, structures, tableStructure, table);
     168   
     169    findStructuresAndMapForMaterialization(structures, tableStructure, table);
    197170
    198171    HashSet<UniquedStringImpl*> seenProperties;
    199172
    200     for (Structure* structure : structures) {
    201         UniquedStringImpl* transitionPropertyName = structure->transitionPropertyName();
    202         if (!transitionPropertyName || seenProperties.contains(transitionPropertyName))
     173    for (auto* structure : structures) {
     174        if (!structure->m_transitionPropertyName || seenProperties.contains(structure->m_transitionPropertyName.get()))
    203175            continue;
    204176
    205         seenProperties.add(transitionPropertyName);
     177        seenProperties.add(structure->m_transitionPropertyName.get());
    206178
    207179        if (structure->isPropertyDeletionTransition())
    208180            continue;
    209181
    210         if (!functor(PropertyMapEntry(transitionPropertyName, structure->transitionOffset(), structure->transitionPropertyAttributes()))) {
     182        if (!functor(PropertyMapEntry(structure->m_transitionPropertyName.get(), structure->transitionOffset(), structure->transitionPropertyAttributes()))) {
    211183            if (table)
    212                 tableStructure->cellLock().unlock();
     184                tableStructure->m_lock.unlock();
    213185            return;
    214186        }
     
    221193
    222194            if (!functor(entry)) {
    223                 tableStructure->cellLock().unlock();
     195                tableStructure->m_lock.unlock();
    224196                return;
    225197            }
    226198        }
    227         tableStructure->cellLock().unlock();
     199        tableStructure->m_lock.unlock();
    228200    }
    229201}
     
    280252inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
    281253{
    282     VM& vm = this->vm();
    283     for (Structure* current = this; current; current = current->previousID(vm)) {
     254    for (Structure* current = this; current; current = current->previousID()) {
    284255        if (current == structureToFind)
    285256            return true;
     
    348319}
    349320
    350 inline StructureChain* Structure::cachedPrototypeChain() const
    351 {
    352     JSCell* cell = cachedPrototypeChainOrRareData();
    353     if (isRareData(cell))
    354         return jsCast<StructureRareData*>(cell)->cachedPrototypeChain();
    355     return jsCast<StructureChain*>(cell);
    356 }
    357 
    358 inline void Structure::setCachedPrototypeChain(VM& vm, StructureChain* chain)
    359 {
    360     ASSERT(isObject());
    361     ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
    362     JSCell* cell = cachedPrototypeChainOrRareData();
    363     if (isRareData(cell)) {
    364         jsCast<StructureRareData*>(cell)->setCachedPrototypeChain(vm, chain);
    365         return;
    366     }
    367 #if CPU(ADDRESS64)
    368     m_inlineCapacityAndCachedPrototypeChainOrRareData.setPointer(chain);
    369     vm.heap.writeBarrier(this, chain);
    370 #else
    371     m_cachedPrototypeChainOrRareData.setMayBeNull(vm, this, chain);
    372 #endif
    373 }
    374 
    375321inline StructureChain* Structure::prototypeChain(VM& vm, JSGlobalObject* globalObject, JSObject* base) const
    376322{
    377     ASSERT(this->isObject());
    378323    ASSERT(base->structure(vm) == this);
    379324    // We cache our prototype chain so our clients can share it.
    380     if (!isValid(globalObject, cachedPrototypeChain(), base)) {
     325    if (!isValid(globalObject, m_cachedPrototypeChain.get(), base)) {
    381326        JSValue prototype = prototypeForLookup(globalObject, base);
    382         const_cast<Structure*>(this)->setCachedPrototypeChain(vm, StructureChain::create(vm, prototype.isNull() ? nullptr : asObject(prototype)));
    383     }
    384     return cachedPrototypeChain();
     327        m_cachedPrototypeChain.set(vm, this, StructureChain::create(vm, prototype.isNull() ? nullptr : asObject(prototype)));
     328    }
     329    return m_cachedPrototypeChain.get();
    385330}
    386331
     
    422367inline WatchpointSet* Structure::propertyReplacementWatchpointSet(PropertyOffset offset)
    423368{
    424     ConcurrentJSCellLocker locker(cellLock());
     369    ConcurrentJSLocker locker(m_lock);
    425370    if (!hasRareData())
    426371        return nullptr;
     
    443388   
    444389    unsigned totalSize = propertyTable->propertyStorageSize();
    445     unsigned inlineOverflowAccordingToTotalSize = totalSize < inlineCapacity() ? 0 : totalSize - inlineCapacity();
     390    unsigned inlineOverflowAccordingToTotalSize = totalSize < m_inlineCapacity ? 0 : totalSize - m_inlineCapacity;
    446391
    447392    auto fail = [&] (const char* description) {
     
    450395        dataLog("transitionOffset = ", transitionOffset(), "\n");
    451396        dataLog("maxOffset = ", maxOffset(), "\n");
    452         dataLog("m_inlineCapacity = ", inlineCapacity(), "\n");
     397        dataLog("m_inlineCapacity = ", m_inlineCapacity, "\n");
    453398        dataLog("propertyTable = ", RawPointer(propertyTable), "\n");
    454         dataLog("numberOfSlotsForMaxOffset = ", numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity()), "\n");
     399        dataLog("numberOfSlotsForMaxOffset = ", numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity), "\n");
    455400        dataLog("totalSize = ", totalSize, "\n");
    456401        dataLog("inlineOverflowAccordingToTotalSize = ", inlineOverflowAccordingToTotalSize, "\n");
     
    460405    };
    461406   
    462     if (numberOfSlotsForMaxOffset(maxOffset(), inlineCapacity()) != totalSize)
     407    if (numberOfSlotsForMaxOffset(maxOffset(), m_inlineCapacity) != totalSize)
    463408        fail("numberOfSlotsForMaxOffset doesn't match totalSize");
    464409    if (inlineOverflowAccordingToTotalSize != numberOfOutOfLineSlotsForMaxOffset(maxOffset()))
     
    470415ALWAYS_INLINE bool Structure::checkOffsetConsistency() const
    471416{
    472     PropertyTable* propertyTable = propertyTableUnsafeOrNull();
     417    PropertyTable* propertyTable = propertyTableOrNull();
    473418
    474419    if (!propertyTable) {
     
    511456    PropertyTable* table = ensurePropertyTable(vm);
    512457
    513     GCSafeConcurrentJSCellLocker locker(cellLock(), vm.heap);
     458    GCSafeConcurrentJSLocker locker(m_lock, vm.heap);
    514459
    515460    switch (shouldPin) {
     
    532477    auto rep = propertyName.uid();
    533478
    534     PropertyOffset newOffset = table->nextOffset(inlineCapacity());
    535 
    536     addPropertyHashAndSeenProperty(rep->existingSymbolAwareHash(), rep);
     479    PropertyOffset newOffset = table->nextOffset(m_inlineCapacity);
     480
     481    m_propertyHash = m_propertyHash ^ rep->existingSymbolAwareHash();
     482    m_seenProperties.add(bitwise_cast<uintptr_t>(rep));
    537483
    538484    auto result = table->add(PropertyMapEntry(rep, newOffset, attributes));
     
    553499{
    554500    PropertyTable* table = ensurePropertyTable(vm);
    555     GCSafeConcurrentJSCellLocker locker(cellLock(), vm.heap);
     501    GCSafeConcurrentJSLocker locker(m_lock, vm.heap);
    556502
    557503    switch (shouldPin) {
     
    603549    ASSERT(isUncacheableDictionary());
    604550    ASSERT(isPinnedPropertyTable());
    605     ASSERT(propertyTableUnsafeOrNull());
     551    ASSERT(propertyTableOrNull());
    606552   
    607553    return remove<ShouldPin::Yes>(vm, propertyName, func);
     
    621567ALWAYS_INLINE void Structure::setPropertyTable(VM& vm, PropertyTable* table)
    622568{
    623 #if CPU(ADDRESS64)
    624     m_outOfLineTypeFlagsAndPropertyTableUnsafe.setPointer(table);
    625     vm.heap.writeBarrier(this, table);
    626 #else
    627569    m_propertyTableUnsafe.setMayBeNull(vm, this, table);
    628 #endif
    629 }
    630 
    631 ALWAYS_INLINE void Structure::clearPropertyTable()
    632 {
    633 #if CPU(ADDRESS64)
    634     m_outOfLineTypeFlagsAndPropertyTableUnsafe.setPointer(nullptr);
    635 #else
    636     m_propertyTableUnsafe.clear();
    637 #endif
    638 }
    639 
    640 ALWAYS_INLINE void Structure::setOutOfLineTypeFlags(TypeInfo::OutOfLineTypeFlags outOfLineTypeFlags)
    641 {
    642 #if CPU(ADDRESS64)
    643     m_outOfLineTypeFlagsAndPropertyTableUnsafe.setType(outOfLineTypeFlags);
    644 #else
    645     m_outOfLineTypeFlags = outOfLineTypeFlags;
    646 #endif
    647 }
    648 
    649 ALWAYS_INLINE void Structure::setInlineCapacity(uint8_t inlineCapacity)
    650 {
    651 #if CPU(ADDRESS64)
    652     m_inlineCapacityAndCachedPrototypeChainOrRareData.setType(inlineCapacity);
    653 #else
    654     m_inlineCapacity = inlineCapacity;
    655 #endif
    656 }
    657 
    658 ALWAYS_INLINE void Structure::setClassInfo(const ClassInfo* classInfo)
    659 {
    660 #if CPU(ADDRESS64)
    661     m_transitionOffsetAndClassInfo.setPointer(classInfo);
    662 #else
    663     m_classInfo = classInfo;
    664 #endif
    665570}
    666571
    667572ALWAYS_INLINE void Structure::setPreviousID(VM& vm, Structure* structure)
    668573{
    669     ASSERT(structure);
    670     m_previousID = structure->id();
    671     vm.heap.writeBarrier(this, structure);
    672 }
    673 
    674 inline void Structure::clearPreviousID()
    675 {
    676     m_previousID = 0;
     574    if (hasRareData())
     575        rareData()->setPreviousID(vm, structure);
     576    else
     577        m_previousOrRareData.set(vm, this, structure);
    677578}
    678579
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp

    r257201 r259463  
    4141Structure* StructureRareData::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    4242{
    43     return Structure::create(vm, globalObject, prototype, TypeInfo(StructureRareDataType, StructureFlags), info());
     43    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
    4444}
    4545
    46 StructureRareData* StructureRareData::create(VM& vm, StructureChain* chain)
     46StructureRareData* StructureRareData::create(VM& vm, Structure* previous)
    4747{
    48     StructureRareData* rareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, chain);
     48    StructureRareData* rareData = new (NotNull, allocateCell<StructureRareData>(vm.heap)) StructureRareData(vm, previous);
    4949    rareData->finishCreation(vm);
    5050    return rareData;
     
    5656}
    5757
    58 StructureRareData::StructureRareData(VM& vm, StructureChain* chain)
     58StructureRareData::StructureRareData(VM& vm, Structure* previous)
    5959    : JSCell(vm, vm.structureRareDataStructure.get())
    6060    , m_maxOffset(invalidOffset)
    6161    , m_transitionOffset(invalidOffset)
    6262{
    63     if (chain)
    64         m_cachedPrototypeChain.set(vm, this, chain);
     63    if (previous)
     64        m_previous.set(vm, this, previous);
    6565}
    6666
     
    7171
    7272    Base::visitChildren(thisObject, visitor);
    73     visitor.append(thisObject->m_cachedPrototypeChain);
     73    visitor.append(thisObject->m_previous);
    7474    visitor.appendUnbarriered(thisObject->objectToStringValue());
    7575    visitor.append(thisObject->m_cachedPropertyNameEnumerator);
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.h

    r257201 r259463  
    3636class JSPropertyNameEnumerator;
    3737class Structure;
    38 class StructureChain;
    3938class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;
    4039class ObjectToStringAdaptiveStructureWatchpoint;
     
    5150    }
    5251
    53     static StructureRareData* create(VM&, StructureChain*);
     52    static StructureRareData* create(VM&, Structure*);
    5453
    5554    static constexpr bool needsDestruction = true;
     
    6059    static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
    6160
    62     StructureChain* cachedPrototypeChain() const
     61    Structure* previousID() const
    6362    {
    64         return m_cachedPrototypeChain.get();
     63        return m_previous.get();
    6564    }
    66     void setCachedPrototypeChain(VM&, StructureChain*);
     65    void setPreviousID(VM&, Structure*);
     66    void clearPreviousID();
    6767
    6868    JSString* objectToStringValue() const;
     
    103103    void clearObjectToStringValue();
    104104
    105     StructureRareData(VM&, StructureChain*);
     105    StructureRareData(VM&, Structure*);
    106106
    107     WriteBarrier<StructureChain> m_cachedPrototypeChain;
     107    WriteBarrier<Structure> m_previous;
    108108    WriteBarrier<JSString> m_objectToStringValue;
    109109    // FIXME: We should have some story for clearing these property names caches in GC.
  • trunk/Source/JavaScriptCore/runtime/StructureRareDataInlines.h

    r257201 r259463  
    3333namespace JSC {
    3434
    35 inline void StructureRareData::setCachedPrototypeChain(VM& vm, StructureChain* chain)
     35inline void StructureRareData::setPreviousID(VM& vm, Structure* structure)
    3636{
    37     m_cachedPrototypeChain.setMayBeNull(vm, this, chain);
     37    m_previous.set(vm, this, structure);
     38}
     39
     40inline void StructureRareData::clearPreviousID()
     41{
     42    m_previous.clear();
    3843}
    3944
  • trunk/Source/JavaScriptCore/runtime/StructureTransitionTable.h

    r257201 r259463  
    151151        struct Key {
    152152            friend struct Hash;
    153             static_assert(OS_CONSTANT(EFFECTIVE_ADDRESS_WIDTH) <= 48);
     153            static_assert(WTF_OS_CONSTANT_EFFECTIVE_ADDRESS_WIDTH <= 48);
    154154            static constexpr uintptr_t isAdditionMask = 1ULL;
    155155            static constexpr uintptr_t stringMask = ((1ULL << 48) - 1) & (~isAdditionMask);
  • trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

    r258664 r259463  
    28752875    Vector<Structure*, 8> structures;
    28762876
    2877     for (auto* structure = obj->structure(); structure; structure = structure->previousID(vm))
     2877    for (auto* structure = obj->structure(); structure; structure = structure->previousID())
    28782878        structures.append(structure);
    28792879
     
    28892889        result->push(globalObject, JSValue(structure->maxOffset()));
    28902890        RETURN_IF_EXCEPTION(scope, { });
    2891         if (auto* transitionPropertyName = structure->transitionPropertyName())
    2892             result->push(globalObject, jsString(vm, String(*transitionPropertyName)));
     2891        if (structure->m_transitionPropertyName)
     2892            result->push(globalObject, jsString(vm, String(*structure->m_transitionPropertyName)));
    28932893        else
    28942894            result->push(globalObject, jsNull());
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r257201 r259463  
    276276            stackLimitGPRIsClobbered = true;
    277277            jit.emitLoadStructure(vm, scratchGPR, scratchGPR, stackLimitGPR);
    278             jit.emitLoadClassInfoFromStructure(scratchGPR, scratchGPR);
     278            jit.loadPtr(CCallHelpers::Address(scratchGPR, Structure::classInfoOffset()), scratchGPR);
    279279
    280280            static_assert(std::is_final<WebAssemblyFunction>::value, "We do not check for subtypes below");
Note: See TracChangeset for help on using the changeset viewer.