Changeset 254464 in webkit


Ignore:
Timestamp:
Jan 13, 2020 3:55:57 PM (4 years ago)
Author:
mark.lam@apple.com
Message:

Replace uses of Box<Identifier> with a new CacheableIdentifier class.
https://bugs.webkit.org/show_bug.cgi?id=205544
<rdar://problem/58041800>

Reviewed by Saam Barati.

JSTests:

  • stress/racy-gc-cleanup-of-identifier-after-mutator-stops-running.js: Added.

Source/JavaScriptCore:

The introduction of the use of Box<Identifier> was to get around having to
ref/deref the underlying UniqedStringImpl in Identifiers from the compiler
and GC threads. However, it proves to be difficult to control when these
Box<Identifier>s get destructed, and requires that we find all the places in
the compier and GC threads where this can happen, and apply keep alive tactics
there to defer destruction of the Box<Identifier> to the mutator thread.

This patch fixes this by replacing uses of Box<Identifier> with
CacheableIdentifier, which is effectively a tagged union of a JSCell* or a
UniquedStringImpl*. The JSCell*, in this case, can be either a Symbol* or a
JSString* that is backed by an atom string. The VM runtime ensures that we'll
never try to cache an identifier from a JSCell that is not one of these. This
CacheableIdentifier can be destructed from the compiler or GC thread. Since it
doesn't hold a ref of the underlying UniquedStringImpl, it won't try to deref
it on destruction.

Instead, we'll need to visit CacheableIdentifiers during GC scans to keep the
JSCell in it alive, and that JSCell will, in turn, keep the underlying
UniquedStringImpl alive.

This patch also does the following:

  1. Add a visitAggregate() method to StructureStubInfo, PolymorphicAccess, and AccessCase to visit the CacheableIdentifier's JSCell identifier. This visitAggregate() is called from CodeBlock::stronglyVisitStrongReferences().

When we write barrier a CodeBlock, it guarantees that its visitAggregate()
methods is called. However, it does not guarantee that its propagateTransitions()
method will be called. Since the CacheableIdentifier's reference to a cell
should be a strong reference, visiting it via a StructureStubInfo::visitAggregate()
method is the right thing to do.
See https://bugs.webkit.org/show_bug.cgi?id=205544#c7 for an example of why
propagateTransitions() doesn't always do the job.

StructureStubInfo::visitWeakReferences() is also inappropriate for this
because it is only called after all marking is done. It is also not meant
to keep cells alive but merely for clearing weak references to dead cells.

  1. Also add to visitAggregate() for ModuleNamespaceData's m_identifier in GetByStatus::markIfCheap().
  1. Remove previously applied keep alive tactics to work around Box<Identifier> destruction. This also retores the allowance to destruct DFG::Plans on a compiler thread.
  1. Added a JSString:getValueImpl() helper.
  1. Added a write barrier in DFG and FTL JITFinalizer's finalizeCommon() to ensure that frozen values are scanned by the GC.

During compilation, the frozen values were previously protected by the Plan.
After finalization, they should be protected by the CodeBlock. Hence, we
should barrier the CodeBlock since the last GC scan of the CodeBlock may have
happened before the frozen values were registered with the CodeBlock.

GC considerations:
==================
The following also addresses Yusuke's concerns in https://bugs.webkit.org/show_bug.cgi?id=205544#c10.

CacheableIdentifier is only stored as fields in 4 classes/structs:

  1. AccessCase::m_identifier
  2. GetByIdVariant::m_identifier
  3. ModuleNamespaceData::m_identifier
  4. StructureStubInfo::m_getByIdSelfIdentifier

AccessCase::m_identifier
========================
While the access case is being created and added in tryCacheGetBy(), the
CacheableIdentifier is still on the stack and protected from the GC. At the
bottom of tryCacheGetBy(), StructureStubInfo::addAccessCase() is called to add
the access case.

StructureStubInfo::addAccessCase() will barrier the owner CodeBlock at its end,
and CodeBlock::stronglyVisitStrongReferences() will visit the StructureStubInfo,
which in turn visits the AccessCase. StructureStubInfo::visitAggregate() has
been added for this purpose.

GetByIdVariant::m_identifier
============================
GetByIdVariant is only stored in GetByStatus. Both GetByIdVariant and GetByStatus
are only created and handled in the DFG/FTL compiler threads. While the compiler
thread is working with them, they are safe from the GC because the GC won't collect
objects until the compiler thread is at a SafePoint.

At compiler SafePoints, any GetByStatus that needs to be persisted is stored in
DFG::Plan::m_recordedStatuses. The Plan will visit the m_recordedStatuses in
Plan::checkLivenessAndVisitChildren().

At the end of compilation, Plan::m_recordedStatuses is transferred over to the owner
CodeBlock's DFG::CommonData in Plan::finalizeWithoutNotifyingCallback().
Plan::finalizeWithoutNotifyingCallback() will also barrier the owner CodeBlock at
its end.

Thereafter, CodeBlock::stronglyVisitStrongReferences() will visit the recordedStatuses.

ModuleNamespaceData::m_identifier
=================================
ModuleNamespaceData is only stored in a GetByStatus, and is therefore protected
similarly as the GetByIdVariant::m_identifier case above.

StructureStubInfo::m_getByIdSelfIdentifier
==========================================
StructureStubInfo::initGetByIdSelf() is called from inside tryCacheGetBy().
StructureStubInfo::initGetByIdSelf() will barrier the owner CodeBlock. The
CacheableIdentifier here is protected in the same way as the AccessCase::m_identifier
case above.

DesiredIdentifiers
==================
The compiler thread may also stash a CacheableIdentifier's uid in its
DesiredIdentifiers. Normally, the identifiers stashed in DesiredIdentifiers are
from identifiers that the CodeBlock already knows abut and manages (e.g. from
GetByIds). For uids from a cell-based CacheableIdentifier variable is passed to
a GetByVal, we need kep the cell alive in order to keep the uid alive. This is
achieved by freezing the cell with freezeStrong() in the op_get_by_val case in
the DFG BytecodeParser.

Reseting a StructureStubInfo while its IC code is still executing on the stack
==============================================================================
The concern is that IC code may call slow path / getter functions that may in turn:

  1. reset the IC, and
  2. run the GC.

This can be a problem if:

  1. there is a scenario where we return from the slow path / getter function and run IC code that uses the cell / uid from the CacheableIdentifier.

This is because the StructureStubInfo is what visits the that cell, which
in turn its uid alive. Once the StructureStubInfo is reset, it will no
longer be associated with any AccessCase or the m_getByIdSelfIdentifier.
As such they will not be visited, and the CacheableIdentifier may be collected
by the GC.

In practice, the generated IC code never uses the cell / uid after it calls
any slow path / getter function. I've verified this by auditing the code
generation in InlineAccess::generateSelfInAccess() and PolymorphicAccess::regenerate().
Hence, there's no issue with using a collected cell / uid.

  1. there is a scenario where a slow path / getter function makes use of the cell / uid from the CacheableIdentifier but does not protect it.

The only 2 slow path functions:

operationGetByValGeneric()
operationGetByValOptimize()

operationGetByValGeneric() does not use any CacheableIdentifier from the StructureStubInfo.

operationGetByValOptimize() modifies the StructureStubInfo in tryCacheGetBy()
under the protection of a GCSafeConcurrentJSLocker, and can reset the
StructureStubInfo. However, it does not use any CacheableIdentifier after
that.

Hence, there's also no GC issue here.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • bytecode/AccessCase.cpp:

(JSC::AccessCase::AccessCase):
(JSC::AccessCase::create):
(JSC::AccessCase::fromStructureStubInfo):
(JSC::AccessCase::commit):
(JSC::AccessCase::canReplace const):
(JSC::AccessCase::dump const):
(JSC::AccessCase::visitAggregate const):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):

  • bytecode/AccessCase.h:

(JSC::AccessCase::uid const):
(JSC::AccessCase::identifier const):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::propagateTransitions):
(JSC::CodeBlock::stronglyVisitStrongReferences):

  • bytecode/GetByIdVariant.cpp:

(JSC::GetByIdVariant::GetByIdVariant):
(JSC::GetByIdVariant::attemptToMerge):
(JSC::GetByIdVariant::visitAggregate):
(JSC::GetByIdVariant::dumpInContext const):

  • bytecode/GetByIdVariant.h:

(JSC::GetByIdVariant::identifier const):
(JSC::GetByIdVariant::overlaps):

  • bytecode/GetByStatus.cpp:

(JSC::GetByStatus::computeFromLLInt):
(JSC::GetByStatus::computeFor):
(JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::GetByStatus::visitAggregate):
(JSC::GetByStatus::singleIdentifier const):

  • bytecode/GetByStatus.h:
  • bytecode/GetterSetterAccessCase.cpp:

(JSC::GetterSetterAccessCase::GetterSetterAccessCase):
(JSC::GetterSetterAccessCase::create):

  • bytecode/GetterSetterAccessCase.h:
  • bytecode/InstanceOfAccessCase.cpp:

(JSC::InstanceOfAccessCase::InstanceOfAccessCase):

  • bytecode/IntrinsicGetterAccessCase.cpp:

(JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
(JSC::IntrinsicGetterAccessCase::create):

  • bytecode/IntrinsicGetterAccessCase.h:
  • bytecode/ModuleNamespaceAccessCase.cpp:

(JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
(JSC::ModuleNamespaceAccessCase::create):

  • bytecode/ModuleNamespaceAccessCase.h:
  • bytecode/PolymorphicAccess.cpp:

(JSC::PolymorphicAccess::visitAggregate):
(JSC::PolymorphicAccess::regenerate):

  • bytecode/PolymorphicAccess.h:
  • bytecode/ProxyableAccessCase.cpp:

(JSC::ProxyableAccessCase::ProxyableAccessCase):
(JSC::ProxyableAccessCase::create):

  • bytecode/ProxyableAccessCase.h:
  • bytecode/RecordedStatuses.cpp:

(JSC::RecordedStatuses::visitAggregate):

  • bytecode/RecordedStatuses.h:
  • bytecode/StructureStubInfo.cpp:

(JSC::StructureStubInfo::initGetByIdSelf):
(JSC::StructureStubInfo::addAccessCase):
(JSC::StructureStubInfo::visitAggregate):

  • bytecode/StructureStubInfo.h:

(JSC::StructureStubInfo::getByIdSelfIdentifier):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseGetById):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGDesiredIdentifiers.cpp:

(JSC::DFG::DesiredIdentifiers::ensure):
(JSC::DFG::DesiredIdentifiers::at const):
(JSC::DFG::DesiredIdentifiers::reallyAdd):
(JSC::DFG::DesiredIdentifiers::processCodeBlockIdentifiersIfNeeded): Deleted.

  • dfg/DFGDesiredIdentifiers.h:
  • dfg/DFGJITFinalizer.cpp:

(JSC::DFG::JITFinalizer::finalizeCommon):

  • dfg/DFGPlan.cpp:

(JSC::DFG::Plan::~Plan):
(JSC::DFG::Plan::checkLivenessAndVisitChildren):
(JSC::DFG::Plan::cancel):

  • dfg/DFGPlan.h:

(JSC::DFG::Plan::keepAliveIdentifier): Deleted.

  • dfg/DFGWorklist.cpp:

(JSC::DFG::Worklist::removeAllReadyPlansForVM):
(JSC::DFG::Worklist::removeDeadPlans):
(JSC::DFG::Worklist::removeNonCompilingPlansForVM):
(JSC::DFG::Worklist::deleteCancelledPlansForVM): Deleted.

  • dfg/DFGWorklist.h:
  • ftl/FTLJITFinalizer.cpp:

(JSC::FTL::JITFinalizer::finalizeCommon):

  • jit/JITOperations.cpp:
  • jit/Repatch.cpp:

(JSC::tryCacheGetBy):
(JSC::repatchGetBy):
(JSC::tryCacheArrayGetByVal):
(JSC::tryCacheInstanceOf):

  • jit/Repatch.h:
  • runtime/CacheableIdentifier.cpp: Added.

(JSC::CacheableIdentifier::dump const):

  • runtime/CacheableIdentifier.h: Added.

(JSC::CacheableIdentifier::CacheableIdentifier):
(JSC::CacheableIdentifier::isUid const):
(JSC::CacheableIdentifier::isCell const):
(JSC::CacheableIdentifier::isSymbol const):
(JSC::CacheableIdentifier::operator bool const):

  • runtime/CacheableIdentifierInlines.h: Added.

(JSC::CacheableIdentifier::CacheableIdentifier):
(JSC::CacheableIdentifier::cell const):
(JSC::CacheableIdentifier::uid const):
(JSC::CacheableIdentifier::isCacheableIdentifierCell):
(JSC::CacheableIdentifier::isSymbolCell const):
(JSC::CacheableIdentifier::isStringCell const):
(JSC::CacheableIdentifier::setCellBits):
(JSC::CacheableIdentifier::setUidBits):
(JSC::CacheableIdentifier::visitAggregate const):
(JSC::CacheableIdentifier::operator== const):
(JSC::CacheableIdentifier::operator!= const):

  • runtime/ExceptionHelpers.cpp:

(JSC::functionCallBase):

  • runtime/JSString.h:

(JSC::JSString::getValueImpl const):

  • runtime/VM.cpp:

(JSC::VM::ensureWatchpointSetForImpureProperty):
(JSC::VM::addImpureProperty):
(JSC::VM::registerWatchpointForImpureProperty): Deleted.

  • runtime/VM.h:

Source/WebCore:

  • bindings/js/CommonVM.cpp:

(WebCore::addImpureProperty):

Location:
trunk
Files:
4 added
45 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r254434 r254464  
     12020-01-13  Mark Lam  <mark.lam@apple.com>
     2
     3        Replace uses of Box<Identifier> with a new CacheableIdentifier class.
     4        https://bugs.webkit.org/show_bug.cgi?id=205544
     5        <rdar://problem/58041800>
     6
     7        Reviewed by Saam Barati.
     8
     9        * stress/racy-gc-cleanup-of-identifier-after-mutator-stops-running.js: Added.
     10
    1112020-01-11  Keith Miller  <keith_miller@apple.com>
    212
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r254447 r254464  
    786786    runtime/CachePayload.h
    787787    runtime/CacheUpdate.h
     788    runtime/CacheableIdentifier.h
     789    runtime/CacheableIdentifierInlines.h
    788790    runtime/CachedBytecode.h
    789791    runtime/CachedTypes.h
  • trunk/Source/JavaScriptCore/ChangeLog

    r254447 r254464  
     12020-01-13  Mark Lam  <mark.lam@apple.com>
     2
     3        Replace uses of Box<Identifier> with a new CacheableIdentifier class.
     4        https://bugs.webkit.org/show_bug.cgi?id=205544
     5        <rdar://problem/58041800>
     6
     7        Reviewed by Saam Barati.
     8
     9        The introduction of the use of Box<Identifier> was to get around having to
     10        ref/deref the underlying UniqedStringImpl in Identifiers from the compiler
     11        and GC threads.  However, it proves to be difficult to control when these
     12        Box<Identifier>s get destructed, and requires that we find all the places in
     13        the compier and GC threads where this can happen, and apply keep alive tactics
     14        there to defer destruction of the Box<Identifier> to the mutator thread.
     15
     16        This patch fixes this by replacing uses of Box<Identifier> with
     17        CacheableIdentifier, which is effectively a tagged union of a JSCell* or a
     18        UniquedStringImpl*.  The JSCell*, in this case, can be either a Symbol* or a
     19        JSString* that is backed by an atom string.  The VM runtime ensures that we'll
     20        never try to cache an identifier from a JSCell that is not one of these.  This
     21        CacheableIdentifier can be destructed from the compiler or GC thread.  Since it
     22        doesn't hold a ref of the underlying UniquedStringImpl, it won't try to deref
     23        it on destruction.
     24
     25        Instead, we'll need to visit CacheableIdentifiers during GC scans to keep the
     26        JSCell in it alive, and that JSCell will, in turn, keep the underlying
     27        UniquedStringImpl alive.
     28
     29        This patch also does the following:
     30
     31        1. Add a visitAggregate() method to StructureStubInfo, PolymorphicAccess, and
     32           AccessCase to visit the CacheableIdentifier's JSCell identifier.  This
     33           visitAggregate() is called from CodeBlock::stronglyVisitStrongReferences().
     34
     35           When we write barrier a CodeBlock, it guarantees that its visitAggregate()
     36           methods is called.  However, it does not guarantee that its propagateTransitions()
     37           method will be called.  Since the CacheableIdentifier's reference to a cell
     38           should be a strong reference, visiting it via a StructureStubInfo::visitAggregate()
     39           method is the right thing to do.
     40           See https://bugs.webkit.org/show_bug.cgi?id=205544#c7 for an example of why
     41           propagateTransitions() doesn't always do the job.
     42
     43           StructureStubInfo::visitWeakReferences() is also inappropriate for this
     44           because it is only called after all marking is done.  It is also not meant
     45           to keep cells alive but merely for clearing weak references to dead cells.
     46
     47        2. Also add to visitAggregate() for ModuleNamespaceData's m_identifier in
     48           GetByStatus::markIfCheap().
     49
     50        3. Remove previously applied keep alive tactics to work around Box<Identifier>
     51           destruction.  This also retores the allowance to destruct DFG::Plans on a
     52           compiler thread.
     53
     54        4. Added a JSString:getValueImpl() helper.
     55
     56        5. Added a write barrier in DFG and FTL JITFinalizer's finalizeCommon() to ensure
     57           that frozen values are scanned by the GC.
     58
     59           During compilation, the frozen values were previously protected by the Plan.
     60           After finalization, they should be protected by the CodeBlock.  Hence, we
     61           should barrier the CodeBlock since the last GC scan of the CodeBlock may have
     62           happened before the frozen values were registered with the CodeBlock.
     63
     64        GC considerations:
     65        ==================
     66        The following also addresses Yusuke's concerns in https://bugs.webkit.org/show_bug.cgi?id=205544#c10.
     67
     68        CacheableIdentifier is only stored as fields in 4 classes/structs:
     69
     70        1. AccessCase::m_identifier
     71        2. GetByIdVariant::m_identifier
     72        3. ModuleNamespaceData::m_identifier
     73        4. StructureStubInfo::m_getByIdSelfIdentifier
     74
     75        AccessCase::m_identifier
     76        ========================
     77        While the access case is being created and added in tryCacheGetBy(), the
     78        CacheableIdentifier is still on the stack and protected from the GC.  At the
     79        bottom of tryCacheGetBy(), StructureStubInfo::addAccessCase() is called to add
     80        the access case.
     81
     82        StructureStubInfo::addAccessCase() will barrier the owner CodeBlock at its end,
     83        and CodeBlock::stronglyVisitStrongReferences() will visit the StructureStubInfo,
     84        which in turn visits the AccessCase.  StructureStubInfo::visitAggregate() has
     85        been added for this purpose.
     86
     87        GetByIdVariant::m_identifier
     88        ============================
     89        GetByIdVariant is only stored in GetByStatus.  Both GetByIdVariant and GetByStatus
     90        are only created and handled in the DFG/FTL compiler threads.  While the compiler
     91        thread is working with them, they are safe from the GC because the GC won't collect
     92        objects until the compiler thread is at a SafePoint.
     93
     94        At compiler SafePoints, any GetByStatus that needs to be persisted is stored in
     95        DFG::Plan::m_recordedStatuses.  The Plan will visit the m_recordedStatuses in
     96        Plan::checkLivenessAndVisitChildren().
     97
     98        At the end of compilation, Plan::m_recordedStatuses is transferred over to the owner
     99        CodeBlock's DFG::CommonData in Plan::finalizeWithoutNotifyingCallback().
     100        Plan::finalizeWithoutNotifyingCallback() will also barrier the owner CodeBlock at
     101        its end.
     102
     103        Thereafter, CodeBlock::stronglyVisitStrongReferences() will visit the recordedStatuses.
     104
     105        ModuleNamespaceData::m_identifier
     106        =================================
     107        ModuleNamespaceData is only stored in a GetByStatus, and is therefore protected
     108        similarly as the GetByIdVariant::m_identifier case above.
     109
     110        StructureStubInfo::m_getByIdSelfIdentifier
     111        ==========================================
     112        StructureStubInfo::initGetByIdSelf() is called from inside tryCacheGetBy().
     113        StructureStubInfo::initGetByIdSelf() will barrier the owner CodeBlock.  The
     114        CacheableIdentifier here is protected in the same way as the AccessCase::m_identifier
     115        case above.
     116
     117        DesiredIdentifiers
     118        ==================
     119        The compiler thread may also stash a CacheableIdentifier's uid in its
     120        DesiredIdentifiers.  Normally, the identifiers stashed in DesiredIdentifiers are
     121        from identifiers that the CodeBlock already knows abut and manages (e.g. from
     122        GetByIds).  For uids from a cell-based CacheableIdentifier variable is passed to
     123        a GetByVal, we need kep the cell alive in order to keep the uid alive.  This is
     124        achieved by freezing the cell with freezeStrong() in the op_get_by_val case in
     125        the DFG BytecodeParser.
     126
     127        Reseting a StructureStubInfo while its IC code is still executing on the stack
     128        ==============================================================================
     129        The concern is that IC code may call slow path / getter functions that may in turn:
     130
     131        1. reset the IC, and
     132        2. run the GC.
     133
     134        This can be a problem if:
     135
     136        1. there is a scenario where we return from the slow path / getter function
     137           and run IC code that uses the cell / uid from the CacheableIdentifier.
     138
     139           This is because the StructureStubInfo is what visits the that cell, which
     140           in turn its uid alive.  Once the StructureStubInfo is reset, it will no
     141           longer be associated with any AccessCase or the m_getByIdSelfIdentifier.
     142           As such they will not be visited, and the CacheableIdentifier may be collected
     143           by the GC.
     144
     145           In practice, the generated IC code never uses the cell / uid after it calls
     146           any slow path / getter function.  I've verified this by auditing the code
     147           generation in InlineAccess::generateSelfInAccess() and PolymorphicAccess::regenerate().
     148           Hence, there's no issue with using a collected cell / uid.
     149
     150        2. there is a scenario where a slow path / getter function makes use of the cell / uid
     151           from the CacheableIdentifier but does not protect it.
     152
     153           The only 2 slow path functions:
     154               operationGetByValGeneric()
     155               operationGetByValOptimize()
     156
     157           operationGetByValGeneric() does not use any CacheableIdentifier from the StructureStubInfo.
     158
     159           operationGetByValOptimize() modifies the StructureStubInfo in tryCacheGetBy()
     160           under the protection of a GCSafeConcurrentJSLocker, and can reset the
     161           StructureStubInfo.  However, it does not use any CacheableIdentifier after
     162           that.
     163
     164           Hence, there's also no GC issue here.
     165
     166        * CMakeLists.txt:
     167        * JavaScriptCore.xcodeproj/project.pbxproj:
     168        * Sources.txt:
     169        * bytecode/AccessCase.cpp:
     170        (JSC::AccessCase::AccessCase):
     171        (JSC::AccessCase::create):
     172        (JSC::AccessCase::fromStructureStubInfo):
     173        (JSC::AccessCase::commit):
     174        (JSC::AccessCase::canReplace const):
     175        (JSC::AccessCase::dump const):
     176        (JSC::AccessCase::visitAggregate const):
     177        (JSC::AccessCase::generateWithGuard):
     178        (JSC::AccessCase::generateImpl):
     179        * bytecode/AccessCase.h:
     180        (JSC::AccessCase::uid const):
     181        (JSC::AccessCase::identifier const):
     182        * bytecode/CodeBlock.cpp:
     183        (JSC::CodeBlock::propagateTransitions):
     184        (JSC::CodeBlock::stronglyVisitStrongReferences):
     185        * bytecode/GetByIdVariant.cpp:
     186        (JSC::GetByIdVariant::GetByIdVariant):
     187        (JSC::GetByIdVariant::attemptToMerge):
     188        (JSC::GetByIdVariant::visitAggregate):
     189        (JSC::GetByIdVariant::dumpInContext const):
     190        * bytecode/GetByIdVariant.h:
     191        (JSC::GetByIdVariant::identifier const):
     192        (JSC::GetByIdVariant::overlaps):
     193        * bytecode/GetByStatus.cpp:
     194        (JSC::GetByStatus::computeFromLLInt):
     195        (JSC::GetByStatus::computeFor):
     196        (JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback):
     197        (JSC::GetByStatus::visitAggregate):
     198        (JSC::GetByStatus::singleIdentifier const):
     199        * bytecode/GetByStatus.h:
     200        * bytecode/GetterSetterAccessCase.cpp:
     201        (JSC::GetterSetterAccessCase::GetterSetterAccessCase):
     202        (JSC::GetterSetterAccessCase::create):
     203        * bytecode/GetterSetterAccessCase.h:
     204        * bytecode/InstanceOfAccessCase.cpp:
     205        (JSC::InstanceOfAccessCase::InstanceOfAccessCase):
     206        * bytecode/IntrinsicGetterAccessCase.cpp:
     207        (JSC::IntrinsicGetterAccessCase::IntrinsicGetterAccessCase):
     208        (JSC::IntrinsicGetterAccessCase::create):
     209        * bytecode/IntrinsicGetterAccessCase.h:
     210        * bytecode/ModuleNamespaceAccessCase.cpp:
     211        (JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
     212        (JSC::ModuleNamespaceAccessCase::create):
     213        * bytecode/ModuleNamespaceAccessCase.h:
     214        * bytecode/PolymorphicAccess.cpp:
     215        (JSC::PolymorphicAccess::visitAggregate):
     216        (JSC::PolymorphicAccess::regenerate):
     217        * bytecode/PolymorphicAccess.h:
     218        * bytecode/ProxyableAccessCase.cpp:
     219        (JSC::ProxyableAccessCase::ProxyableAccessCase):
     220        (JSC::ProxyableAccessCase::create):
     221        * bytecode/ProxyableAccessCase.h:
     222        * bytecode/RecordedStatuses.cpp:
     223        (JSC::RecordedStatuses::visitAggregate):
     224        * bytecode/RecordedStatuses.h:
     225        * bytecode/StructureStubInfo.cpp:
     226        (JSC::StructureStubInfo::initGetByIdSelf):
     227        (JSC::StructureStubInfo::addAccessCase):
     228        (JSC::StructureStubInfo::visitAggregate):
     229        * bytecode/StructureStubInfo.h:
     230        (JSC::StructureStubInfo::getByIdSelfIdentifier):
     231        * dfg/DFGByteCodeParser.cpp:
     232        (JSC::DFG::ByteCodeParser::parseGetById):
     233        (JSC::DFG::ByteCodeParser::parseBlock):
     234        * dfg/DFGDesiredIdentifiers.cpp:
     235        (JSC::DFG::DesiredIdentifiers::ensure):
     236        (JSC::DFG::DesiredIdentifiers::at const):
     237        (JSC::DFG::DesiredIdentifiers::reallyAdd):
     238        (JSC::DFG::DesiredIdentifiers::processCodeBlockIdentifiersIfNeeded): Deleted.
     239        * dfg/DFGDesiredIdentifiers.h:
     240        * dfg/DFGJITFinalizer.cpp:
     241        (JSC::DFG::JITFinalizer::finalizeCommon):
     242        * dfg/DFGPlan.cpp:
     243        (JSC::DFG::Plan::~Plan):
     244        (JSC::DFG::Plan::checkLivenessAndVisitChildren):
     245        (JSC::DFG::Plan::cancel):
     246        * dfg/DFGPlan.h:
     247        (JSC::DFG::Plan::keepAliveIdentifier): Deleted.
     248        * dfg/DFGWorklist.cpp:
     249        (JSC::DFG::Worklist::removeAllReadyPlansForVM):
     250        (JSC::DFG::Worklist::removeDeadPlans):
     251        (JSC::DFG::Worklist::removeNonCompilingPlansForVM):
     252        (JSC::DFG::Worklist::deleteCancelledPlansForVM): Deleted.
     253        * dfg/DFGWorklist.h:
     254        * ftl/FTLJITFinalizer.cpp:
     255        (JSC::FTL::JITFinalizer::finalizeCommon):
     256        * jit/JITOperations.cpp:
     257        * jit/Repatch.cpp:
     258        (JSC::tryCacheGetBy):
     259        (JSC::repatchGetBy):
     260        (JSC::tryCacheArrayGetByVal):
     261        (JSC::tryCacheInstanceOf):
     262        * jit/Repatch.h:
     263        * runtime/CacheableIdentifier.cpp: Added.
     264        (JSC::CacheableIdentifier::dump const):
     265        * runtime/CacheableIdentifier.h: Added.
     266        (JSC::CacheableIdentifier::CacheableIdentifier):
     267        (JSC::CacheableIdentifier::isUid const):
     268        (JSC::CacheableIdentifier::isCell const):
     269        (JSC::CacheableIdentifier::isSymbol const):
     270        (JSC::CacheableIdentifier::operator bool const):
     271        * runtime/CacheableIdentifierInlines.h: Added.
     272        (JSC::CacheableIdentifier::CacheableIdentifier):
     273        (JSC::CacheableIdentifier::cell const):
     274        (JSC::CacheableIdentifier::uid const):
     275        (JSC::CacheableIdentifier::isCacheableIdentifierCell):
     276        (JSC::CacheableIdentifier::isSymbolCell const):
     277        (JSC::CacheableIdentifier::isStringCell const):
     278        (JSC::CacheableIdentifier::setCellBits):
     279        (JSC::CacheableIdentifier::setUidBits):
     280        (JSC::CacheableIdentifier::visitAggregate const):
     281        (JSC::CacheableIdentifier::operator== const):
     282        (JSC::CacheableIdentifier::operator!= const):
     283        * runtime/ExceptionHelpers.cpp:
     284        (JSC::functionCallBase):
     285        * runtime/JSString.h:
     286        (JSC::JSString::getValueImpl const):
     287        * runtime/VM.cpp:
     288        (JSC::VM::ensureWatchpointSetForImpureProperty):
     289        (JSC::VM::addImpureProperty):
     290        (JSC::VM::registerWatchpointForImpureProperty): Deleted.
     291        * runtime/VM.h:
     292
    12932020-01-13  Yusuke Suzuki  <ysuzuki@apple.com>
    2294
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r254447 r254464  
    19151915                FE7C41961B97FC4B00F4D598 /* PingPongStackOverflowTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */; };
    19161916                FE80C1971D775CDD008510C0 /* CatchScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80C1961D775B27008510C0 /* CatchScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1917                FE8DE54B23AC1DAD005C9142 /* CacheableIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE8DE54A23AC1DAD005C9142 /* CacheableIdentifier.h */; };
     1918                FE8DE54D23AC1E86005C9142 /* CacheableIdentifierInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FE8DE54C23AC1E86005C9142 /* CacheableIdentifierInlines.h */; };
    19171919                FE99B2491C24C3D300C82159 /* JITNegGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE99B2481C24B6D300C82159 /* JITNegGenerator.h */; };
    19181920                FEA08620182B7A0400F6D851 /* Breakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = FEA0861E182B7A0400F6D851 /* Breakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    51705172                FE80C1981D775FB4008510C0 /* CatchScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CatchScope.cpp; sourceTree = "<group>"; };
    51715173                FE80C19A1D7768FD008510C0 /* ExceptionEventLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionEventLocation.cpp; sourceTree = "<group>"; };
     5174                FE8DE54A23AC1DAD005C9142 /* CacheableIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheableIdentifier.h; sourceTree = "<group>"; };
     5175                FE8DE54C23AC1E86005C9142 /* CacheableIdentifierInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheableIdentifierInlines.h; sourceTree = "<group>"; };
     5176                FE8DE54E23AC3A8E005C9142 /* CacheableIdentifier.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CacheableIdentifier.cpp; sourceTree = "<group>"; };
    51725177                FE90BB3A1B7CF64E006B3F03 /* VMInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInlines.h; sourceTree = "<group>"; };
    51735178                FE98B5B61BB9AE110073E7A6 /* JITSubGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITSubGenerator.h; sourceTree = "<group>"; };
     
    70097014                                1435952022A521CA00E8086D /* BytecodeCacheError.cpp */,
    70107015                                1435951F22A521CA00E8086D /* BytecodeCacheError.h */,
     7016                                FE8DE54E23AC3A8E005C9142 /* CacheableIdentifier.cpp */,
     7017                                FE8DE54A23AC1DAD005C9142 /* CacheableIdentifier.h */,
     7018                                FE8DE54C23AC1E86005C9142 /* CacheableIdentifierInlines.h */,
    70117019                                148B1419225DD1E900D6E998 /* CachedBytecode.cpp */,
    70127020                                144CA34F221F037900817789 /* CachedBytecode.h */,
     
    88658873                                0F40E4A71C497F7400A577FA /* AirOpcode.h in Headers */,
    88668874                                0F40E4A81C497F7400A577FA /* AirOpcodeGenerated.h in Headers */,
     8875                                FE8DE54B23AC1DAD005C9142 /* CacheableIdentifier.h in Headers */,
    88678876                                0F40E4A91C497F7400A577FA /* AirOpcodeUtils.h in Headers */,
    88688877                                0FB387901BFBC44D00E3AB1E /* AirOptimizeBlockOrder.h in Headers */,
     
    1025810267                                FE5932A8183C5A2600A1ECCC /* VMEntryScope.h in Headers */,
    1025910268                                0F5AE2C41DF4F2800066EFE1 /* VMInlines.h in Headers */,
     10269                                FE8DE54D23AC1E86005C9142 /* CacheableIdentifierInlines.h in Headers */,
    1026010270                                FE3022D71E42857300BAC493 /* VMInspector.h in Headers */,
    1026110271                                FEC5797323105B5100BCA83F /* VMInspectorInlines.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r254447 r254464  
    730730runtime/CachePayload.cpp
    731731runtime/CacheUpdate.cpp
     732runtime/CacheableIdentifier.cpp
    732733runtime/CachedBytecode.cpp
    733734runtime/CachedTypes.cpp
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp

    r254087 r254464  
    11/*
    2  * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030
    3131#include "CCallHelpers.h"
     32#include "CacheableIdentifierInlines.h"
    3233#include "CallLinkInfo.h"
    3334#include "DOMJITGetterSetter.h"
     
    5758DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(AccessCase);
    5859
    59 AccessCase::AccessCase(VM& vm, JSCell* owner, AccessType type, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     60AccessCase::AccessCase(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    6061    : m_type(type)
    6162    , m_offset(offset)
    6263    , m_polyProtoAccessChain(WTFMove(prototypeAccessChain))
    63     , m_identifier(Box<Identifier>::create(identifier))
     64    , m_identifier(identifier)
    6465{
    6566    m_structure.setMayBeNull(vm, owner, structure);
     
    6869}
    6970
    70 std::unique_ptr<AccessCase> AccessCase::create(VM& vm, JSCell* owner, AccessType type, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     71std::unique_ptr<AccessCase> AccessCase::create(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    7172{
    7273    switch (type) {
     
    107108
    108109std::unique_ptr<AccessCase> AccessCase::create(
    109     VM& vm, JSCell* owner, const Identifier& identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure,
     110    VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure,
    110111    const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    111112{
     
    128129
    129130std::unique_ptr<AccessCase> AccessCase::fromStructureStubInfo(
    130     VM& vm, JSCell* owner, const Identifier& identifier, StructureStubInfo& stubInfo)
     131    VM& vm, JSCell* owner, CacheableIdentifier identifier, StructureStubInfo& stubInfo)
    131132{
    132133    switch (stubInfo.cacheType()) {
     
    137138    case CacheType::PutByIdReplace:
    138139        RELEASE_ASSERT(stubInfo.hasConstantIdentifier);
     140        ASSERT(!identifier.isCell());
    139141        return AccessCase::create(vm, owner, Replace, identifier, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
    140142
    141143    case CacheType::InByIdSelf:
    142144        RELEASE_ASSERT(stubInfo.hasConstantIdentifier);
     145        ASSERT(!identifier.isCell());
    143146        return AccessCase::create(vm, owner, InHit, identifier, stubInfo.u.byIdSelf.offset, stubInfo.u.byIdSelf.baseObjectStructure.get());
    144147
    145148    case CacheType::ArrayLength:
    146149        RELEASE_ASSERT(stubInfo.hasConstantIdentifier);
     150        ASSERT(!identifier.isCell());
    147151        return AccessCase::create(vm, owner, AccessCase::ArrayLength, identifier);
    148152
    149153    case CacheType::StringLength:
    150154        RELEASE_ASSERT(stubInfo.hasConstantIdentifier);
     155        ASSERT(!identifier.isCell());
    151156        return AccessCase::create(vm, owner, AccessCase::StringLength, identifier);
    152157
     
    183188    Structure* structure = this->structure();
    184189
    185     if (!m_identifier->isNull()) {
     190    if (m_identifier) {
    186191        if ((structure && structure->needImpurePropertyWatchpoint())
    187192            || m_conditionSet.needImpurePropertyWatchpoint()
    188193            || (m_polyProtoAccessChain && m_polyProtoAccessChain->needImpurePropertyWatchpoint()))
    189             result.append(vm.ensureWatchpointSetForImpureProperty(*m_identifier));
     194            result.append(vm.ensureWatchpointSetForImpureProperty(m_identifier.uid()));
    190195    }
    191196
     
    553558    // A->canReplace(B) == B->canReplace(A).
    554559
    555     if (*m_identifier != *other.m_identifier)
     560    if (m_identifier != other.m_identifier)
    556561        return false;
    557562   
     
    651656    out.print(comma, m_state);
    652657
    653     out.print(comma, "ident = '", *m_identifier, "'");
     658    out.print(comma, "ident = '", m_identifier, "'");
    654659    if (isValidOffset(m_offset))
    655660        out.print(comma, "offset = ", m_offset);
     
    713718}
    714719
     720void AccessCase::visitAggregate(SlotVisitor& visitor) const
     721{
     722    m_identifier.visitAggregate(visitor);
     723}
     724
    715725void AccessCase::generateWithGuard(
    716726    AccessGenerationState& state, CCallHelpers::JumpList& fallThrough)
     
    731741
    732742    if (requiresIdentifierNameMatch() && !stubInfo.hasConstantIdentifier) {
    733         RELEASE_ASSERT(!m_identifier->isNull());
     743        RELEASE_ASSERT(m_identifier);
    734744        GPRReg propertyGPR = state.u.propertyGPR;
    735745        // non-rope string check done inside polymorphic access.
     
    16691679            // https://bugs.webkit.org/show_bug.cgi?id=203204
    16701680            if (m_type == CustomValueGetter || m_type == CustomAccessorGetter) {
    1671                 RELEASE_ASSERT(!m_identifier->isNull());
     1681                RELEASE_ASSERT(m_identifier);
    16721682                jit.setupArguments<PropertySlot::GetValueFunc>(
    16731683                    CCallHelpers::TrustedImmPtr(codeBlock->globalObject()),
  • trunk/Source/JavaScriptCore/bytecode/AccessCase.h

    r254087 r254464  
    11/*
    2  * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(JIT)
    2929
     30#include "CacheableIdentifier.h"
    3031#include "JSFunctionInlines.h"
    3132#include "ObjectPropertyConditionSet.h"
    3233#include "PolyProtoAccessChain.h"
    33 #include <wtf/Box.h>
    3434#include <wtf/CommaPrinter.h>
    3535
     
    143143    }
    144144
    145     static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, AccessType, const Identifier&, PropertyOffset = invalidOffset,
     145    static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset = invalidOffset,
    146146        Structure* = nullptr, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(), std::unique_ptr<PolyProtoAccessChain> = nullptr);
    147147
    148148    // This create method should be used for transitions.
    149     static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, const Identifier&, PropertyOffset, Structure* oldStructure,
     149    static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, CacheableIdentifier, PropertyOffset, Structure* oldStructure,
    150150        Structure* newStructure, const ObjectPropertyConditionSet&, std::unique_ptr<PolyProtoAccessChain>);
    151151   
    152     static std::unique_ptr<AccessCase> fromStructureStubInfo(VM&, JSCell* owner, const Identifier&, StructureStubInfo&);
     152    static std::unique_ptr<AccessCase> fromStructureStubInfo(VM&, JSCell* owner, CacheableIdentifier, StructureStubInfo&);
    153153
    154154    AccessType type() const { return m_type; }
     
    236236    static TypedArrayType toTypedArrayType(AccessType);
    237237
    238     UniquedStringImpl* uid() const { return m_identifier->impl(); }
    239     Box<Identifier> identifier() const { return m_identifier; }
    240 
     238    UniquedStringImpl* uid() const { return m_identifier.uid(); }
     239    CacheableIdentifier identifier() const { return m_identifier; }
    241240
    242241#if ASSERT_ENABLED
     
    247246   
    248247protected:
    249     AccessCase(VM&, JSCell* owner, AccessType, const Identifier&, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, std::unique_ptr<PolyProtoAccessChain>);
     248    AccessCase(VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, std::unique_ptr<PolyProtoAccessChain>);
    250249    AccessCase(AccessCase&&) = default;
    251250    AccessCase(const AccessCase& other)
     
    272271    void forEachDependentCell(const Functor&) const;
    273272
     273    void visitAggregate(SlotVisitor&) const;
    274274    bool visitWeak(VM&) const;
    275275    bool propagateTransitions(SlotVisitor&) const;
     
    314314    std::unique_ptr<PolyProtoAccessChain> m_polyProtoAccessChain;
    315315
    316     Box<Identifier> m_identifier; // We use this indirection so the concurrent compiler can concurrently ref this Box.
     316    CacheableIdentifier m_identifier;
    317317};
    318318
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r254087 r254464  
    11/*
    2  * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2020 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
    44 *
     
    11021102void CodeBlock::propagateTransitions(const ConcurrentJSLocker&, SlotVisitor& visitor)
    11031103{
    1104     UNUSED_PARAM(visitor);
    1105 
    11061104    VM& vm = *m_vm;
    11071105
     
    16541652        for (ByValInfo* byValInfo : jitData->m_byValInfos)
    16551653            visitor.append(byValInfo->cachedSymbol);
     1654        for (StructureStubInfo* stubInfo : jitData->m_stubInfos)
     1655            stubInfo->visitAggregate(visitor);
    16561656    }
    16571657#endif
    16581658
    16591659#if ENABLE(DFG_JIT)
    1660     if (JITCode::isOptimizingJIT(jitType()))
     1660    if (JITCode::isOptimizingJIT(jitType())) {
     1661        DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
     1662        dfgCommon->recordedStatuses.visitAggregate(visitor);
    16611663        visitOSRExitTargets(locker, visitor);
     1664    }
    16621665#endif
    16631666}
  • trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp

    r253298 r254464  
    11/*
    2  * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "GetByIdVariant.h"
    2828
     29#include "CacheableIdentifierInlines.h"
    2930#include "CallLinkStatus.h"
    3031#include "JSCInlines.h"
     
    3435
    3536GetByIdVariant::GetByIdVariant(
    36     Box<Identifier> identifier,
     37    CacheableIdentifier identifier,
    3738    const StructureSet& structureSet, PropertyOffset offset,
    3839    const ObjectPropertyConditionSet& conditionSet,
     
    111112        return false;
    112113
    113     if (m_identifier && (*m_identifier != *other.m_identifier))
     114    if (m_identifier && (m_identifier != other.m_identifier))
    114115        return false;
    115116
     
    157158}
    158159
     160void GetByIdVariant::visitAggregate(SlotVisitor& visitor)
     161{
     162    m_identifier.visitAggregate(visitor);
     163}
     164
    159165void GetByIdVariant::markIfCheap(SlotVisitor& visitor)
    160166{
     
    183189{
    184190    out.print("<");
    185     out.print("id='", m_identifier ? m_identifier->impl() : StringImpl::empty(), "', ");
     191    out.print("id='", m_identifier, "', ");
    186192    if (!isSet()) {
    187193        out.print("empty>");
  • trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h

    r252763 r254464  
    11/*
    2  * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "CacheableIdentifier.h"
    2829#include "CallLinkStatus.h"
    2930#include "ObjectPropertyConditionSet.h"
     
    4546public:
    4647    GetByIdVariant(
    47         Box<Identifier>,
     48        CacheableIdentifier,
    4849        const StructureSet& structureSet = StructureSet(), PropertyOffset offset = invalidOffset,
    4950        const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),
     
    7778    bool attemptToMerge(const GetByIdVariant& other);
    7879   
     80    void visitAggregate(SlotVisitor&);
    7981    void markIfCheap(SlotVisitor&);
    8082    bool finalize(VM&);
     
    8385    void dumpInContext(PrintStream&, DumpContext*) const;
    8486
    85     Box<Identifier> identifier() const { return m_identifier; }
     87    CacheableIdentifier identifier() const { return m_identifier; }
    8688
    8789    bool overlaps(const GetByIdVariant& other)
     
    9092            return true;
    9193        if (m_identifier) {
    92             if (m_identifier->impl() != other.m_identifier->impl())
     94            if (m_identifier != other.m_identifier)
    9395                return false;
    9496        }
     
    108110    FunctionPtr<OperationPtrTag> m_customAccessorGetter;
    109111    std::unique_ptr<DOMAttributeAnnotation> m_domAttribute;
    110     Box<Identifier> m_identifier; // We use this indirection to allow ref/deref in the concurrent compiler.
     112    CacheableIdentifier m_identifier;
    111113};
    112114
  • trunk/Source/JavaScriptCore/bytecode/GetByStatus.cpp

    r253257 r254464  
    11/*
    2  * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828
    2929#include "BytecodeStructs.h"
     30#include "CacheableIdentifierInlines.h"
    3031#include "CodeBlock.h"
    3132#include "ComplexGetStatus.h"
     
    5354}
    5455
    55 GetByStatus GetByStatus::computeFromLLInt(CodeBlock* profiledBlock, BytecodeIndex bytecodeIndex, TrackIdentifiers trackIdentifiers)
     56GetByStatus GetByStatus::computeFromLLInt(CodeBlock* profiledBlock, BytecodeIndex bytecodeIndex)
    5657{
    5758    VM& vm = profiledBlock->vm();
     
    9293    }
    9394
    94     ASSERT_UNUSED(trackIdentifiers, trackIdentifiers == TrackIdentifiers::No); // We could make this work in the future, but nobody needs it right now.
    95 
    9695    if (!structureID)
    9796        return GetByStatus(NoInformation, false);
     
    114113}
    115114
    116 GetByStatus GetByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, ExitFlag didExit, CallLinkStatus::ExitSiteData callExitSiteData, TrackIdentifiers trackIdentifiers, IdentifierKeepAlive& keepAlive)
     115GetByStatus GetByStatus::computeFor(CodeBlock* profiledBlock, ICStatusMap& map, BytecodeIndex bytecodeIndex, ExitFlag didExit, CallLinkStatus::ExitSiteData callExitSiteData)
    117116{
    118117    ConcurrentJSLocker locker(profiledBlock->m_lock);
     
    122121#if ENABLE(DFG_JIT)
    123122    result = computeForStubInfoWithoutExitSiteFeedback(
    124         locker, profiledBlock, map.get(CodeOrigin(bytecodeIndex)).stubInfo, callExitSiteData, trackIdentifiers, keepAlive);
     123        locker, profiledBlock, map.get(CodeOrigin(bytecodeIndex)).stubInfo, callExitSiteData);
    125124   
    126125    if (didExit)
     
    130129    UNUSED_PARAM(didExit);
    131130    UNUSED_PARAM(callExitSiteData);
    132     UNUSED_PARAM(keepAlive);
    133131#endif
    134132
    135133    if (!result)
    136         return computeFromLLInt(profiledBlock, bytecodeIndex, trackIdentifiers);
     134        return computeFromLLInt(profiledBlock, bytecodeIndex);
    137135   
    138136    return result;
     
    169167
    170168GetByStatus GetByStatus::computeForStubInfoWithoutExitSiteFeedback(
    171     const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CallLinkStatus::ExitSiteData callExitSiteData, TrackIdentifiers trackIdentifiers, IdentifierKeepAlive& keepAlive)
     169    const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CallLinkStatus::ExitSiteData callExitSiteData)
    172170{
    173171    StubInfoSummary summary = StructureStubInfo::summary(stubInfo);
     
    187185        if (structure->takesSlowPathInDFGForImpureProperty())
    188186            return GetByStatus(JSC::slowVersion(summary), *stubInfo);
    189         Box<Identifier> identifier = stubInfo->getByIdSelfIdentifier();
    190         keepAlive(identifier);
    191         UniquedStringImpl* uid = identifier->impl();
     187        CacheableIdentifier identifier = stubInfo->getByIdSelfIdentifier();
     188        UniquedStringImpl* uid = identifier.uid();
    192189        RELEASE_ASSERT(uid);
    193         if (trackIdentifiers == TrackIdentifiers::No)
    194             identifier = nullptr;
    195190        GetByIdVariant variant(WTFMove(identifier));
    196191        unsigned attributes;
     
    213208            switch (access.type()) {
    214209            case AccessCase::ModuleNamespaceLoad:
    215                 keepAlive(access.identifier());
    216210                return GetByStatus(access.as<ModuleNamespaceAccessCase>());
    217211            default:
     
    297291
    298292                ASSERT((AccessCase::Miss == access.type() || access.isCustom()) == (access.offset() == invalidOffset));
    299                 Box<Identifier> identifier;
    300                 if (trackIdentifiers == TrackIdentifiers::Yes) {
    301                     identifier = access.identifier();
    302                     keepAlive(identifier);
    303                 }
    304                 GetByIdVariant variant(identifier, StructureSet(structure), complexGetStatus.offset(),
     293                GetByIdVariant variant(access.identifier(), StructureSet(structure), complexGetStatus.offset(),
    305294                    complexGetStatus.conditionSet(), WTFMove(callLinkStatus),
    306295                    intrinsicFunction,
     
    337326GetByStatus GetByStatus::computeFor(
    338327    CodeBlock* profiledBlock, ICStatusMap& baselineMap,
    339     ICStatusContextStack& icContextStack, CodeOrigin codeOrigin, TrackIdentifiers trackIdentifiers, IdentifierKeepAlive& keepAlive)
     328    ICStatusContextStack& icContextStack, CodeOrigin codeOrigin)
    340329{
    341330    BytecodeIndex bytecodeIndex = codeOrigin.bytecodeIndex();
     
    352341                GetByStatus baselineResult = computeFor(
    353342                    profiledBlock, baselineMap, bytecodeIndex, didExit,
    354                     callExitSiteData, trackIdentifiers, keepAlive);
     343                    callExitSiteData);
    355344                baselineResult.merge(result);
    356345                return baselineResult;
     
    366355                ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock);
    367356                result = computeForStubInfoWithoutExitSiteFeedback(
    368                     locker, context->optimizedCodeBlock, status.stubInfo, callExitSiteData, trackIdentifiers, keepAlive);
     357                    locker, context->optimizedCodeBlock, status.stubInfo, callExitSiteData);
    369358            }
    370359            if (result.isSet())
     
    376365    }
    377366   
    378     return computeFor(profiledBlock, baselineMap, bytecodeIndex, didExit, callExitSiteData, trackIdentifiers, keepAlive);
     367    return computeFor(profiledBlock, baselineMap, bytecodeIndex, didExit, callExitSiteData);
    379368}
    380369
     
    515504}
    516505
     506void GetByStatus::visitAggregate(SlotVisitor& visitor)
     507{
     508    if (isModuleNamespace())
     509        m_moduleNamespaceData->m_identifier.visitAggregate(visitor);
     510    for (GetByIdVariant& variant : m_variants)
     511        variant.visitAggregate(visitor);
     512}
     513
    517514void GetByStatus::markIfCheap(SlotVisitor& visitor)
    518515{
     
    536533}
    537534
    538 Box<Identifier> GetByStatus::singleIdentifier() const
    539 {
    540     if (isModuleNamespace()) {
    541         Box<Identifier> result = m_moduleNamespaceData->m_identifier;
    542         if (!result || result->isNull())
    543             return nullptr;
    544         return result;
    545     }
     535CacheableIdentifier GetByStatus::singleIdentifier() const
     536{
     537    if (isModuleNamespace())
     538        return m_moduleNamespaceData->m_identifier;
    546539
    547540    if (m_variants.isEmpty())
    548541        return nullptr;
    549542
    550     Box<Identifier> result = m_variants.first().identifier();
     543    CacheableIdentifier result = m_variants.first().identifier();
    551544    if (!result)
    552545        return nullptr;
    553     if (result->isNull())
    554         return nullptr;
    555546    for (size_t i = 1; i < m_variants.size(); ++i) {
    556         Box<Identifier> uid = m_variants[i].identifier();
    557         if (!uid)
     547        CacheableIdentifier identifier = m_variants[i].identifier();
     548        if (!identifier)
    558549            return nullptr;
    559         if (*uid != *result)
     550        if (identifier != result)
    560551            return nullptr;
    561552    }
  • trunk/Source/JavaScriptCore/bytecode/GetByStatus.h

    r253969 r254464  
    11/*
    2  * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "CacheableIdentifier.h"
    2829#include "CallLinkStatus.h"
    2930#include "CodeOrigin.h"
     
    6768    };
    6869
    69     enum class TrackIdentifiers : uint8_t {
    70         No,  // Used for get_by_id
    71         Yes, // Used for get_by_val
    72     };
    73 
    7470    GetByStatus()
    7571        : m_state(NoInformation)
     
    9288    }
    9389
    94     // If we use a Box<Identifier> in the compiler thread, we need to keep the
    95     // Identifier alive and only deref it in the mutator thread later. This
    96     // ensures that the compiler thread doesn't race against the mutator in
    97     // adjusting the Identifier's refCount.
    98     using IdentifierKeepAlive = std::function<void(Box<Identifier>)>;
    99 
    100     static GetByStatus computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack& dfgContextStack, CodeOrigin, TrackIdentifiers, IdentifierKeepAlive&);
     90    static GetByStatus computeFor(CodeBlock* baselineBlock, ICStatusMap& baselineMap, ICStatusContextStack& dfgContextStack, CodeOrigin);
    10191    static GetByStatus computeFor(const StructureSet&, UniquedStringImpl*);
    10292
     
    129119    ScopeOffset scopeOffset() const { return m_moduleNamespaceData->m_scopeOffset; }
    130120   
     121    void visitAggregate(SlotVisitor&);
    131122    void markIfCheap(SlotVisitor&);
    132123    bool finalize(VM&); // Return true if this gets to live.
     
    136127    void dump(PrintStream&) const;
    137128
    138     Box<Identifier> singleIdentifier() const;
     129    CacheableIdentifier singleIdentifier() const;
    139130   
    140131private:
     
    144135    GetByStatus(const ModuleNamespaceAccessCase&);
    145136    static GetByStatus computeForStubInfoWithoutExitSiteFeedback(
    146         const ConcurrentJSLocker&, CodeBlock* profiledBlock, StructureStubInfo*, CallLinkStatus::ExitSiteData, TrackIdentifiers, IdentifierKeepAlive&);
     137        const ConcurrentJSLocker&, CodeBlock* profiledBlock, StructureStubInfo*, CallLinkStatus::ExitSiteData);
    147138#endif
    148     static GetByStatus computeFromLLInt(CodeBlock*, BytecodeIndex, TrackIdentifiers);
    149     static GetByStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, ExitFlag, CallLinkStatus::ExitSiteData, TrackIdentifiers, IdentifierKeepAlive&);
     139    static GetByStatus computeFromLLInt(CodeBlock*, BytecodeIndex);
     140    static GetByStatus computeFor(CodeBlock*, ICStatusMap&, BytecodeIndex, ExitFlag, CallLinkStatus::ExitSiteData);
    150141
    151142    struct ModuleNamespaceData {
     
    153144        JSModuleEnvironment* m_moduleEnvironment { nullptr };
    154145        ScopeOffset m_scopeOffset { };
    155         Box<Identifier> m_identifier;
     146        CacheableIdentifier m_identifier;
    156147    };
    157148
  • trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp

    r253083 r254464  
    11/*
    2  * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343}
    4444
    45 GetterSetterAccessCase::GetterSetterAccessCase(VM& vm, JSCell* owner, AccessType accessType, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, JSObject* customSlotBase, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     45GetterSetterAccessCase::GetterSetterAccessCase(VM& vm, JSCell* owner, AccessType accessType, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, JSObject* customSlotBase, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    4646    : Base(vm, owner, accessType, identifier, offset, structure, conditionSet, viaProxy, additionalSet, WTFMove(prototypeAccessChain))
    4747{
     
    4949}
    5050
    51 
    5251std::unique_ptr<AccessCase> GetterSetterAccessCase::create(
    53     VM& vm, JSCell* owner, AccessType type, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet,
     52    VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet,
    5453    bool viaProxy, WatchpointSet* additionalSet, FunctionPtr<OperationPtrTag> customGetter, JSObject* customSlotBase,
    5554    Optional<DOMAttributeAnnotation> domAttribute, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     
    7069}
    7170
    72 std::unique_ptr<AccessCase> GetterSetterAccessCase::create(VM& vm, JSCell* owner, AccessType type, Structure* structure, const Identifier& identifier, PropertyOffset offset,
     71std::unique_ptr<AccessCase> GetterSetterAccessCase::create(VM& vm, JSCell* owner, AccessType type, Structure* structure, CacheableIdentifier identifier, PropertyOffset offset,
    7372    const ObjectPropertyConditionSet& conditionSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain, FunctionPtr<OperationPtrTag> customSetter,
    7473    JSObject* customSlotBase)
  • trunk/Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h

    r253361 r254464  
    11/*
    2  * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5555
    5656    static std::unique_ptr<AccessCase> create(
    57         VM&, JSCell* owner, AccessType, const Identifier&, PropertyOffset, Structure*,
     57        VM&, JSCell* owner, AccessType, CacheableIdentifier, PropertyOffset, Structure*,
    5858        const ObjectPropertyConditionSet&, bool viaProxy, WatchpointSet* additionalSet, FunctionPtr<OperationPtrTag> customGetter,
    5959        JSObject* customSlotBase, Optional<DOMAttributeAnnotation>, std::unique_ptr<PolyProtoAccessChain>);
    6060
    61     static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, AccessType, Structure*, const Identifier&, PropertyOffset,
     61    static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, AccessType, Structure*, CacheableIdentifier, PropertyOffset,
    6262        const ObjectPropertyConditionSet&, std::unique_ptr<PolyProtoAccessChain>,
    6363        FunctionPtr<OperationPtrTag> customSetter = nullptr, JSObject* customSlotBase = nullptr);
     
    7171
    7272private:
    73     GetterSetterAccessCase(VM&, JSCell*, AccessType, const Identifier&, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, bool viaProxy, WatchpointSet* additionalSet, JSObject* customSlotBase, std::unique_ptr<PolyProtoAccessChain>);
     73    GetterSetterAccessCase(VM&, JSCell*, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, bool viaProxy, WatchpointSet* additionalSet, JSObject* customSlotBase, std::unique_ptr<PolyProtoAccessChain>);
    7474
    7575    GetterSetterAccessCase(const GetterSetterAccessCase&);
  • trunk/Source/JavaScriptCore/bytecode/InstanceOfAccessCase.cpp

    r252684 r254464  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6060    VM& vm, JSCell* owner, AccessType accessType, Structure* structure,
    6161    const ObjectPropertyConditionSet& conditionSet, JSObject* prototype)
    62     : Base(vm, owner, accessType, Identifier(), invalidOffset, structure, conditionSet, nullptr)
     62    : Base(vm, owner, accessType, nullptr, invalidOffset, structure, conditionSet, nullptr)
    6363    , m_prototype(vm, owner, prototype)
    6464{
  • trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp

    r252684 r254464  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3333namespace JSC {
    3434
    35 IntrinsicGetterAccessCase::IntrinsicGetterAccessCase(VM& vm, JSCell* owner, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     35IntrinsicGetterAccessCase::IntrinsicGetterAccessCase(VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    3636    : Base(vm, owner, IntrinsicGetter, identifier, offset, structure, conditionSet, WTFMove(prototypeAccessChain))
    3737{
     
    3939}
    4040
    41 std::unique_ptr<AccessCase> IntrinsicGetterAccessCase::create(VM& vm, JSCell* owner, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     41std::unique_ptr<AccessCase> IntrinsicGetterAccessCase::create(VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    4242{
    4343    return std::unique_ptr<AccessCase>(new IntrinsicGetterAccessCase(vm, owner, identifier, offset, structure, conditionSet, intrinsicFunction, WTFMove(prototypeAccessChain)));
  • trunk/Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.h

    r252684 r254464  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343    void emitIntrinsicGetter(AccessGenerationState&);
    4444
    45     static std::unique_ptr<AccessCase> create(VM&, JSCell*, const Identifier&, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain>);
     45    static std::unique_ptr<AccessCase> create(VM&, JSCell*, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain>);
    4646
    4747    std::unique_ptr<AccessCase> clone() const override;
     
    5050
    5151private:
    52     IntrinsicGetterAccessCase(VM&, JSCell*, const Identifier&, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain>);
     52    IntrinsicGetterAccessCase(VM&, JSCell*, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, std::unique_ptr<PolyProtoAccessChain>);
    5353
    5454    WriteBarrier<JSFunction> m_intrinsicFunction;
  • trunk/Source/JavaScriptCore/bytecode/ModuleNamespaceAccessCase.cpp

    r252684 r254464  
    11/*
    22 * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>.
     3 * Copyright (C) 2020 Apple Inc. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    3839namespace JSC {
    3940
    40 ModuleNamespaceAccessCase::ModuleNamespaceAccessCase(VM& vm, JSCell* owner, const Identifier& identifier, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)
     41ModuleNamespaceAccessCase::ModuleNamespaceAccessCase(VM& vm, JSCell* owner, CacheableIdentifier identifier, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)
    4142    : Base(vm, owner, ModuleNamespaceLoad, identifier, invalidOffset, nullptr, ObjectPropertyConditionSet(), nullptr)
    4243    , m_scopeOffset(scopeOffset)
     
    4647}
    4748
    48 std::unique_ptr<AccessCase> ModuleNamespaceAccessCase::create(VM& vm, JSCell* owner, const Identifier& identifier, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)
     49std::unique_ptr<AccessCase> ModuleNamespaceAccessCase::create(VM& vm, JSCell* owner, CacheableIdentifier identifier, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)
    4950{
    5051    return std::unique_ptr<AccessCase>(new ModuleNamespaceAccessCase(vm, owner, identifier, moduleNamespaceObject, moduleEnvironment, scopeOffset));
  • trunk/Source/JavaScriptCore/bytecode/ModuleNamespaceAccessCase.h

    r252684 r254464  
    11/*
    22 * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>.
     3 * Copyright (C) 2020 Apple Inc. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    4445    ScopeOffset scopeOffset() const { return m_scopeOffset; }
    4546
    46     static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, const Identifier&, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);
     47    static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, CacheableIdentifier, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);
    4748
    4849    std::unique_ptr<AccessCase> clone() const override;
     
    5354
    5455private:
    55     ModuleNamespaceAccessCase(VM&, JSCell* owner, const Identifier&, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);
     56    ModuleNamespaceAccessCase(VM&, JSCell* owner, CacheableIdentifier, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);
    5657
    5758    WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject;
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp

    r253987 r254464  
    11/*
    2  * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "BinarySwitch.h"
    3232#include "CCallHelpers.h"
     33#include "CacheableIdentifierInlines.h"
    3334#include "CodeBlock.h"
    3435#include "FullCodeOrigin.h"
     
    351352        result &= at(i).propagateTransitions(visitor);
    352353    return result;
     354}
     355
     356void PolymorphicAccess::visitAggregate(SlotVisitor& visitor)
     357{
     358    for (unsigned i = 0; i < size(); ++i)
     359        at(i).visitAggregate(visitor);
    353360}
    354361
     
    473480        allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
    474481
    475    
    476482    bool generatedFinalCode = false;
    477483
     
    482488        while (!cases.isEmpty())
    483489            m_list.append(cases.takeLast());
    484         cases.append(AccessCase::create(vm, codeBlock, AccessCase::InstanceOfGeneric, Identifier()));
     490        cases.append(AccessCase::create(vm, codeBlock, AccessCase::InstanceOfGeneric, nullptr));
    485491        generatedFinalCode = true;
    486492    }
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h

    r253987 r254464  
    11/*
    2  * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    152152    const AccessCase& operator[](unsigned i) const { return *m_list[i]; }
    153153
     154    void visitAggregate(SlotVisitor&);
     155
    154156    // If this returns false then we are requesting a reset of the owning StructureStubInfo.
    155157    bool visitWeak(VM&) const;
  • trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.cpp

    r252684 r254464  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131namespace JSC {
    3232
    33 ProxyableAccessCase::ProxyableAccessCase(VM& vm, JSCell* owner, AccessType accessType, const Identifier& identifier, PropertyOffset offset, Structure* structure,
     33ProxyableAccessCase::ProxyableAccessCase(VM& vm, JSCell* owner, AccessType accessType, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure,
    3434    const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    3535    : Base(vm, owner, accessType, identifier, offset, structure, conditionSet, WTFMove(prototypeAccessChain))
     
    3939}
    4040
    41 std::unique_ptr<AccessCase> ProxyableAccessCase::create(VM& vm, JSCell* owner, AccessType type, const Identifier& identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
     41std::unique_ptr<AccessCase> ProxyableAccessCase::create(VM& vm, JSCell* owner, AccessType type, CacheableIdentifier identifier, PropertyOffset offset, Structure* structure, const ObjectPropertyConditionSet& conditionSet, bool viaProxy, WatchpointSet* additionalSet, std::unique_ptr<PolyProtoAccessChain> prototypeAccessChain)
    4242{
    4343    ASSERT(type == Load || type == Miss || type == GetGetter);
  • trunk/Source/JavaScriptCore/bytecode/ProxyableAccessCase.h

    r252684 r254464  
    11/*
    2  * Copyright (C) 2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3838    WatchpointSet* additionalSet() const override { return m_additionalSet.get(); }
    3939
    40     static std::unique_ptr<AccessCase> create(VM&, JSCell*, AccessType, const Identifier&, PropertyOffset, Structure*, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),
     40    static std::unique_ptr<AccessCase> create(VM&, JSCell*, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),
    4141        bool viaProxy = false, WatchpointSet* additionalSet = nullptr, std::unique_ptr<PolyProtoAccessChain> = nullptr);
    4242
     
    4747
    4848protected:
    49     ProxyableAccessCase(VM&, JSCell*, AccessType, const Identifier&, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, bool viaProxy, WatchpointSet* additionalSet, std::unique_ptr<PolyProtoAccessChain>);
     49    ProxyableAccessCase(VM&, JSCell*, AccessType, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, bool viaProxy, WatchpointSet* additionalSet, std::unique_ptr<PolyProtoAccessChain>);
    5050
    5151private:
  • trunk/Source/JavaScriptCore/bytecode/RecordedStatuses.cpp

    r252684 r254464  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7676}
    7777
     78void RecordedStatuses::visitAggregate(SlotVisitor& slotVisitor)
     79{
     80    for (auto& pair : gets)
     81        pair.second->visitAggregate(slotVisitor);
     82}
     83
    7884void RecordedStatuses::markIfCheap(SlotVisitor& slotVisitor)
    7985{
  • trunk/Source/JavaScriptCore/bytecode/RecordedStatuses.h

    r252684 r254464  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4949    InByIdStatus* addInByIdStatus(const CodeOrigin&, const InByIdStatus&);
    5050   
    51     void markIfCheap(SlotVisitor& slotVisitor);
     51    void visitAggregate(SlotVisitor&);
     52    void markIfCheap(SlotVisitor&);
    5253   
    5354    void finalizeWithoutDeleting(VM&);
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp

    r254087 r254464  
    11/*
    2  * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "StructureStubInfo.h"
    2828
     29#include "CacheableIdentifierInlines.h"
    2930#include "JSObject.h"
    3031#include "JSCInlines.h"
     
    6364}
    6465
    65 void StructureStubInfo::initGetByIdSelf(CodeBlock* codeBlock, Structure* baseObjectStructure, PropertyOffset offset, const Identifier& identifier)
     66void StructureStubInfo::initGetByIdSelf(CodeBlock* codeBlock, Structure* baseObjectStructure, PropertyOffset offset, CacheableIdentifier identifier)
    6667{
    6768    ASSERT(hasConstantIdentifier);
    6869    setCacheType(CacheType::GetByIdSelf);
    69     m_getByIdSelfIdentifier = Box<Identifier>::create(identifier);
     70    m_getByIdSelfIdentifier = identifier;
     71    codeBlock->vm().heap.writeBarrier(codeBlock);
    7072   
    7173    u.byIdSelf.baseObjectStructure.set(
     
    139141
    140142AccessGenerationResult StructureStubInfo::addAccessCase(
    141     const GCSafeConcurrentJSLocker& locker, CodeBlock* codeBlock, const Identifier& ident, std::unique_ptr<AccessCase> accessCase)
     143    const GCSafeConcurrentJSLocker& locker, CodeBlock* codeBlock, CacheableIdentifier ident, std::unique_ptr<AccessCase> accessCase)
    142144{
    143145    checkConsistency();
     
    195197        }
    196198       
     199        ASSERT(m_cacheType == CacheType::Stub);
    197200        RELEASE_ASSERT(!result.generatedSomeCode());
    198201       
     
    278281    deref();
    279282    setCacheType(CacheType::Unset);
     283}
     284
     285void StructureStubInfo::visitAggregate(SlotVisitor& visitor)
     286{
     287    switch (m_cacheType) {
     288    case CacheType::Unset:
     289    case CacheType::ArrayLength:
     290    case CacheType::StringLength:
     291    case CacheType::PutByIdReplace:
     292    case CacheType::InByIdSelf:
     293        return;
     294    case CacheType::GetByIdSelf:
     295        m_getByIdSelfIdentifier.visitAggregate(visitor);
     296        return;
     297    case CacheType::Stub:
     298        u.stub->visitAggregate(visitor);
     299        return;
     300    }
     301   
     302    RELEASE_ASSERT_NOT_REACHED();
     303    return;
    280304}
    281305
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h

    r254087 r254464  
    11/*
    2  * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include "CacheableIdentifier.h"
    2829#include "CodeBlock.h"
    2930#include "CodeOrigin.h"
     
    7576    ~StructureStubInfo();
    7677
    77     void initGetByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset, const Identifier&);
     78    void initGetByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset, CacheableIdentifier);
    7879    void initArrayLength();
    7980    void initStringLength();
     
    8182    void initInByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
    8283
    83     AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, CodeBlock*, const Identifier&, std::unique_ptr<AccessCase>);
     84    AccessGenerationResult addAccessCase(const GCSafeConcurrentJSLocker&, CodeBlock*, CacheableIdentifier, std::unique_ptr<AccessCase>);
    8485
    8586    void reset(CodeBlock*);
     
    8788    void deref();
    8889    void aboutToDie();
     90
     91    void visitAggregate(SlotVisitor&);
    8992
    9093    // Check if the stub has weak references that are dead. If it does, then it resets itself,
     
    172175    CodeOrigin codeOrigin;
    173176private:
    174     Box<Identifier> m_getByIdSelfIdentifier;
     177    CacheableIdentifier m_getByIdSelfIdentifier;
    175178public:
    176179
     
    183186    } u;
    184187
    185     Box<Identifier> getByIdSelfIdentifier()
     188    CacheableIdentifier getByIdSelfIdentifier()
    186189    {
    187190        RELEASE_ASSERT(m_cacheType == CacheType::GetByIdSelf);
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r254252 r254464  
    11/*
    2  * Copyright (C) 2011-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535#include "BytecodeGenerator.h"
    3636#include "BytecodeUseDef.h"
     37#include "CacheableIdentifierInlines.h"
    3738#include "CallLinkStatus.h"
    3839#include "CodeBlock.h"
     
    48324833        type = AccessType::GetByIdDirect;
    48334834   
    4834     GetByStatus::IdentifierKeepAlive keepAlive = [&] (Box<Identifier> identifier) {
    4835         m_graph.m_plan.keepAliveIdentifier(WTFMove(identifier));
    4836     };
    48374835    GetByStatus getByStatus = GetByStatus::computeFor(
    48384836        m_inlineStackTop->m_profiledBlock,
    48394837        m_inlineStackTop->m_baselineMap, m_icContextStack,
    4840         currentCodeOrigin(), GetByStatus::TrackIdentifiers::No, keepAlive);
     4838        currentCodeOrigin());
    48414839
    48424840    handleGetById(
     
    57395737            Node* property = get(bytecode.m_property);
    57405738            bool shouldCompileAsGetById = false;
    5741             GetByStatus::IdentifierKeepAlive keepAlive = [&] (Box<Identifier> identifier) {
    5742                 m_graph.m_plan.keepAliveIdentifier(WTFMove(identifier));
    5743             };
    5744             GetByStatus getByStatus = GetByStatus::computeFor(m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_baselineMap, m_icContextStack, currentCodeOrigin(), GetByStatus::TrackIdentifiers::Yes, keepAlive);
     5739            GetByStatus getByStatus = GetByStatus::computeFor(m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_baselineMap, m_icContextStack, currentCodeOrigin());
    57455740
    57465741            unsigned identifierNumber = 0;
     
    57535748                // That way, we could both switch on multiple structures and multiple identifiers (or int 32 properties).
    57545749                // https://bugs.webkit.org/show_bug.cgi?id=204216
    5755                 if (Box<Identifier> impl = getByStatus.singleIdentifier()) {
    5756                     identifierNumber = m_graph.identifiers().ensure(impl);
     5750                if (CacheableIdentifier identifier = getByStatus.singleIdentifier()) {
     5751                    UniquedStringImpl* uid = identifier.uid();
     5752                    identifierNumber = m_graph.identifiers().ensure(identifier.uid());
     5753                    if (identifier.isCell()) {
     5754                        FrozenValue* frozen = m_graph.freezeStrong(identifier.cell());
     5755                        if (identifier.isSymbolCell())
     5756                            addToGraph(CheckCell, OpInfo(frozen), property);
     5757                        else
     5758                            addToGraph(CheckIdent, OpInfo(uid), property);
     5759                    } else
     5760                        addToGraph(CheckIdent, OpInfo(uid), property);
    57575761                    shouldCompileAsGetById = true;
    5758                     addToGraph(CheckIdent, OpInfo(impl->impl()), property);
    57595762                }
    57605763            }
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredIdentifiers.cpp

    r252684 r254464  
    11/*
    2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5656}
    5757
    58 void DesiredIdentifiers::processCodeBlockIdentifiersIfNeeded()
     58unsigned DesiredIdentifiers::ensure(UniquedStringImpl* rep)
    5959{
    6060    if (!m_didProcessIdentifiers) {
     
    6565        m_didProcessIdentifiers = true;
    6666    }
    67 }
    68 
    69 unsigned DesiredIdentifiers::ensure(UniquedStringImpl* rep)
    70 {
    71     processCodeBlockIdentifiersIfNeeded();
    7267
    7368    auto addResult = m_identifierNumberForName.add(rep, numberOfIdentifiers());
     
    8075}
    8176
    82 unsigned DesiredIdentifiers::ensure(Box<Identifier> rep)
    83 {
    84     processCodeBlockIdentifiersIfNeeded();
    85 
    86     UniquedStringImpl* impl = rep->impl();
    87     auto addResult = m_identifierNumberForName.add(impl, numberOfIdentifiers());
    88     unsigned result = addResult.iterator->value;
    89     if (addResult.isNewEntry) {
    90         m_addedIdentifiers.append(WTFMove(rep));
    91         ASSERT(at(result) == impl);
    92     }
    93     return result;
    94 }
    95 
    9677UniquedStringImpl* DesiredIdentifiers::at(unsigned index) const
    9778{
     
    9980    if (index < m_codeBlock->numberOfIdentifiers())
    10081        result = m_codeBlock->identifier(index).impl();
    101     else {
    102         const auto& variant = m_addedIdentifiers[index - m_codeBlock->numberOfIdentifiers()];
    103         if (WTF::holds_alternative<UniquedStringImpl*>(variant))
    104             result = WTF::get<UniquedStringImpl*>(variant);
    105         else
    106             result = WTF::get<Box<Identifier>>(variant)->impl();
    107     }
     82    else
     83        result = m_addedIdentifiers[index - m_codeBlock->numberOfIdentifiers()];
    10884    ASSERT(result->hasAtLeastOneRef());
    10985    return result;
     
    11288void DesiredIdentifiers::reallyAdd(VM& vm, CommonData* commonData)
    11389{
    114     for (const auto& variant : m_addedIdentifiers) {
    115         UniquedStringImpl* rep;
    116         if (WTF::holds_alternative<UniquedStringImpl*>(variant))
    117             rep = WTF::get<UniquedStringImpl*>(variant);
    118         else
    119             rep = WTF::get<Box<Identifier>>(variant)->impl();
    120 
     90    for (auto rep : m_addedIdentifiers) {
    12191        ASSERT(rep->hasAtLeastOneRef());
    12292        Identifier uid = Identifier::fromUid(vm, rep);
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredIdentifiers.h

    r253538 r254464  
    11/*
    2  * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "Identifier.h"
    3131#include <wtf/HashMap.h>
    32 #include <wtf/Variant.h>
    3332#include <wtf/text/UniquedStringImpl.h>
    3433
     
    5049    unsigned numberOfIdentifiers();
    5150    unsigned ensure(UniquedStringImpl*);
    52     unsigned ensure(Box<Identifier>);
    5351   
    5452    UniquedStringImpl* at(unsigned index) const;
     
    6260
    6361    CodeBlock* m_codeBlock;
    64     Vector<Variant<UniquedStringImpl*, Box<Identifier>>> m_addedIdentifiers;
     62    Vector<UniquedStringImpl*> m_addedIdentifiers;
    6563    HashMap<UniquedStringImpl*, unsigned> m_identifierNumberForName;
    6664    bool m_didProcessIdentifiers;
  • trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp

    r249706 r254464  
    11/*
    2  * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8282void JITFinalizer::finalizeCommon()
    8383{
     84    CodeBlock* codeBlock = m_plan.codeBlock();
     85
    8486    // Some JIT finalizers may have added more constants. Shrink-to-fit those things now.
    8587    {
    86         ConcurrentJSLocker locker(m_plan.codeBlock()->m_lock);
    87         m_plan.codeBlock()->constants().shrinkToFit();
    88         m_plan.codeBlock()->constantsSourceCodeRepresentation().shrinkToFit();
     88        ConcurrentJSLocker locker(codeBlock->m_lock);
     89        codeBlock->constants().shrinkToFit();
     90        codeBlock->constantsSourceCodeRepresentation().shrinkToFit();
    8991    }
    9092
    9193#if ENABLE(FTL_JIT)
    92     m_jitCode->optimizeAfterWarmUp(m_plan.codeBlock());
     94    m_jitCode->optimizeAfterWarmUp(codeBlock);
    9395#endif // ENABLE(FTL_JIT)
    9496
    9597    if (UNLIKELY(m_plan.compilation()))
    96         m_plan.vm()->m_perBytecodeProfiler->addCompilation(m_plan.codeBlock(), *m_plan.compilation());
     98        m_plan.vm()->m_perBytecodeProfiler->addCompilation(codeBlock, *m_plan.compilation());
    9799
    98100    if (!m_plan.willTryToTierUp())
    99         m_plan.codeBlock()->baselineVersion()->m_didFailFTLCompilation = true;
     101        codeBlock->baselineVersion()->m_didFailFTLCompilation = true;
     102
     103    // The codeBlock is now responsible for keeping many things alive (e.g. frozen values)
     104    // that were previously kept alive by the plan.
     105    m_plan.vm()->heap.writeBarrier(codeBlock);
    100106}
    101107
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r253243 r254464  
    11/*
    2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8080#include "TrackedReferences.h"
    8181#include "VMInlines.h"
    82 #include <wtf/Threading.h>
    8382
    8483#if ENABLE(FTL_JIT)
     
    156155Plan::~Plan()
    157156{
    158     RELEASE_ASSERT(unnukedVM()->currentThreadIsHoldingAPILock());
    159157}
    160158
     
    658656    }
    659657
     658    m_recordedStatuses.visitAggregate(visitor);
    660659    m_recordedStatuses.markIfCheap(visitor);
    661660
     
    697696{
    698697    RELEASE_ASSERT(m_stage != Cancelled);
    699 
    700     // When we cancel a plan, there's a chance that the compiler thread may have
    701     // already ref'ed it and is working on it. This results in a race where the
    702     // compiler thread may hold the last reference to the plan. We require that
    703     // the plan is only destructed on the mutator thread because we piggy back
    704     // on the plan to ensure certain other objects are only destructed on the
    705     // mutator thread. For example, see Plan::m_identifiersKeptAliveForCleanUp.
    706     //
    707     // To ensure that the plan is destructed on the mutator and not the compiler
    708     // thread, the compiler thread will enqueue any cancelled plan it sees in
    709     // the worklist's m_cancelledPlansPendingDestruction. The mutator will later
    710     // delete the cancelled plans in m_cancelledPlansPendingDestruction.
    711     // However, a mutator should only delete cancelled plans that belong to its
    712     // VM. Hence, a cancelled plan needs to keep its m_vm pointer to let the
    713     // mutator know which VM it belongs to.
    714     // Ref: See Worklist::deleteCancelledPlansForVM().
    715698    ASSERT(m_vm);
    716699
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.h

    r253243 r254464  
    11/*
    2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939#include "ProfilerCompilation.h"
    4040#include "RecordedStatuses.h"
    41 #include <wtf/Box.h>
    4241#include <wtf/HashMap.h>
    4342#include <wtf/ThreadSafeRefCounted.h>
     
    118117    void setCallback(Ref<DeferredCompilationCallback>&& callback) { m_callback = WTFMove(callback); }
    119118
    120     void keepAliveIdentifier(Box<Identifier> identifier)
    121     {
    122         if (identifier)
    123             m_identifiersKeptAliveForCleanUp.append(WTFMove(identifier));
    124     }
    125 
    126119private:
    127120    bool computeCompileTimes() const;
     
    182175
    183176    RefPtr<DeferredCompilationCallback> m_callback;
    184     Vector<Box<Identifier>, 16> m_identifiersKeptAliveForCleanUp;
    185177
    186178    MonotonicTime m_timeBeforeFTL;
  • trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp

    r253358 r254464  
    11/*
    2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    101101        {
    102102            LockHolder locker(*m_worklist.m_lock);
    103             if (m_plan->stage() == Plan::Cancelled) {
    104                 m_worklist.m_cancelledPlansPendingDestruction.append(WTFMove(m_plan));
     103            if (m_plan->stage() == Plan::Cancelled)
    105104                return WorkResult::Continue;
    106             }
    107105            m_plan->notifyCompiling();
    108106        }
     
    126124        {
    127125            LockHolder locker(*m_worklist.m_lock);
    128             if (m_plan->stage() == Plan::Cancelled) {
    129                 m_worklist.m_cancelledPlansPendingDestruction.append(WTFMove(m_plan));
     126            if (m_plan->stage() == Plan::Cancelled)
    130127                return WorkResult::Continue;
    131             }
    132128           
    133129            m_plan->notifyReady();
     
    305301}
    306302
    307 void Worklist::deleteCancelledPlansForVM(LockHolder&, VM& vm)
    308 {
    309     RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock());
    310     HashSet<RefPtr<Plan>> removedPlans;
    311 
    312     // The following scenario can occur:
    313     // 1. The DFG thread started compiling a plan.
    314     // 2. The GC thread cancels the plan, and adds it to m_cancelledPlansPendingDestruction.
    315     // 3. The DFG thread finishes compiling, and discovers that the thread is cancelled.
    316     //    To avoid destructing the plan in the DFG thread, it adds it to
    317     //    m_cancelledPlansPendingDestruction.
    318     // 4. The above occurs before the mutator runs deleteCancelledPlansForVM().
    319     //
    320     // Hence, the same cancelled plan can appear in m_cancelledPlansPendingDestruction
    321     // more than once. This is why we need to filter the cancelled plans through
    322     // the removedPlans HashSet before we do the refCount check below.
    323 
    324     for (size_t i = 0; i < m_cancelledPlansPendingDestruction.size(); ++i) {
    325         RefPtr<Plan> plan = m_cancelledPlansPendingDestruction[i];
    326         if (plan->unnukedVM() != &vm)
    327             continue;
    328         m_cancelledPlansPendingDestruction[i--] = m_cancelledPlansPendingDestruction.last();
    329         m_cancelledPlansPendingDestruction.removeLast();
    330         removedPlans.add(WTFMove(plan));
    331     }
    332 
    333     while (!removedPlans.isEmpty()) {
    334         RefPtr<Plan> plan = removedPlans.takeAny();
    335         ASSERT(plan->stage() == Plan::Cancelled);
    336         if (plan->refCount() > 1)
    337             m_cancelledPlansPendingDestruction.append(WTFMove(plan));
    338     }
    339 }
    340 
    341303void Worklist::removeAllReadyPlansForVM(VM& vm, Vector<RefPtr<Plan>, 8>& myReadyPlans)
    342304{
    343305    DeferGC deferGC(vm.heap);
    344306    LockHolder locker(*m_lock);
    345     ASSERT(vm.currentThreadIsHoldingAPILock());
    346 
    347     deleteCancelledPlansForVM(locker, vm);
    348307    for (size_t i = 0; i < m_readyPlans.size(); ++i) {
    349308        RefPtr<Plan> plan = m_readyPlans[i];
     
    448407        LockHolder locker(*m_lock);
    449408        HashSet<CompilationKey> deadPlanKeys;
    450         bool isInMutator = vm.currentThreadIsHoldingAPILock();
    451 
    452409        for (PlanMap::iterator iter = m_plans.begin(); iter != m_plans.end(); ++iter) {
    453410            Plan* plan = iter->value.get();
     
    463420        }
    464421        if (!deadPlanKeys.isEmpty()) {
    465             for (HashSet<CompilationKey>::iterator iter = deadPlanKeys.begin(); iter != deadPlanKeys.end(); ++iter) {
    466                 RefPtr<Plan> plan = m_plans.take(*iter);
    467                 plan->cancel();
    468                 if (!isInMutator)
    469                     m_cancelledPlansPendingDestruction.append(WTFMove(plan));
    470             }
     422            for (HashSet<CompilationKey>::iterator iter = deadPlanKeys.begin(); iter != deadPlanKeys.end(); ++iter)
     423                m_plans.take(*iter)->cancel();
    471424            Deque<RefPtr<Plan>> newQueue;
    472425            while (!m_queue.isEmpty()) {
     
    504457    HashSet<CompilationKey> deadPlanKeys;
    505458    Vector<RefPtr<Plan>> deadPlans;
    506     ASSERT(vm.currentThreadIsHoldingAPILock());
    507 
    508     deleteCancelledPlansForVM(locker, vm);
    509459    for (auto& entry : m_plans) {
    510460        Plan* plan = entry.value.get();
  • trunk/Source/JavaScriptCore/dfg/DFGWorklist.h

    r253243 r254464  
    11/*
    2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    9494   
    9595    void removeAllReadyPlansForVM(VM&, Vector<RefPtr<Plan>, 8>&);
    96     void deleteCancelledPlansForVM(LockHolder&, VM&);
    9796
    9897    void dump(const AbstractLocker&, PrintStream&) const;
     
    115114    // be completed.
    116115    Vector<RefPtr<Plan>, 16> m_readyPlans;
    117     Vector<RefPtr<Plan>, 4> m_cancelledPlansPendingDestruction;
    118116    Ref<AutomaticThreadCondition> m_planEnqueued;
    119117    Condition m_planCompiled;
  • trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp

    r244764 r254464  
    11/*
    2  * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7272bool JITFinalizer::finalizeCommon()
    7373{
     74    CodeBlock* codeBlock = m_plan.codeBlock();
    7475    bool dumpDisassembly = shouldDumpDisassembly() || Options::asyncDisassembly();
    75    
     76
    7677    MacroAssemblerCodeRef<JSEntryPtrTag> b3CodeRef =
    7778        FINALIZE_CODE_IF(dumpDisassembly, *b3CodeLinkBuffer, JSEntryPtrTag,
    78             "FTL B3 code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock(), JITType::FTLJIT)).data());
     79            "FTL B3 code for %s", toCString(CodeBlockWithJITType(codeBlock, JITType::FTLJIT)).data());
    7980
    8081    MacroAssemblerCodeRef<JSEntryPtrTag> arityCheckCodeRef = entrypointLinkBuffer
    8182        ? FINALIZE_CODE_IF(dumpDisassembly, *entrypointLinkBuffer, JSEntryPtrTag,
    82             "FTL entrypoint thunk for %s with B3 generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock(), JITType::FTLJIT)).data(), function)
     83            "FTL entrypoint thunk for %s with B3 generated code at %p", toCString(CodeBlockWithJITType(codeBlock, JITType::FTLJIT)).data(), function)
    8384        : MacroAssemblerCodeRef<JSEntryPtrTag>::createSelfManagedCodeRef(b3CodeRef.code());
    8485
     
    8687    jitCode->initializeArityCheckEntrypoint(arityCheckCodeRef);
    8788
    88     m_plan.codeBlock()->setJITCode(*jitCode);
     89    codeBlock->setJITCode(*jitCode);
    8990
    9091    if (UNLIKELY(m_plan.compilation()))
    91         m_plan.vm()->m_perBytecodeProfiler->addCompilation(m_plan.codeBlock(), *m_plan.compilation());
     92        m_plan.vm()->m_perBytecodeProfiler->addCompilation(codeBlock, *m_plan.compilation());
     93
     94    // The codeBlock is now responsible for keeping many things alive (e.g. frozen values)
     95    // that were previously kept alive by the plan.
     96    m_plan.vm()->heap.writeBarrier(codeBlock);
    9297
    9398    return true;
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r253896 r254464  
    11/*
    2  * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "ArithProfile.h"
    3232#include "ArrayConstructor.h"
     33#include "CacheableIdentifierInlines.h"
    3334#include "CommonSlowPaths.h"
    3435#include "DFGCompilationMode.h"
     
    20292030    }
    20302031
    2031     if (baseValue.isCell() && isStringOrSymbol(subscript)) {
     2032    if (baseValue.isCell() && CacheableIdentifier::isCacheableIdentifierCell(subscript)) {
    20322033        const Identifier propertyName = subscript.toPropertyKey(globalObject);
    20332034        RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
    20382039               
    20392040                if (stubInfo->considerCaching(vm, codeBlock, baseValue.structureOrNull(), propertyName.impl()))
    2040                     repatchGetBy(globalObject, codeBlock, baseValue, propertyName, slot, *stubInfo, GetByKind::NormalByVal);
     2041                    repatchGetBy(globalObject, codeBlock, baseValue, subscript.asCell(), slot, *stubInfo, GetByKind::NormalByVal);
    20412042                return found ? slot.getValue(globalObject, propertyName) : jsUndefined();
    20422043            }));
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r254087 r254464  
    11/*
    2  * Copyright (C) 2011-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "BinarySwitch.h"
    3232#include "CCallHelpers.h"
     33#include "CacheableIdentifierInlines.h"
    3334#include "CallFrameShuffler.h"
    3435#include "DFGOperations.h"
     
    179180}
    180181
    181 static InlineCacheAction tryCacheGetBy(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByKind kind)
     182static InlineCacheAction tryCacheGetBy(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSValue baseValue, CacheableIdentifier propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByKind kind)
    182183{
    183184    VM& vm = globalObject->vm();
     
    269270                bool generatedCodeInline = InlineAccess::generateSelfPropertyAccess(stubInfo, structure, slot.cachedOffset());
    270271                if (generatedCodeInline) {
    271                     LOG_IC((ICEvent::GetBySelfPatch, structure->classInfo(), propertyName, slot.slotBase() == baseValue));
     272                    LOG_IC((ICEvent::GetBySelfPatch, structure->classInfo(), Identifier::fromUid(vm, propertyName.uid()), slot.slotBase() == baseValue));
    272273                    structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
    273274                    ftlThunkAwareRepatchCall(codeBlock, stubInfo.slowPathCallLocation, appropriateOptimizingGetByFunction(kind));
     
    320321                        if (!prototypeAccessChain)
    321322                            return GiveUpOnCache;
    322                         RELEASE_ASSERT(slot.isCacheableCustom() || prototypeAccessChain->slotBaseStructure(structure)->get(vm, propertyName) == offset);
     323                        RELEASE_ASSERT(slot.isCacheableCustom() || prototypeAccessChain->slotBaseStructure(structure)->get(vm, propertyName.uid()) == offset);
    323324                    } else {
    324325                        // We use ObjectPropertyConditionSet instead for faster accesses.
     
    329330                        if (slot.isUnset()) {
    330331                            conditionSet = generateConditionsForPropertyMiss(
    331                                 vm, codeBlock, globalObject, structure, propertyName.impl());
     332                                vm, codeBlock, globalObject, structure, propertyName.uid());
    332333                        } else if (!slot.isCacheableCustom()) {
    333334                            conditionSet = generateConditionsForPrototypePropertyHit(
    334335                                vm, codeBlock, globalObject, structure, slot.slotBase(),
    335                                 propertyName.impl());
     336                                propertyName.uid());
    336337                            RELEASE_ASSERT(!conditionSet.isValid() || conditionSet.slotBaseCondition().offset() == offset);
    337338                        } else {
    338339                            conditionSet = generateConditionsForPrototypePropertyHitCustom(
    339340                                vm, codeBlock, globalObject, structure, slot.slotBase(),
    340                                 propertyName.impl(), slot.attributes());
     341                                propertyName.uid(), slot.attributes());
    341342                        }
    342343
     
    394395        }
    395396
    396         LOG_IC((ICEvent::GetByAddAccessCase, baseValue.classInfoOrNull(vm), propertyName, slot.slotBase() == baseValue));
     397        LOG_IC((ICEvent::GetByAddAccessCase, baseValue.classInfoOrNull(vm), Identifier::fromUid(vm, propertyName.uid()), slot.slotBase() == baseValue));
    397398
    398399        result = stubInfo.addAccessCase(locker, codeBlock, propertyName, WTFMove(newCase));
    399400
    400401        if (result.generatedSomeCode()) {
    401             LOG_IC((ICEvent::GetByReplaceWithJump, baseValue.classInfoOrNull(vm), propertyName, slot.slotBase() == baseValue));
     402            LOG_IC((ICEvent::GetByReplaceWithJump, baseValue.classInfoOrNull(vm), Identifier::fromUid(vm, propertyName.uid()), slot.slotBase() == baseValue));
    402403           
    403404            RELEASE_ASSERT(result.code());
     
    411412}
    412413
    413 void repatchGetBy(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByKind kind)
     414void repatchGetBy(JSGlobalObject* globalObject, CodeBlock* codeBlock, JSValue baseValue, CacheableIdentifier propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo, GetByKind kind)
    414415{
    415416    SuperSamplerScope superSamplerScope(false);
     
    495496        }
    496497
    497         result = stubInfo.addAccessCase(locker, codeBlock, Identifier(), AccessCase::create(vm, codeBlock, accessType, Identifier()));
     498        result = stubInfo.addAccessCase(locker, codeBlock, nullptr, AccessCase::create(vm, codeBlock, accessType, nullptr));
    498499
    499500        if (result.generatedSomeCode()) {
     
    885886        LOG_IC((ICEvent::InstanceOfAddAccessCase, structure->classInfo(), Identifier()));
    886887       
    887         result = stubInfo.addAccessCase(locker, codeBlock, Identifier(), WTFMove(newCase));
     888        result = stubInfo.addAccessCase(locker, codeBlock, nullptr, WTFMove(newCase));
    888889       
    889890        if (result.generatedSomeCode()) {
  • trunk/Source/JavaScriptCore/jit/Repatch.h

    r252684 r254464  
    11/*
    2  * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#if ENABLE(JIT)
    2929
     30#include "CacheableIdentifier.h"
    3031#include "CallVariant.h"
    3132#include "PutKind.h"
     
    4243
    4344void repatchArrayGetByVal(JSGlobalObject*, CodeBlock*, JSValue base, JSValue index, StructureStubInfo&);
    44 void repatchGetBy(JSGlobalObject*, CodeBlock*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&, GetByKind);
     45void repatchGetBy(JSGlobalObject*, CodeBlock*, JSValue, CacheableIdentifier, const PropertySlot&, StructureStubInfo&, GetByKind);
    4546void repatchPutByID(JSGlobalObject*, CodeBlock*, JSValue, Structure*, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
    4647void repatchInByID(JSGlobalObject*, CodeBlock*, JSObject*, const Identifier&, bool wasFound, const PropertySlot&, StructureStubInfo&);
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r253515 r254464  
    11/*
    2  * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    131131        // For function calls that have many new lines in between their open parenthesis
    132132        // and their closing parenthesis, the text range passed into the message appender
    133         // will not inlcude the text in between these parentheses, it will just be the desired
     133        // will not include the text in between these parentheses, it will just be the desired
    134134        // text that precedes the parentheses.
    135135        return String();
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r253648 r254464  
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003-2020 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    190190    const String& value(JSGlobalObject*) const;
    191191    inline const String& tryGetValue(bool allocationAllowed = true) const;
     192    const StringImpl* getValueImpl() const;
    192193    const StringImpl* tryGetValueImpl() const;
    193194    ALWAYS_INLINE unsigned length() const;
     
    704705}
    705706
     707inline const StringImpl* JSString::getValueImpl() const
     708{
     709    ASSERT(!isRope());
     710    return bitwise_cast<StringImpl*>(m_fiber);
     711}
     712
    706713inline const StringImpl* JSString::tryGetValueImpl() const
    707714{
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r254447 r254464  
    11/*
    2  * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    11531153#endif
    11541154
    1155 WatchpointSet* VM::ensureWatchpointSetForImpureProperty(const Identifier& propertyName)
    1156 {
    1157     auto result = m_impurePropertyWatchpointSets.add(propertyName.string(), nullptr);
     1155WatchpointSet* VM::ensureWatchpointSetForImpureProperty(UniquedStringImpl* propertyName)
     1156{
     1157    auto result = m_impurePropertyWatchpointSets.add(propertyName, nullptr);
    11581158    if (result.isNewEntry)
    11591159        result.iterator->value = adoptRef(new WatchpointSet(IsWatched));
     
    11611161}
    11621162
    1163 void VM::registerWatchpointForImpureProperty(const Identifier& propertyName, Watchpoint* watchpoint)
    1164 {
    1165     ensureWatchpointSetForImpureProperty(propertyName)->add(watchpoint);
    1166 }
    1167 
    1168 void VM::addImpureProperty(const String& propertyName)
     1163void VM::addImpureProperty(UniquedStringImpl* propertyName)
    11691164{
    11701165    if (RefPtr<WatchpointSet> watchpointSet = m_impurePropertyWatchpointSets.take(propertyName))
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r254447 r254464  
    11/*
    2  * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    10311031    void shrinkFootprintWhenIdle();
    10321032
    1033     WatchpointSet* ensureWatchpointSetForImpureProperty(const Identifier&);
    1034     void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
     1033    WatchpointSet* ensureWatchpointSetForImpureProperty(UniquedStringImpl*);
    10351034   
    10361035    // FIXME: Use AtomString once it got merged with Identifier.
    1037     JS_EXPORT_PRIVATE void addImpureProperty(const String&);
     1036    JS_EXPORT_PRIVATE void addImpureProperty(UniquedStringImpl*);
    10381037   
    10391038    InlineWatchpointSet& primitiveGigacageEnabled() { return m_primitiveGigacageEnabled; }
     
    12091208    std::unique_ptr<CodeCache> m_codeCache;
    12101209    std::unique_ptr<BuiltinExecutables> m_builtinExecutables;
    1211     HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
     1210    HashMap<RefPtr<UniquedStringImpl>, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
    12121211    std::unique_ptr<TypeProfiler> m_typeProfiler;
    12131212    std::unique_ptr<TypeProfilerLog> m_typeProfilerLog;
  • trunk/Source/WebCore/ChangeLog

    r254463 r254464  
     12020-01-13  Mark Lam  <mark.lam@apple.com>
     2
     3        Replace uses of Box<Identifier> with a new CacheableIdentifier class.
     4        https://bugs.webkit.org/show_bug.cgi?id=205544
     5        <rdar://problem/58041800>
     6
     7        Reviewed by Saam Barati.
     8
     9        * bindings/js/CommonVM.cpp:
     10        (WebCore::addImpureProperty):
     11
    1122020-01-13  Ross Kirsling  <ross.kirsling@sony.com>
    213
  • trunk/Source/WebCore/bindings/js/CommonVM.cpp

    r251529 r254464  
    11/*
    2  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8989void addImpureProperty(const AtomString& propertyName)
    9090{
    91     commonVM().addImpureProperty(propertyName);
     91    commonVM().addImpureProperty(propertyName.impl());
    9292}
    9393
Note: See TracChangeset for help on using the changeset viewer.