Changeset 243560 in webkit


Ignore:
Timestamp:
Mar 27, 2019 1:29:29 PM (5 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Owner of watchpoints should validate at GC finalizing phase
https://bugs.webkit.org/show_bug.cgi?id=195827

Reviewed by Filip Pizlo.

JSTests:

  • stress/gc-should-reap-dead-watchpoints.js: Added.

(foo):
(A.prototype.y):
(A):

Source/JavaScriptCore:

This patch fixes JSC's watchpoint liveness issue by the following two policies.

  1. Watchpoint should have owner cell, and "fire" operation should be gaurded with owner cell's isLive check.

Watchpoints should hold its owner cell, and fire procedure should be guarded by owner->isLive().
When the owner cell is destroyed, these watchpoints are destroyed too. But this destruction can
be delayed due to incremental sweeper. So the following condition can happen.

When we have a watchpoint like the following.

class XXXWatchpoint {

ObjectPropertyCondition m_key;
JSCell* m_owner;

};

Both m_key's cell and m_owner is now unreachable from the root. So eventually, m_owner cell's destructor
is called and this watchpoint will be destroyed. But before that, m_key's cell can be destroyed. And this
watchpoint's fire procedure can be called since m_owner's destructor is not called yet. In this situation,
we encounter the destroyed cell held in m_key. This problem can be avoided if we guard fire procedure with
m_owner->isLive(). Until the owner cell is destroyed, this guard avoids "fire" procedure execution. And
once the destructor of m_owner is called, this watchpoint will be destroyed too.

  1. Watchpoint liveness should be maintained by owner cell's unconditional finalizer

Watchpoints often hold weak references to the other cell (like, m_key in the above example). If we do not
delete watchpoints with dead cells when these weak cells become dead, these watchpoints continue holding dead cells,
and watchpoint's fire operation can use these dead cells accidentally. isLive / isStillLive check for these weak cells
in fire operation is not useful. Because these dead cells can be reused to the other live cells eventually, and this
isLive / isStillLive checks fail to see these cells are live if they are reused. Appropriate way is deleting watchpoints
with dead cells when finalizing GC. In this patch, we do this in unconditional finalizers in owner cells of watchpoints.
We already did this in CodeBlock etc. We add the same thing to StructureRareData which owns watchpoints for toString operations.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:

(JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::StructureWatchpoint): Deleted.
(JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::PropertyWatchpoint): Deleted.

  • bytecode/CodeBlockJettisoningWatchpoint.h:

(JSC::CodeBlockJettisoningWatchpoint::CodeBlockJettisoningWatchpoint): Deleted.

  • bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:

(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal):

  • bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:

(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::key const): Deleted.

  • bytecode/StructureStubClearingWatchpoint.cpp:

(JSC::StructureStubClearingWatchpoint::fireInternal):
(JSC::WatchpointsOnStructureStubInfo::isValid const):

  • bytecode/StructureStubClearingWatchpoint.h:

(JSC::StructureStubClearingWatchpoint::StructureStubClearingWatchpoint): Deleted.

  • dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:

(JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::isValid const):

  • dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
  • dfg/DFGAdaptiveStructureWatchpoint.cpp:

(JSC::DFG::AdaptiveStructureWatchpoint::fireInternal):

  • dfg/DFGAdaptiveStructureWatchpoint.h:

(JSC::DFG::AdaptiveStructureWatchpoint::key const): Deleted.

  • dfg/DFGDesiredWatchpoints.cpp:

(JSC::DFG::ArrayBufferViewWatchpointAdaptor::add):

  • heap/Heap.cpp:

(JSC::Heap::finalizeUnconditionalFinalizers):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::setupGetByIdPrototypeCache):

  • runtime/ArrayBuffer.cpp:

(JSC::ArrayBuffer::notifyIncommingReferencesOfTransfer):

  • runtime/ArrayBufferNeuteringWatchpointSet.cpp: Renamed from Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp.

(JSC::ArrayBufferNeuteringWatchpointSet::ArrayBufferNeuteringWatchpointSet):
(JSC::ArrayBufferNeuteringWatchpointSet::destroy):
(JSC::ArrayBufferNeuteringWatchpointSet::create):
(JSC::ArrayBufferNeuteringWatchpointSet::createStructure):
(JSC::ArrayBufferNeuteringWatchpointSet::fireAll):

  • runtime/ArrayBufferNeuteringWatchpointSet.h: Renamed from Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h.
  • runtime/FunctionRareData.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::tryInstallArraySpeciesWatchpoint):

  • runtime/ObjectPropertyChangeAdaptiveWatchpoint.h:

(JSC::ObjectPropertyChangeAdaptiveWatchpoint::ObjectPropertyChangeAdaptiveWatchpoint): Deleted.

  • runtime/StructureRareData.cpp:

(JSC::StructureRareData::finalizeUnconditionally):

  • runtime/StructureRareData.h:
  • runtime/VM.cpp:

(JSC::VM::VM):

Location:
trunk
Files:
1 added
24 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r243529 r243560  
     12019-03-27  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Owner of watchpoints should validate at GC finalizing phase
     4        https://bugs.webkit.org/show_bug.cgi?id=195827
     5
     6        Reviewed by Filip Pizlo.
     7
     8        * stress/gc-should-reap-dead-watchpoints.js: Added.
     9        (foo):
     10        (A.prototype.y):
     11        (A):
     12
    1132019-03-26  Dominik Infuehr  <dinfuehr@igalia.com>
    214
  • trunk/Source/JavaScriptCore/ChangeLog

    r243530 r243560  
     12019-03-27  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Owner of watchpoints should validate at GC finalizing phase
     4        https://bugs.webkit.org/show_bug.cgi?id=195827
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch fixes JSC's watchpoint liveness issue by the following two policies.
     9
     10        1. Watchpoint should have owner cell, and "fire" operation should be gaurded with owner cell's isLive check.
     11
     12        Watchpoints should hold its owner cell, and fire procedure should be guarded by `owner->isLive()`.
     13        When the owner cell is destroyed, these watchpoints are destroyed too. But this destruction can
     14        be delayed due to incremental sweeper. So the following condition can happen.
     15
     16        When we have a watchpoint like the following.
     17
     18            class XXXWatchpoint {
     19                ObjectPropertyCondition m_key;
     20                JSCell* m_owner;
     21            };
     22
     23        Both m_key's cell and m_owner is now unreachable from the root. So eventually, m_owner cell's destructor
     24        is called and this watchpoint will be destroyed. But before that, m_key's cell can be destroyed. And this
     25        watchpoint's fire procedure can be called since m_owner's destructor is not called yet. In this situation,
     26        we encounter the destroyed cell held in m_key. This problem can be avoided if we guard fire procedure with
     27        `m_owner->isLive()`. Until the owner cell is destroyed, this guard avoids "fire" procedure execution. And
     28        once the destructor of m_owner is called, this watchpoint will be destroyed too.
     29
     30        2. Watchpoint liveness should be maintained by owner cell's unconditional finalizer
     31
     32        Watchpoints often hold weak references to the other cell (like, m_key in the above example). If we do not
     33        delete watchpoints with dead cells when these weak cells become dead, these watchpoints continue holding dead cells,
     34        and watchpoint's fire operation can use these dead cells accidentally. isLive / isStillLive check for these weak cells
     35        in fire operation is not useful. Because these dead cells can be reused to the other live cells eventually, and this
     36        isLive / isStillLive checks fail to see these cells are live if they are reused. Appropriate way is deleting watchpoints
     37        with dead cells when finalizing GC. In this patch, we do this in unconditional finalizers in owner cells of watchpoints.
     38        We already did this in CodeBlock etc. We add the same thing to StructureRareData which owns watchpoints for toString operations.
     39
     40        * JavaScriptCore.xcodeproj/project.pbxproj:
     41        * Sources.txt:
     42        * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:
     43        (JSC::AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint::StructureWatchpoint): Deleted.
     44        (JSC::AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint::PropertyWatchpoint): Deleted.
     45        * bytecode/CodeBlockJettisoningWatchpoint.h:
     46        (JSC::CodeBlockJettisoningWatchpoint::CodeBlockJettisoningWatchpoint): Deleted.
     47        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:
     48        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
     49        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal):
     50        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
     51        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::key const): Deleted.
     52        * bytecode/StructureStubClearingWatchpoint.cpp:
     53        (JSC::StructureStubClearingWatchpoint::fireInternal):
     54        (JSC::WatchpointsOnStructureStubInfo::isValid const):
     55        * bytecode/StructureStubClearingWatchpoint.h:
     56        (JSC::StructureStubClearingWatchpoint::StructureStubClearingWatchpoint): Deleted.
     57        * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp:
     58        (JSC::DFG::AdaptiveInferredPropertyValueWatchpoint::isValid const):
     59        * dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h:
     60        * dfg/DFGAdaptiveStructureWatchpoint.cpp:
     61        (JSC::DFG::AdaptiveStructureWatchpoint::fireInternal):
     62        * dfg/DFGAdaptiveStructureWatchpoint.h:
     63        (JSC::DFG::AdaptiveStructureWatchpoint::key const): Deleted.
     64        * dfg/DFGDesiredWatchpoints.cpp:
     65        (JSC::DFG::ArrayBufferViewWatchpointAdaptor::add):
     66        * heap/Heap.cpp:
     67        (JSC::Heap::finalizeUnconditionalFinalizers):
     68        * llint/LLIntSlowPaths.cpp:
     69        (JSC::LLInt::setupGetByIdPrototypeCache):
     70        * runtime/ArrayBuffer.cpp:
     71        (JSC::ArrayBuffer::notifyIncommingReferencesOfTransfer):
     72        * runtime/ArrayBufferNeuteringWatchpointSet.cpp: Renamed from Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.cpp.
     73        (JSC::ArrayBufferNeuteringWatchpointSet::ArrayBufferNeuteringWatchpointSet):
     74        (JSC::ArrayBufferNeuteringWatchpointSet::destroy):
     75        (JSC::ArrayBufferNeuteringWatchpointSet::create):
     76        (JSC::ArrayBufferNeuteringWatchpointSet::createStructure):
     77        (JSC::ArrayBufferNeuteringWatchpointSet::fireAll):
     78        * runtime/ArrayBufferNeuteringWatchpointSet.h: Renamed from Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h.
     79        * runtime/FunctionRareData.h:
     80        * runtime/JSGlobalObject.cpp:
     81        (JSC::JSGlobalObject::init):
     82        (JSC::JSGlobalObject::tryInstallArraySpeciesWatchpoint):
     83        * runtime/ObjectPropertyChangeAdaptiveWatchpoint.h:
     84        (JSC::ObjectPropertyChangeAdaptiveWatchpoint::ObjectPropertyChangeAdaptiveWatchpoint): Deleted.
     85        * runtime/StructureRareData.cpp:
     86        (JSC::StructureRareData::finalizeUnconditionally):
     87        * runtime/StructureRareData.h:
     88        * runtime/VM.cpp:
     89        (JSC::VM::VM):
     90
    1912019-03-26  Saam Barati  <sbarati@apple.com>
    292
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r243365 r243560  
    745745                0FFC92161B94FB3E0071DD66 /* DFGPropertyTypeKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC92151B94FB3E0071DD66 /* DFGPropertyTypeKey.h */; };
    746746                0FFC99D1184EC8AD009C10AB /* ConstantMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D0184EC8AD009C10AB /* ConstantMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    747                 0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
     747                0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
    748748                0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */; };
    749749                0FFFC95A14EF90A900C72532 /* DFGCSEPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC94E14EF909500C72532 /* DFGCSEPhase.h */; };
     
    31143114                0FFC92151B94FB3E0071DD66 /* DFGPropertyTypeKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPropertyTypeKey.h; path = dfg/DFGPropertyTypeKey.h; sourceTree = "<group>"; };
    31153115                0FFC99D0184EC8AD009C10AB /* ConstantMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantMode.h; sourceTree = "<group>"; };
    3116                 0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBufferNeuteringWatchpoint.cpp; sourceTree = "<group>"; };
    3117                 0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayBufferNeuteringWatchpoint.h; sourceTree = "<group>"; };
     3116                0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBufferNeuteringWatchpointSet.cpp; sourceTree = "<group>"; };
     3117                0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayBufferNeuteringWatchpointSet.h; sourceTree = "<group>"; };
    31183118                0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFAPhase.cpp; path = dfg/DFGCFAPhase.cpp; sourceTree = "<group>"; };
    31193119                0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCFAPhase.h; path = dfg/DFGCFAPhase.h; sourceTree = "<group>"; };
     
    66336633                                A7A8AF2517ADB5F2005AB174 /* ArrayBuffer.cpp */,
    66346634                                A7A8AF2617ADB5F3005AB174 /* ArrayBuffer.h */,
    6635                                 0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.cpp */,
    6636                                 0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h */,
     6635                                0FFC99D2184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.cpp */,
     6636                                0FFC99D3184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.h */,
    66376637                                0F30FB601DC2DE96003124F2 /* ArrayBufferSharingMode.h */,
    66386638                                A7A8AF2717ADB5F3005AB174 /* ArrayBufferView.cpp */,
     
    85138513                                0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */,
    85148514                                A7A8AF3517ADB5F3005AB174 /* ArrayBuffer.h in Headers */,
    8515                                 0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpoint.h in Headers */,
     8515                                0FFC99D5184EE318009C10AB /* ArrayBufferNeuteringWatchpointSet.h in Headers */,
    85168516                                0F30FB611DC2DE99003124F2 /* ArrayBufferSharingMode.h in Headers */,
    85178517                                A7A8AF3717ADB5F3005AB174 /* ArrayBufferView.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r243365 r243560  
    693693runtime/ArgList.cpp
    694694runtime/ArrayBuffer.cpp
    695 runtime/ArrayBufferNeuteringWatchpoint.cpp
     695runtime/ArrayBufferNeuteringWatchpointSet.cpp
    696696runtime/ArrayBufferView.cpp
    697697runtime/ArrayConstructor.cpp
  • trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h

    r233245 r243560  
    5151
    5252private:
    53     class StructureWatchpoint : public Watchpoint {
     53    class StructureWatchpoint final : public Watchpoint {
    5454    public:
    5555        StructureWatchpoint() { }
     
    5757        void fireInternal(VM&, const FireDetail&) override;
    5858    };
    59     class PropertyWatchpoint : public Watchpoint {
     59    class PropertyWatchpoint final : public Watchpoint {
    6060    public:
    6161        PropertyWatchpoint() { }
  • trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h

    r233245 r243560  
    3232class CodeBlock;
    3333
    34 class CodeBlockJettisoningWatchpoint : public Watchpoint {
     34class CodeBlockJettisoningWatchpoint final : public Watchpoint {
    3535public:
    3636    CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock)
  • trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp

    r243420 r243560  
    3333namespace JSC {
    3434
    35 LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, OpGetById::Metadata& getByIdMetadata)
    36     : m_key(key)
     35LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(CodeBlock* owner, const ObjectPropertyCondition& key, OpGetById::Metadata& getByIdMetadata)
     36    : m_owner(owner)
     37    , m_key(key)
    3738    , m_getByIdMetadata(getByIdMetadata)
    3839{
     
    5051void LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal(VM& vm, const FireDetail&)
    5152{
     53    if (!m_owner->isLive())
     54        return;
     55
    5256    if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
    5357        install(vm);
  • trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h

    r240703 r243560  
    3232namespace JSC {
    3333
    34 class LLIntPrototypeLoadAdaptiveStructureWatchpoint : public Watchpoint {
     34class LLIntPrototypeLoadAdaptiveStructureWatchpoint final : public Watchpoint {
    3535public:
    36     LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, OpGetById::Metadata&);
     36    LLIntPrototypeLoadAdaptiveStructureWatchpoint(CodeBlock*, const ObjectPropertyCondition&, OpGetById::Metadata&);
    3737
    3838    void install(VM&);
     
    4646
    4747private:
     48    CodeBlock* m_owner;
    4849    ObjectPropertyCondition m_key;
    4950    OpGetById::Metadata& m_getByIdMetadata;
  • trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp

    r243420 r243560  
    3737void StructureStubClearingWatchpoint::fireInternal(VM& vm, const FireDetail&)
    3838{
     39    if (!m_holder.isValid())
     40        return;
     41
    3942    if (!m_key || !m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
    4043        // This will implicitly cause my own demise: stub reset removes all watchpoints.
     
    5356
    5457    m_key.object()->structure(vm)->addTransitionWatchpoint(this);
     58}
     59
     60inline bool WatchpointsOnStructureStubInfo::isValid() const
     61{
     62    return m_codeBlock->isLive();
    5563}
    5664
  • trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h

    r235776 r243560  
    4141class WatchpointsOnStructureStubInfo;
    4242
    43 class StructureStubClearingWatchpoint : public Watchpoint {
     43class StructureStubClearingWatchpoint final : public Watchpoint {
    4444    WTF_MAKE_NONCOPYABLE(StructureStubClearingWatchpoint);
    4545    WTF_MAKE_FAST_ALLOCATED;
     
    7979    CodeBlock* codeBlock() const { return m_codeBlock; }
    8080    StructureStubInfo* stubInfo() const { return m_stubInfo; }
     81
     82    bool isValid() const;
    8183   
    8284private:
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.cpp

    r233245 r243560  
    5252}
    5353
     54bool AdaptiveInferredPropertyValueWatchpoint::isValid() const
     55{
     56    return m_codeBlock->isLive();
     57}
     58
    5459} } // namespace JSC::DFG
    5560
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveInferredPropertyValueWatchpoint.h

    r233245 r243560  
    3232namespace JSC { namespace DFG {
    3333
    34 class AdaptiveInferredPropertyValueWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
     34class AdaptiveInferredPropertyValueWatchpoint final : public AdaptiveInferredPropertyValueWatchpointBase {
    3535public:
    3636    typedef AdaptiveInferredPropertyValueWatchpointBase Base;
     
    3838
    3939private:
     40    bool isValid() const override;
     41
    4042    void handleFire(VM&, const FireDetail&) override;
    4143
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp

    r243420 r243560  
    5353void AdaptiveStructureWatchpoint::fireInternal(VM& vm, const FireDetail& detail)
    5454{
     55    if (!m_codeBlock->isLive())
     56        return;
     57
    5558    if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
    5659        install(vm);
  • trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h

    r233245 r243560  
    3333namespace JSC { namespace DFG {
    3434
    35 class AdaptiveStructureWatchpoint : public Watchpoint {
     35class AdaptiveStructureWatchpoint final : public Watchpoint {
    3636public:
    3737    AdaptiveStructureWatchpoint(const ObjectPropertyCondition&, CodeBlock*);
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp

    r240023 r243560  
    2929#if ENABLE(DFG_JIT)
    3030
    31 #include "ArrayBufferNeuteringWatchpoint.h"
     31#include "ArrayBufferNeuteringWatchpointSet.h"
    3232#include "CodeBlock.h"
    3333#include "JSCInlines.h"
     
    4040    VM& vm = *codeBlock->vm();
    4141    Watchpoint* watchpoint = common.watchpoints.add(codeBlock);
    42     ArrayBufferNeuteringWatchpoint* neuteringWatchpoint =
    43         ArrayBufferNeuteringWatchpoint::create(vm);
     42    ArrayBufferNeuteringWatchpointSet* neuteringWatchpoint =
     43        ArrayBufferNeuteringWatchpointSet::create(vm);
    4444    neuteringWatchpoint->set().add(watchpoint);
    4545    codeBlock->addConstant(neuteringWatchpoint);
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r243467 r243560  
    596596        });
    597597    finalizeMarkedUnconditionalFinalizers<ExecutableToCodeBlockEdge>(vm()->executableToCodeBlockEdgesWithFinalizers);
     598    finalizeMarkedUnconditionalFinalizers<StructureRareData>(vm()->structureRareDataSpace);
    598599    if (vm()->m_weakSetSpace)
    599600        finalizeMarkedUnconditionalFinalizers<JSWeakSet>(*vm()->m_weakSetSpace);
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r242596 r243560  
    728728        if (condition.condition().kind() == PropertyCondition::Presence)
    729729            offset = condition.condition().offset();
    730         watchpoints.add(condition, metadata)->install(vm);
     730        watchpoints.add(codeBlock, condition, metadata)->install(vm);
    731731    }
    732732
  • trunk/Source/JavaScriptCore/runtime/ArrayBuffer.cpp

    r239535 r243560  
    2727#include "ArrayBuffer.h"
    2828
    29 #include "ArrayBufferNeuteringWatchpoint.h"
     29#include "ArrayBufferNeuteringWatchpointSet.h"
    3030#include "JSArrayBufferView.h"
    3131#include "JSCInlines.h"
     
    383383        if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, cell))
    384384            view->neuter();
    385         else if (ArrayBufferNeuteringWatchpoint* watchpoint = jsDynamicCast<ArrayBufferNeuteringWatchpoint*>(vm, cell))
     385        else if (ArrayBufferNeuteringWatchpointSet* watchpoint = jsDynamicCast<ArrayBufferNeuteringWatchpointSet*>(vm, cell))
    386386            watchpoint->fireAll();
    387387    }
  • trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpointSet.cpp

    r243558 r243560  
    2525
    2626#include "config.h"
    27 #include "ArrayBufferNeuteringWatchpoint.h"
     27#include "ArrayBufferNeuteringWatchpointSet.h"
    2828
    2929#include "JSCInlines.h"
     
    3131namespace JSC {
    3232
    33 const ClassInfo ArrayBufferNeuteringWatchpoint::s_info = {
    34     "ArrayBufferNeuteringWatchpoint", nullptr, nullptr, nullptr,
    35     CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpoint)
     33const ClassInfo ArrayBufferNeuteringWatchpointSet::s_info = {
     34    "ArrayBufferNeuteringWatchpointSet", nullptr, nullptr, nullptr,
     35    CREATE_METHOD_TABLE(ArrayBufferNeuteringWatchpointSet)
    3636};
    3737
    38 ArrayBufferNeuteringWatchpoint::ArrayBufferNeuteringWatchpoint(VM& vm)
     38ArrayBufferNeuteringWatchpointSet::ArrayBufferNeuteringWatchpointSet(VM& vm)
    3939    : Base(vm, vm.arrayBufferNeuteringWatchpointStructure.get())
    4040    , m_set(adoptRef(*new WatchpointSet(IsWatched)))
     
    4242}
    4343
    44 void ArrayBufferNeuteringWatchpoint::destroy(JSCell* cell)
     44void ArrayBufferNeuteringWatchpointSet::destroy(JSCell* cell)
    4545{
    46     static_cast<ArrayBufferNeuteringWatchpoint*>(cell)->ArrayBufferNeuteringWatchpoint::~ArrayBufferNeuteringWatchpoint();
     46    static_cast<ArrayBufferNeuteringWatchpointSet*>(cell)->ArrayBufferNeuteringWatchpointSet::~ArrayBufferNeuteringWatchpointSet();
    4747}
    4848
    49 ArrayBufferNeuteringWatchpoint* ArrayBufferNeuteringWatchpoint::create(VM& vm)
     49ArrayBufferNeuteringWatchpointSet* ArrayBufferNeuteringWatchpointSet::create(VM& vm)
    5050{
    51     ArrayBufferNeuteringWatchpoint* result = new
    52         (NotNull, allocateCell<ArrayBufferNeuteringWatchpoint>(vm.heap))
    53         ArrayBufferNeuteringWatchpoint(vm);
     51    ArrayBufferNeuteringWatchpointSet* result = new
     52        (NotNull, allocateCell<ArrayBufferNeuteringWatchpointSet>(vm.heap))
     53        ArrayBufferNeuteringWatchpointSet(vm);
    5454    result->finishCreation(vm);
    5555    return result;
    5656}
    5757
    58 Structure* ArrayBufferNeuteringWatchpoint::createStructure(VM& vm)
     58Structure* ArrayBufferNeuteringWatchpointSet::createStructure(VM& vm)
    5959{
    6060    return Structure::create(vm, 0, jsNull(), TypeInfo(CellType, StructureFlags), info());
    6161}
    6262
    63 void ArrayBufferNeuteringWatchpoint::fireAll()
     63void ArrayBufferNeuteringWatchpointSet::fireAll()
    6464{
    6565    m_set->fireAll(*vm(), "Array buffer was neutered");
  • trunk/Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpointSet.h

    r243558 r243560  
    3131namespace JSC {
    3232
    33 class ArrayBufferNeuteringWatchpoint final : public JSCell {
     33class ArrayBufferNeuteringWatchpointSet final : public JSCell {
    3434public:
    3535    typedef JSCell Base;
     
    3838    DECLARE_INFO;
    3939   
    40     static ArrayBufferNeuteringWatchpoint* create(VM&);
     40    static ArrayBufferNeuteringWatchpointSet* create(VM&);
    4141
    4242    static const bool needsDestruction = true;
     
    5050
    5151private:
    52     explicit ArrayBufferNeuteringWatchpoint(VM&);
     52    explicit ArrayBufferNeuteringWatchpointSet(VM&);
    5353   
    5454    Ref<WatchpointSet> m_set;
  • trunk/Source/JavaScriptCore/runtime/FunctionRareData.h

    r239191 r243560  
    117117private:
    118118
    119     class AllocationProfileClearingWatchpoint : public Watchpoint {
     119    class AllocationProfileClearingWatchpoint final : public Watchpoint {
    120120    public:
    121121        AllocationProfileClearingWatchpoint(FunctionRareData* rareData)
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r243312 r243560  
    11041104    {
    11051105        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(arrayIteratorPrototype, m_vm.propertyNames->next);
    1106         m_arrayIteratorPrototypeNext = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_arrayIteratorProtocolWatchpoint);
     1106        m_arrayIteratorPrototypeNext = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_arrayIteratorProtocolWatchpoint);
    11071107        m_arrayIteratorPrototypeNext->install(vm);
    11081108    }
    11091109    {
    11101110        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(this->arrayPrototype(), m_vm.propertyNames->iteratorSymbol);
    1111         m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_arrayIteratorProtocolWatchpoint);
     1111        m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_arrayIteratorProtocolWatchpoint);
    11121112        m_arrayPrototypeSymbolIteratorWatchpoint->install(vm);
    11131113    }
     
    11151115    {
    11161116        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(mapIteratorPrototype, m_vm.propertyNames->next);
    1117         m_mapIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_mapIteratorProtocolWatchpoint);
     1117        m_mapIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_mapIteratorProtocolWatchpoint);
    11181118        m_mapIteratorPrototypeNextWatchpoint->install(vm);
    11191119    }
    11201120    {
    11211121        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->iteratorSymbol);
    1122         m_mapPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_mapIteratorProtocolWatchpoint);
     1122        m_mapPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_mapIteratorProtocolWatchpoint);
    11231123        m_mapPrototypeSymbolIteratorWatchpoint->install(vm);
    11241124    }
     
    11261126    {
    11271127        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(setIteratorPrototype, m_vm.propertyNames->next);
    1128         m_setIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_setIteratorProtocolWatchpoint);
     1128        m_setIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_setIteratorProtocolWatchpoint);
    11291129        m_setIteratorPrototypeNextWatchpoint->install(vm);
    11301130    }
    11311131    {
    11321132        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->iteratorSymbol);
    1133         m_setPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_setIteratorProtocolWatchpoint);
     1133        m_setPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_setIteratorProtocolWatchpoint);
    11341134        m_setPrototypeSymbolIteratorWatchpoint->install(vm);
    11351135    }
     
    11371137    {
    11381138        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringIteratorPrototype.get(), m_vm.propertyNames->next);
    1139         m_stringIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_stringIteratorProtocolWatchpoint);
     1139        m_stringIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_stringIteratorProtocolWatchpoint);
    11401140        m_stringIteratorPrototypeNextWatchpoint->install(vm);
    11411141    }
    11421142    {
    11431143        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringPrototype.get(), m_vm.propertyNames->iteratorSymbol);
    1144         m_stringPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_stringIteratorProtocolWatchpoint);
     1144        m_stringPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_stringIteratorProtocolWatchpoint);
    11451145        m_stringPrototypeSymbolIteratorWatchpoint->install(vm);
    11461146    }
     
    11481148    {
    11491149        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->set);
    1150         m_mapPrototypeSetWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_mapSetWatchpoint);
     1150        m_mapPrototypeSetWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_mapSetWatchpoint);
    11511151        m_mapPrototypeSetWatchpoint->install(vm);
    11521152    }
     
    11541154    {
    11551155        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->add);
    1156         m_setPrototypeAddWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_setAddWatchpoint);
     1156        m_setPrototypeAddWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_setAddWatchpoint);
    11571157        m_setPrototypeAddWatchpoint->install(vm);
    11581158    }
     
    11651165
    11661166        ObjectPropertyCondition condition = setupAdaptiveWatchpoint(numberPrototype, m_vm.propertyNames->toString);
    1167         m_numberPrototypeToStringWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(condition, m_numberToStringWatchpoint);
     1167        m_numberPrototypeToStringWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, condition, m_numberToStringWatchpoint);
    11681168        m_numberPrototypeToStringWatchpoint->install(vm);
    11691169        m_numberProtoToStringFunction.set(vm, this, jsCast<JSFunction*>(numberPrototype->getDirect(vm, vm.propertyNames->toString)));
     
    18931893    m_arraySpeciesWatchpoint.touch(vm, "Set up array species watchpoint.");
    18941894
    1895     m_arrayPrototypeConstructorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(constructorCondition, m_arraySpeciesWatchpoint);
     1895    m_arrayPrototypeConstructorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, constructorCondition, m_arraySpeciesWatchpoint);
    18961896    m_arrayPrototypeConstructorWatchpoint->install(vm);
    18971897
    1898     m_arrayConstructorSpeciesWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(speciesCondition, m_arraySpeciesWatchpoint);
     1898    m_arrayConstructorSpeciesWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(this, speciesCondition, m_arraySpeciesWatchpoint);
    18991899    m_arrayConstructorSpeciesWatchpoint->install(vm);
    19001900}
  • trunk/Source/JavaScriptCore/runtime/ObjectPropertyChangeAdaptiveWatchpoint.h

    r233245 r243560  
    3131
    3232template<typename Watchpoint>
    33 class ObjectPropertyChangeAdaptiveWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
     33class ObjectPropertyChangeAdaptiveWatchpoint final : public AdaptiveInferredPropertyValueWatchpointBase {
    3434public:
    3535    using Base = AdaptiveInferredPropertyValueWatchpointBase;
    36     ObjectPropertyChangeAdaptiveWatchpoint(const ObjectPropertyCondition& condition, Watchpoint& watchpoint)
     36    ObjectPropertyChangeAdaptiveWatchpoint(JSCell* owner, const ObjectPropertyCondition& condition, Watchpoint& watchpoint)
    3737        : Base(condition)
     38        , m_owner(owner)
    3839        , m_watchpoint(watchpoint)
    3940    {
     
    4243
    4344private:
     45    bool isValid() const override
     46    {
     47        return m_owner->isLive();
     48    }
     49
    4450    void handleFire(VM& vm, const FireDetail&) override
    4551    {
     
    4753    }
    4854
     55    JSCell* m_owner;
    4956    Watchpoint& m_watchpoint;
    5057};
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp

    r243420 r243560  
    7979// ----------- Object.prototype.toString() helper watchpoint classes -----------
    8080
    81 class ObjectToStringAdaptiveInferredPropertyValueWatchpoint : public AdaptiveInferredPropertyValueWatchpointBase {
     81class ObjectToStringAdaptiveInferredPropertyValueWatchpoint final : public AdaptiveInferredPropertyValueWatchpointBase {
    8282public:
    8383    typedef AdaptiveInferredPropertyValueWatchpointBase Base;
     
    9191};
    9292
    93 class ObjectToStringAdaptiveStructureWatchpoint : public Watchpoint {
     93class ObjectToStringAdaptiveStructureWatchpoint final : public Watchpoint {
    9494public:
    9595    ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, StructureRareData*);
    9696
    9797    void install(VM&);
     98
     99    const ObjectPropertyCondition& key() const { return m_key; }
    98100
    99101protected:
     
    170172}
    171173
     174void StructureRareData::finalizeUnconditionally(VM& vm)
     175{
     176    if (m_objectToStringAdaptiveInferredValueWatchpoint) {
     177        if (!m_objectToStringAdaptiveInferredValueWatchpoint->key().isStillLive(vm)) {
     178            clearObjectToStringValue();
     179            return;
     180        }
     181    }
     182    for (auto* watchpoint : m_objectToStringAdaptiveWatchpointSet) {
     183        if (!watchpoint->key().isStillLive(vm)) {
     184            clearObjectToStringValue();
     185            return;
     186        }
     187    }
     188}
     189
    172190// ------------- Methods for Object.prototype.toString() helper watchpoint classes --------------
    173191
  • trunk/Source/JavaScriptCore/runtime/StructureRareData.h

    r240965 r243560  
    9191    DECLARE_EXPORT_INFO;
    9292
     93    void finalizeUnconditionally(VM&);
     94
    9395private:
    9496    friend class Structure;
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r243312 r243560  
    3131
    3232#include "ArgList.h"
    33 #include "ArrayBufferNeuteringWatchpoint.h"
     33#include "ArrayBufferNeuteringWatchpointSet.h"
    3434#include "BuiltinExecutables.h"
    3535#include "BytecodeIntrinsicRegistry.h"
     
    382382    sparseArrayValueMapStructure.set(*this, SparseArrayValueMap::createStructure(*this, 0, jsNull()));
    383383    templateObjectDescriptorStructure.set(*this, JSTemplateObjectDescriptor::createStructure(*this, 0, jsNull()));
    384     arrayBufferNeuteringWatchpointStructure.set(*this, ArrayBufferNeuteringWatchpoint::createStructure(*this));
     384    arrayBufferNeuteringWatchpointStructure.set(*this, ArrayBufferNeuteringWatchpointSet::createStructure(*this));
    385385    unlinkedFunctionExecutableStructure.set(*this, UnlinkedFunctionExecutable::createStructure(*this, 0, jsNull()));
    386386    unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull()));
Note: See TracChangeset for help on using the changeset viewer.