Title: [262475] trunk/Source/_javascript_Core
Revision
262475
Author
mark....@apple.com
Date
2020-06-02 21:47:30 -0700 (Tue, 02 Jun 2020)

Log Message

Enhance DoesGC verification to print more useful info when verification fails.
https://bugs.webkit.org/show_bug.cgi?id=212680

Reviewed by Yusuke Suzuki.

When DoesGC verification fails, the first step of debugging it would be to find
out what and which DFG node resulted in the failed verification.  In pre-existing
code, all we get is an assertion failure.

This patch makes it so that the verifier will dump useful info.  Here's an example:

    Error: DoesGC failed @ D@34 DateGetInt32OrNaN in #DtCHMz:[0x1135bd1d0->0x1135bcab0->0x1135e5c80, DFGFunctionCall, 150 (DidTryToEnterInLoop)]
        [0] frame 0x7ffee8285660 {
          name: 
          sourceURL: 
          isInlinedFrame: false
          callee: 0x1135f6820
          returnPC: 0x50ce61248ae6
          callerFrame: 0x7ffee82856f0
          rawLocationBits: 5 0x5
          codeBlock: 0x1135bd1d0 #DtCHMz:[0x1135bd1d0->0x1135bcab0->0x1135e5c80, DFGFunctionCall, 150 (DidTryToEnterInLoop)]
            hasCodeOrigins: true
            callSiteIndex: 5 of 13
            jitCode: 0x113020200 start 0x50ce61214c60 end 0x50ce61219b00
            line: 1
            column: 60
          EntryFrame: 0x7ffee8285860
        }
        [1] frame 0x7ffee82856f0 {
          name: 
          sourceURL: date-format-xparb.js
          isInlinedFrame: false
          callee: 0x1135f65a0
          returnPC: 0x50ce61227e99
          callerFrame: 0x7ffee8285770
          rawLocationBits: 4 0x4
          codeBlock: 0x1135bd0a0 #BU6Zcd:[0x1135bd0a0->0x1135bc260->0x1135e5180, DFGFunctionCall, 112 (DidTryToEnterInLoop)]
            hasCodeOrigins: true
            callSiteIndex: 4 of 12
            jitCode: 0x113004000 start 0x50ce61212c60 end 0x50ce61214960
            line: 26
            column: 22
          EntryFrame: 0x7ffee8285860
        }
        [2] frame 0x7ffee8285770 {
          name: 
          sourceURL: date-format-xparb.js
          isInlinedFrame: false
          callee: 0x1135f64e0
          returnPC: 0x108058eb1
          callerFrame: 0x7ffee82857e0
          rawLocationBits: 1001 0x3e9
          codeBlock: 0x1135bc130 #DAS9xe:[0x1135bc130->0x1135e5100, BaselineFunctionCall, 1149]
            bc#1001 of 1149
            line: 417
            column: 38
          EntryFrame: 0x7ffee8285860
        }
        [3] frame 0x7ffee82857e0 {
          name: global code
          sourceURL: date-format-xparb.js
          isInlinedFrame: false
          callee: 0x1130f97b8
          returnPC: 0x108039043
          callerFrame: 0x0
          rawLocationBits: 23 0x17
          codeBlock: 0x1135bc000 <global>#CukXvt:[0x1135bc000->0x1130cd768, LLIntGlobal, 81]
            bc#23 of 81
            line: 425
            column: 3
          EntryFrame: 0x7ffee8285860
        }

    ASSERTION FAILED: expectDoesGC()

The error message now comes with the node index, NodeType, codeBlock which this
failure was found in, and the JS call stack that led to the failure.

Changes made:

1. Introduced a DoesGCCheck value that is used to encode some of the above data.

   Previously, we only recorded whether doesGC() returns true or false for the
   Node.  Now, we record the nodeIndex and nodeOp as well.

   Note that we also set DoesGC expectations for OSR exits.  So, DoesGCCheck
   includes Special cases for those.

2. Added store64(TrustedImm64 imm, const void* address) emitters for X86_64 and ARM64.
   Also added a test for this new emitter in testmasm.

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::store64):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::store64):
* assembler/testmasm.cpp:
(JSC::testStore64Imm64AddressPointer):
(JSC::run):
* dfg/DFGDoesGCCheck.cpp: Added.
(JSC::DFG::DoesGCCheck::verifyCanGC):
* dfg/DFGDoesGCCheck.h: Added.
(JSC::DFG::DoesGCCheck::DoesGCCheck):
(JSC::DFG::DoesGCCheck::encode):
(JSC::DFG::DoesGCCheck::set):
(JSC::DFG::DoesGCCheck::expectDoesGC):
(JSC::DFG::DoesGCCheck::special):
(JSC::DFG::DoesGCCheck::nodeIndex):
(JSC::DFG::DoesGCCheck::nodeOp):
(JSC::DFG::DoesGCCheck::isSpecial):
(JSC::DFG::DoesGCCheck::specialIndex):
(JSC::DFG::DoesGCCheck::bits):
* dfg/DFGGraph.cpp:
* dfg/DFGOSRExit.cpp:
(JSC::DFG::operationCompileOSRExit):
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
(JSC::FTL::operationCompileFTLOSRExit):
* heap/CompleteSubspace.cpp:
(JSC::CompleteSubspace::tryAllocateSlow):
(JSC::CompleteSubspace::reallocatePreciseAllocationNonVirtual):
* heap/CompleteSubspaceInlines.h:
(JSC::CompleteSubspace::allocateNonVirtual):
* heap/DeferGC.h:
(JSC::DeferGC::~DeferGC):
* heap/GCDeferralContextInlines.h:
(JSC::GCDeferralContext::~GCDeferralContext):
* heap/Heap.cpp:
(JSC::Heap::collectNow):
(JSC::Heap::collectAsync):
(JSC::Heap::collectSync):
(JSC::Heap::stopIfNecessarySlow):
(JSC::Heap::collectIfNecessaryOrDefer):
* heap/Heap.h:
(JSC::Heap::addressOfDoesGC):
(JSC::Heap::setDoesGCExpectation):
(JSC::Heap::verifyCanGC):
(JSC::Heap::expectDoesGC const): Deleted.
(JSC::Heap::setExpectDoesGC): Deleted.
(JSC::Heap::addressOfExpectDoesGC): Deleted.
* heap/HeapInlines.h:
(JSC::Heap::acquireAccess):
(JSC::Heap::stopIfNecessary):
* heap/LocalAllocatorInlines.h:
(JSC::LocalAllocator::allocate):
* heap/PreciseAllocation.cpp:
(JSC::PreciseAllocation::tryCreate):
(JSC::PreciseAllocation::createForLowerTier):
* runtime/JSString.h:
(JSC::jsSingleCharacterString):
(JSC::JSString::toAtomString const):
(JSC::JSString::toExistingAtomString const):
(JSC::JSString::value const):
(JSC::JSString::tryGetValue const):
(JSC::JSRopeString::unsafeView const):
(JSC::JSRopeString::viewWithUnderlyingString const):
(JSC::JSString::unsafeView const):
* runtime/RegExpMatchesArray.h:
(JSC::createRegExpMatchesArray):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (262474 => 262475)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2020-06-03 04:47:30 UTC (rev 262475)
@@ -564,6 +564,7 @@
 
     dfg/DFGCommon.h
     dfg/DFGCompilationMode.h
+    dfg/DFGDoesGCCheck.h
     dfg/DFGMinifiedID.h
 
     domjit/DOMJITAbstractHeap.h

Modified: trunk/Source/_javascript_Core/ChangeLog (262474 => 262475)


--- trunk/Source/_javascript_Core/ChangeLog	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,5 +1,174 @@
 2020-06-02  Mark Lam  <mark....@apple.com>
 
+        Enhance DoesGC verification to print more useful info when verification fails.
+        https://bugs.webkit.org/show_bug.cgi?id=212680
+
+        Reviewed by Yusuke Suzuki.
+
+        When DoesGC verification fails, the first step of debugging it would be to find
+        out what and which DFG node resulted in the failed verification.  In pre-existing
+        code, all we get is an assertion failure.
+
+        This patch makes it so that the verifier will dump useful info.  Here's an example:
+
+            Error: DoesGC failed @ D@34 DateGetInt32OrNaN in #DtCHMz:[0x1135bd1d0->0x1135bcab0->0x1135e5c80, DFGFunctionCall, 150 (DidTryToEnterInLoop)]
+                [0] frame 0x7ffee8285660 {
+                  name: 
+                  sourceURL: 
+                  isInlinedFrame: false
+                  callee: 0x1135f6820
+                  returnPC: 0x50ce61248ae6
+                  callerFrame: 0x7ffee82856f0
+                  rawLocationBits: 5 0x5
+                  codeBlock: 0x1135bd1d0 #DtCHMz:[0x1135bd1d0->0x1135bcab0->0x1135e5c80, DFGFunctionCall, 150 (DidTryToEnterInLoop)]
+                    hasCodeOrigins: true
+                    callSiteIndex: 5 of 13
+                    jitCode: 0x113020200 start 0x50ce61214c60 end 0x50ce61219b00
+                    line: 1
+                    column: 60
+                  EntryFrame: 0x7ffee8285860
+                }
+                [1] frame 0x7ffee82856f0 {
+                  name: 
+                  sourceURL: date-format-xparb.js
+                  isInlinedFrame: false
+                  callee: 0x1135f65a0
+                  returnPC: 0x50ce61227e99
+                  callerFrame: 0x7ffee8285770
+                  rawLocationBits: 4 0x4
+                  codeBlock: 0x1135bd0a0 #BU6Zcd:[0x1135bd0a0->0x1135bc260->0x1135e5180, DFGFunctionCall, 112 (DidTryToEnterInLoop)]
+                    hasCodeOrigins: true
+                    callSiteIndex: 4 of 12
+                    jitCode: 0x113004000 start 0x50ce61212c60 end 0x50ce61214960
+                    line: 26
+                    column: 22
+                  EntryFrame: 0x7ffee8285860
+                }
+                [2] frame 0x7ffee8285770 {
+                  name: 
+                  sourceURL: date-format-xparb.js
+                  isInlinedFrame: false
+                  callee: 0x1135f64e0
+                  returnPC: 0x108058eb1
+                  callerFrame: 0x7ffee82857e0
+                  rawLocationBits: 1001 0x3e9
+                  codeBlock: 0x1135bc130 #DAS9xe:[0x1135bc130->0x1135e5100, BaselineFunctionCall, 1149]
+                    bc#1001 of 1149
+                    line: 417
+                    column: 38
+                  EntryFrame: 0x7ffee8285860
+                }
+                [3] frame 0x7ffee82857e0 {
+                  name: global code
+                  sourceURL: date-format-xparb.js
+                  isInlinedFrame: false
+                  callee: 0x1130f97b8
+                  returnPC: 0x108039043
+                  callerFrame: 0x0
+                  rawLocationBits: 23 0x17
+                  codeBlock: 0x1135bc000 <global>#CukXvt:[0x1135bc000->0x1130cd768, LLIntGlobal, 81]
+                    bc#23 of 81
+                    line: 425
+                    column: 3
+                  EntryFrame: 0x7ffee8285860
+                }
+
+            ASSERTION FAILED: expectDoesGC()
+
+        The error message now comes with the node index, NodeType, codeBlock which this
+        failure was found in, and the JS call stack that led to the failure.
+
+        Changes made:
+
+        1. Introduced a DoesGCCheck value that is used to encode some of the above data.
+
+           Previously, we only recorded whether doesGC() returns true or false for the
+           Node.  Now, we record the nodeIndex and nodeOp as well.
+
+           Note that we also set DoesGC expectations for OSR exits.  So, DoesGCCheck
+           includes Special cases for those.
+
+        2. Added store64(TrustedImm64 imm, const void* address) emitters for X86_64 and ARM64.
+           Also added a test for this new emitter in testmasm.
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::store64):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::store64):
+        * assembler/testmasm.cpp:
+        (JSC::testStore64Imm64AddressPointer):
+        (JSC::run):
+        * dfg/DFGDoesGCCheck.cpp: Added.
+        (JSC::DFG::DoesGCCheck::verifyCanGC):
+        * dfg/DFGDoesGCCheck.h: Added.
+        (JSC::DFG::DoesGCCheck::DoesGCCheck):
+        (JSC::DFG::DoesGCCheck::encode):
+        (JSC::DFG::DoesGCCheck::set):
+        (JSC::DFG::DoesGCCheck::expectDoesGC):
+        (JSC::DFG::DoesGCCheck::special):
+        (JSC::DFG::DoesGCCheck::nodeIndex):
+        (JSC::DFG::DoesGCCheck::nodeOp):
+        (JSC::DFG::DoesGCCheck::isSpecial):
+        (JSC::DFG::DoesGCCheck::specialIndex):
+        (JSC::DFG::DoesGCCheck::bits):
+        * dfg/DFGGraph.cpp:
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::operationCompileOSRExit):
+        (JSC::DFG::OSRExit::compileExit):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        (JSC::FTL::operationCompileFTLOSRExit):
+        * heap/CompleteSubspace.cpp:
+        (JSC::CompleteSubspace::tryAllocateSlow):
+        (JSC::CompleteSubspace::reallocatePreciseAllocationNonVirtual):
+        * heap/CompleteSubspaceInlines.h:
+        (JSC::CompleteSubspace::allocateNonVirtual):
+        * heap/DeferGC.h:
+        (JSC::DeferGC::~DeferGC):
+        * heap/GCDeferralContextInlines.h:
+        (JSC::GCDeferralContext::~GCDeferralContext):
+        * heap/Heap.cpp:
+        (JSC::Heap::collectNow):
+        (JSC::Heap::collectAsync):
+        (JSC::Heap::collectSync):
+        (JSC::Heap::stopIfNecessarySlow):
+        (JSC::Heap::collectIfNecessaryOrDefer):
+        * heap/Heap.h:
+        (JSC::Heap::addressOfDoesGC):
+        (JSC::Heap::setDoesGCExpectation):
+        (JSC::Heap::verifyCanGC):
+        (JSC::Heap::expectDoesGC const): Deleted.
+        (JSC::Heap::setExpectDoesGC): Deleted.
+        (JSC::Heap::addressOfExpectDoesGC): Deleted.
+        * heap/HeapInlines.h:
+        (JSC::Heap::acquireAccess):
+        (JSC::Heap::stopIfNecessary):
+        * heap/LocalAllocatorInlines.h:
+        (JSC::LocalAllocator::allocate):
+        * heap/PreciseAllocation.cpp:
+        (JSC::PreciseAllocation::tryCreate):
+        (JSC::PreciseAllocation::createForLowerTier):
+        * runtime/JSString.h:
+        (JSC::jsSingleCharacterString):
+        (JSC::JSString::toAtomString const):
+        (JSC::JSString::toExistingAtomString const):
+        (JSC::JSString::value const):
+        (JSC::JSString::tryGetValue const):
+        (JSC::JSRopeString::unsafeView const):
+        (JSC::JSRopeString::viewWithUnderlyingString const):
+        (JSC::JSString::unsafeView const):
+        * runtime/RegExpMatchesArray.h:
+        (JSC::createRegExpMatchesArray):
+
+2020-06-02  Mark Lam  <mark....@apple.com>
+
         VMInspector APIs should be taking a VM* instead of a JSGlobalObject*.
         https://bugs.webkit.org/show_bug.cgi?id=212676
 

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (262474 => 262475)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1936,6 +1936,7 @@
 		FEB51F6C1A97B688001F921C /* Regress141809.mm in Sources */ = {isa = PBXBuildFile; fileRef = FEB51F6B1A97B688001F921C /* Regress141809.mm */; };
 		FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FEB58C13187B8B160098EF0B /* ErrorHandlingScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FEC160322339E9F900A04CB8 /* CellSize.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC160312339E9F900A04CB8 /* CellSize.h */; };
+		FEC3A3A1248735CA00395B54 /* DFGDoesGCCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC3A3A0248735BC00395B54 /* DFGDoesGCCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FEC5797323105B5100BCA83F /* VMInspectorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC5797223105B4800BCA83F /* VMInspectorInlines.h */; };
 		FEC5797623105F4E00BCA83F /* Integrity.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC5797523105F4300BCA83F /* Integrity.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FEC579782310954C00BCA83F /* IntegrityInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEC579772310954B00BCA83F /* IntegrityInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -5232,6 +5233,8 @@
 		FEB58C12187B8B160098EF0B /* ErrorHandlingScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorHandlingScope.cpp; sourceTree = "<group>"; };
 		FEB58C13187B8B160098EF0B /* ErrorHandlingScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorHandlingScope.h; sourceTree = "<group>"; };
 		FEC160312339E9F900A04CB8 /* CellSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CellSize.h; sourceTree = "<group>"; };
+		FEC3A39F248735BC00395B54 /* DFGDoesGCCheck.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDoesGCCheck.cpp; path = dfg/DFGDoesGCCheck.cpp; sourceTree = "<group>"; };
+		FEC3A3A0248735BC00395B54 /* DFGDoesGCCheck.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DFGDoesGCCheck.h; path = dfg/DFGDoesGCCheck.h; sourceTree = "<group>"; };
 		FEC5797223105B4800BCA83F /* VMInspectorInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspectorInlines.h; sourceTree = "<group>"; };
 		FEC5797423105F4200BCA83F /* Integrity.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Integrity.cpp; sourceTree = "<group>"; };
 		FEC5797523105F4300BCA83F /* Integrity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Integrity.h; sourceTree = "<group>"; };
@@ -7896,6 +7899,8 @@
 				0FF427621591A1C9004CB9FF /* DFGDisassembler.h */,
 				0F5A1271192D9FDF008764A3 /* DFGDoesGC.cpp */,
 				0F5A1272192D9FDF008764A3 /* DFGDoesGC.h */,
+				FEC3A39F248735BC00395B54 /* DFGDoesGCCheck.cpp */,
+				FEC3A3A0248735BC00395B54 /* DFGDoesGCCheck.h */,
 				0FD81AD0154FB4EB00983E72 /* DFGDominators.h */,
 				0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */,
 				0FD3C82014115CF800FD81CB /* DFGDriver.cpp */,
@@ -10196,6 +10201,7 @@
 				79D5CD5B1C1106A900CECA07 /* SamplingProfiler.h in Headers */,
 				0FE050281AA9095600D33B33 /* ScopedArguments.h in Headers */,
 				0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
+				FEC3A3A1248735CA00395B54 /* DFGDoesGCCheck.h in Headers */,
 				0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
 				0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */,
 				33111B8B2397256500AA34CE /* Scribble.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (262474 => 262475)


--- trunk/Source/_javascript_Core/Sources.txt	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/Sources.txt	2020-06-03 04:47:30 UTC (rev 262475)
@@ -347,6 +347,7 @@
 dfg/DFGDesiredWeakReferences.cpp
 dfg/DFGDisassembler.cpp
 dfg/DFGDoesGC.cpp
+dfg/DFGDoesGCCheck.cpp
 dfg/DFGDriver.cpp
 dfg/DFGEdge.cpp
 dfg/DFGEpoch.cpp

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (262474 => 262475)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM64.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1459,6 +1459,17 @@
         store<64>(src, address);
     }
 
+    void store64(TrustedImm64 imm, const void* address)
+    {
+        if (!imm.m_value) {
+            store64(ARM64Registers::zr, address);
+            return;
+        }
+
+        moveToCachedReg(imm, dataMemoryTempRegister());
+        store64(dataTempRegister, address);
+    }
+
     void store64(TrustedImm32 imm, ImplicitAddress address)
     {
         store64(TrustedImm64(imm.m_value), address);

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (262474 => 262475)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -977,6 +977,22 @@
         m_assembler.movq_i32m(imm.m_value, address.offset, address.base, address.index, address.scale);
     }
 
+    void store64(TrustedImm64 imm, void* address)
+    {
+        if (CAN_SIGN_EXTEND_32_64(imm.m_value)) {
+            auto addressReg = scratchRegister();
+            move(TrustedImmPtr(address), addressReg);
+            store64(TrustedImm32(static_cast<int32_t>(imm.m_value)), addressReg);
+            return;
+        }
+
+        auto src = ""
+        move(imm, src);
+        swap(src, X86Registers::eax);
+        m_assembler.movq_EAXm(address);
+        swap(src, X86Registers::eax);
+    }
+
     void store64(TrustedImm64 imm, ImplicitAddress address)
     {
         if (CAN_SIGN_EXTEND_32_64(imm.m_value)) {

Modified: trunk/Source/_javascript_Core/assembler/testmasm.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/assembler/testmasm.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/assembler/testmasm.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -658,6 +658,31 @@
     bool wordCanBeZero = false;
     testCountTrailingZeros64Impl(wordCanBeZero);
 }
+
+void testStore64Imm64AddressPointer()
+{
+    auto doTest = [] (int64_t value) {
+        int64_t dest;
+        void* destAddress = &dest;
+
+        auto test = compile([=] (CCallHelpers& jit) {
+            emitFunctionPrologue(jit);
+            jit.store64(CCallHelpers::TrustedImm64(value), destAddress);
+            emitFunctionEpilogue(jit);
+            jit.ret();
+        });
+
+        invoke<size_t>(test);
+        CHECK_EQ(dest, value);
+    };
+    
+    for (auto value : int64Operands())
+        doTest(value);
+
+    doTest(0x98765555AAAA4321);
+    doTest(0xAAAA432198765555);
+}
+
 #endif // CPU(X86_64) || CPU(ARM64)
 
 void testCompareDouble(MacroAssembler::DoubleCondition condition)
@@ -2499,6 +2524,7 @@
     RUN(testClearBits64WithMaskTernary());
     RUN(testCountTrailingZeros64());
     RUN(testCountTrailingZeros64WithoutNullCheck());
+    RUN(testStore64Imm64AddressPointer());
 #endif
 
 #if CPU(ARM64)

Added: trunk/Source/_javascript_Core/dfg/DFGDoesGCCheck.cpp (0 => 262475)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGCCheck.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGCCheck.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DFGDoesGCCheck.h"
+
+#include "CallFrame.h"
+#include "CodeBlock.h"
+#include "Heap.h"
+#include "VMInspector.h"
+#include <wtf/DataLog.h>
+
+namespace JSC {
+namespace DFG {
+
+#if ENABLE(DFG_DOES_GC_VALIDATION)
+
+extern const char* dfgOpNames[];
+
+JS_EXPORT_PRIVATE void DoesGCCheck::verifyCanGC(VM& vm)
+{
+    if (!expectDoesGC()) {
+        dataLog("Error: DoesGC failed");
+        if (isSpecial()) {
+            switch (special()) {
+            case Special::Uninitialized:
+                break;
+            case Special::DFGOSRExit:
+                dataLog(" @ DFG osr exit");
+                break;
+            case Special::FTLOSRExit:
+                dataLog(" @ FTL osr exit");
+                break;
+            case Special::ReservedUnused:
+            case Special::NumberOfSpecials:
+                RELEASE_ASSERT_NOT_REACHED();
+            }
+        } else
+            dataLog(" @ D@", nodeIndex(), " ", DFG::dfgOpNames[nodeOp()]);
+
+        CallFrame* callFrame = vm.topCallFrame;
+        if (callFrame) {
+            CodeBlock* codeBlock = callFrame->codeBlock();
+            dataLogLn(" in ", codeBlock);
+            VMInspector::dumpStack(&vm, callFrame);
+        }
+        dataLogLn();
+    }
+    RELEASE_ASSERT(expectDoesGC());
+}
+#endif // ENABLE(DFG_DOES_GC_VALIDATION)
+
+} // namespace DFG
+} // namespace JSC
+

Added: trunk/Source/_javascript_Core/dfg/DFGDoesGCCheck.h (0 => 262475)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGCCheck.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGCCheck.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+class VM;
+
+namespace DFG {
+
+struct DoesGCCheck {
+    enum class Special {
+        ReservedUnused, // so that specials start with 1. isSpecial() relies on this.
+        Uninitialized,
+        DFGOSRExit,
+        FTLOSRExit,
+        NumberOfSpecials
+    };
+
+    DoesGCCheck()
+        : m_value(encode(true, Special::Uninitialized))
+    { }
+
+    static uint64_t encode(bool expectDoesGC, unsigned nodeIndex, unsigned nodeOp)
+    {
+        uint64_t result = bits(nodeIndex) << nodeIndexShift;
+        result |= bits(nodeOp) << nodeOpShift;
+        result |= bits(expectDoesGC) << expectDoesGCShift;
+        return result;
+    }
+
+    static uint64_t encode(bool expectDoesGC, Special special)
+    {
+        ASSERT(bits(special) < numberOfSpecials);
+        uint64_t result = bits(special) << specialShift;
+        result |= bits(expectDoesGC) << expectDoesGCShift;
+        return result;
+    }
+
+    void set(bool expectDoesGC, unsigned nodeIndex, unsigned nodeOp)
+    {
+        m_value = encode(expectDoesGC, nodeIndex, nodeOp);
+    }
+
+    void set(bool expectDoesGC, Special special)
+    {
+        m_value = encode(expectDoesGC, special);
+    }
+
+    bool expectDoesGC() { return m_value & expectDoesGCMask; }
+    Special special() { return static_cast<Special>(specialIndex()); }
+    unsigned nodeIndex() { return m_value >> nodeIndexShift; }
+    unsigned nodeOp() { return (m_value >> nodeOpShift) & nodeOpMask; }
+
+    bool isSpecial() { return specialIndex(); }
+
+    void verifyCanGC(VM&);
+
+private:
+    unsigned specialIndex() { return (m_value >> specialShift) & specialMask; }
+
+    template<typename T> static uint64_t bits(T value) { return static_cast<uint64_t>(value); }
+
+    static constexpr uint64_t numberOfSpecials = static_cast<uint64_t>(Special::NumberOfSpecials);
+
+    static constexpr unsigned expectDoesGCShift = 0;
+    static constexpr unsigned specialShift = 1;
+    static constexpr unsigned nodeOpShift = 16;
+    static constexpr unsigned nodeIndexShift = 32;
+
+    static constexpr unsigned expectDoesGCMask = 0x1;
+    static constexpr unsigned specialMask = 0x7fff;
+    static constexpr unsigned nodeOpMask = 0xffff;
+
+    uint64_t m_value { 0 };
+};
+
+} // namespace DFG
+
+using DFG::DoesGCCheck;
+
+} // namespace JSC

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -62,7 +62,7 @@
 static constexpr bool dumpOSRAvailabilityData = false;
 
 // Creates an array of stringized names.
-static const char* dfgOpNames[] = {
+const char* dfgOpNames[] = {
 #define STRINGIZE_DFG_OP_ENUM(opcode, flags) #opcode ,
     FOR_EACH_DFG_OP(STRINGIZE_DFG_OP_ENUM)
 #undef STRINGIZE_DFG_OP_ENUM

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -146,7 +146,7 @@
     if (validateDFGDoesGC) {
         // We're about to exit optimized code. So, there's no longer any optimized
         // code running that expects no GC.
-        vm.heap.setExpectDoesGC(true);
+        vm.heap.setDoesGCExpectation(true, DoesGCCheck::Special::DFGOSRExit);
     }
 
     if (vm.callFrameForCatch)
@@ -555,11 +555,11 @@
         // code running that expects no GC. We need to set this before arguments
         // materialization below (see emitRestoreArguments()).
 
-        // Even though we set Heap::m_expectDoesGC in compileOSRExit(), we also need
+        // Even though we set Heap::m_doesGC in compileOSRExit(), we also need
         // to set it here because compileOSRExit() is only called on the first time
         // we exit from this site, but all subsequent exits will take this compiled
         // ramp without calling compileOSRExit() first.
-        jit.store8(CCallHelpers::TrustedImm32(true), vm.heap.addressOfExpectDoesGC());
+        jit.store64(CCallHelpers::TrustedImm64(DoesGCCheck::encode(true, DoesGCCheck::Special::DFGOSRExit)), vm.heap.addressOfDoesGC());
     }
 
     // Need to ensure that the stack pointer accounts for the worst-case stack usage at exit. This

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -2138,7 +2138,7 @@
 
     if (validateDFGDoesGC) {
         bool expectDoesGC = doesGC(m_jit.graph(), node);
-        m_jit.store8(TrustedImm32(expectDoesGC), vm().heap.addressOfExpectDoesGC());
+        m_jit.store64(TrustedImm64(DoesGCCheck::encode(expectDoesGC, node->index(), node->op())), vm().heap.addressOfDoesGC());
     }
 
 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -704,7 +704,7 @@
 
         if (validateDFGDoesGC) {
             bool expectDoesGC = doesGC(m_graph, m_node);
-            m_out.store(m_out.constBool(expectDoesGC), m_out.absolute(vm().heap.addressOfExpectDoesGC()));
+            m_out.store(m_out.constInt64(DoesGCCheck::encode(expectDoesGC, m_node->index(), m_node->op())), m_out.absolute(vm().heap.addressOfDoesGC()));
         }
 
         switch (m_node->op()) {

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -211,11 +211,11 @@
         // code running that expects no GC. We need to set this before object
         // materialization below.
 
-        // Even though we set Heap::m_expectDoesGC in compileFTLOSRExit(), we also need
+        // Even though we set Heap::m_doesGC in compileFTLOSRExit(), we also need
         // to set it here because compileFTLOSRExit() is only called on the first time
         // we exit from this site, but all subsequent exits will take this compiled
         // ramp without calling compileFTLOSRExit() first.
-        jit.store8(CCallHelpers::TrustedImm32(true), vm.heap.addressOfExpectDoesGC());
+        jit.store64(CCallHelpers::TrustedImm64(DoesGCCheck::encode(true, DoesGCCheck::Special::FTLOSRExit)), vm.heap.addressOfDoesGC());
     }
 
     // Bring the stack back into a sane form and assert that it's sane.
@@ -548,7 +548,7 @@
     if (validateDFGDoesGC) {
         // We're about to exit optimized code. So, there's no longer any optimized
         // code running that expects no GC.
-        vm.heap.setExpectDoesGC(true);
+        vm.heap.setDoesGCExpectation(true, DoesGCCheck::Special::FTLOSRExit);
     }
 
     if (vm.callFrameForCatch)

Modified: trunk/Source/_javascript_Core/heap/CompleteSubspace.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/CompleteSubspace.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/CompleteSubspace.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -120,7 +120,7 @@
 void* CompleteSubspace::tryAllocateSlow(VM& vm, size_t size, GCDeferralContext* deferralContext)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm.heap.expectDoesGC());
+        vm.heap.verifyCanGC();
 
     sanitizeStackForVM(vm);
     
@@ -156,7 +156,7 @@
 void* CompleteSubspace::reallocatePreciseAllocationNonVirtual(VM& vm, HeapCell* oldCell, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm.heap.expectDoesGC());
+        vm.heap.verifyCanGC();
 
     // The following conditions are met in Butterfly for example.
     ASSERT(oldCell->isPreciseAllocation());

Modified: trunk/Source/_javascript_Core/heap/CompleteSubspaceInlines.h (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/CompleteSubspaceInlines.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/CompleteSubspaceInlines.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,7 +33,7 @@
 ALWAYS_INLINE void* CompleteSubspace::allocateNonVirtual(VM& vm, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm.heap.expectDoesGC());
+        vm.heap.verifyCanGC();
 
     if (Allocator allocator = allocatorForNonVirtual(size, AllocatorForMode::AllocatorIfExists))
         return allocator.allocate(vm.heap, deferralContext, failureMode);

Modified: trunk/Source/_javascript_Core/heap/DeferGC.h (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/DeferGC.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/DeferGC.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,7 +45,7 @@
     ~DeferGC()
     {
         if (validateDFGDoesGC)
-            RELEASE_ASSERT(m_heap.expectDoesGC());
+            m_heap.verifyCanGC();
         m_heap.decrementDeferralDepthAndGCIfNeeded();
     }
 

Modified: trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,7 +38,7 @@
 ALWAYS_INLINE GCDeferralContext::~GCDeferralContext()
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(m_heap.expectDoesGC());
+        m_heap.verifyCanGC();
 
     if (UNLIKELY(m_shouldGC))
         m_heap.collectIfNecessaryOrDefer();

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2020 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel <e...@webkit.org>
  *
  *  This library is free software; you can redistribute it and/or
@@ -1064,7 +1064,7 @@
 void Heap::collectNow(Synchronousness synchronousness, GCRequest request)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     switch (synchronousness) {
     case Async: {
@@ -1097,7 +1097,7 @@
 void Heap::collectAsync(GCRequest request)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     if (!m_isSafeToCollect)
         return;
@@ -1121,7 +1121,7 @@
 void Heap::collectSync(GCRequest request)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     if (!m_isSafeToCollect)
         return;
@@ -1784,7 +1784,7 @@
 void Heap::stopIfNecessarySlow()
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     while (stopIfNecessarySlow(m_worldState.load())) { }
     
@@ -1799,7 +1799,7 @@
 bool Heap::stopIfNecessarySlow(unsigned oldState)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     RELEASE_ASSERT(oldState & hasAccessBit);
     RELEASE_ASSERT(!(oldState & stoppedBit));
@@ -2601,7 +2601,7 @@
 {
     ASSERT(deferralContext || isDeferred() || !DisallowGC::isInEffectOnCurrentThread());
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     if (!m_isSafeToCollect)
         return;

Modified: trunk/Source/_javascript_Core/heap/Heap.h (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/Heap.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (por...@kde.org)
  *  Copyright (C) 2001 Peter Kelly (p...@post.com)
- *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2020 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
 #include "CellState.h"
 #include "CollectionScope.h"
 #include "CollectorPhase.h"
+#include "DFGDoesGCCheck.h"
 #include "DeleteAllCodeEffort.h"
 #include "GCConductor.h"
 #include "GCIncomingRefCountedSet.h"
@@ -303,13 +304,15 @@
     const unsigned* addressOfBarrierThreshold() const { return &m_barrierThreshold; }
 
 #if ENABLE(DFG_DOES_GC_VALIDATION)
-    bool expectDoesGC() const { return m_expectDoesGC; }
-    void setExpectDoesGC(bool value) { m_expectDoesGC = value; }
-    bool* addressOfExpectDoesGC() { return &m_expectDoesGC; }
+    DoesGCCheck* addressOfDoesGC() { return &m_doesGC; }
+    void setDoesGCExpectation(bool expectDoesGC, unsigned nodeIndex, unsigned nodeOp) { m_doesGC.set(expectDoesGC, nodeIndex, nodeOp); }
+    void setDoesGCExpectation(bool expectDoesGC, DoesGCCheck::Special special) { m_doesGC.set(expectDoesGC, special); }
+    void verifyCanGC() { m_doesGC.verifyCanGC(vm()); }
 #else
-    bool expectDoesGC() const { UNREACHABLE_FOR_PLATFORM(); return true; }
-    void setExpectDoesGC(bool) { UNREACHABLE_FOR_PLATFORM(); }
-    bool* addressOfExpectDoesGC() { UNREACHABLE_FOR_PLATFORM(); return nullptr; }
+    DoesGCCheck* addressOfDoesGC() { UNREACHABLE_FOR_PLATFORM(); return nullptr; }
+    void setDoesGCExpectation(bool, unsigned, unsigned) { }
+    void setDoesGCExpectation(bool, DoesGCCheck::Special) { }
+    void verifyCanGC() { }
 #endif
 
     // If true, the GC believes that the mutator is currently messing with the heap. We call this
@@ -606,7 +609,7 @@
     Markable<CollectionScope, EnumMarkableTraits<CollectionScope>> m_lastCollectionScope;
     Lock m_raceMarkStackLock;
 #if ENABLE(DFG_DOES_GC_VALIDATION)
-    bool m_expectDoesGC { true };
+    DoesGCCheck m_doesGC;
 #endif
 
     StructureIDTable m_structureIDTable;

Modified: trunk/Source/_javascript_Core/heap/HeapInlines.h (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/HeapInlines.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/HeapInlines.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -236,7 +236,7 @@
 inline void Heap::acquireAccess()
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     if (m_worldState.compareExchangeWeak(0, hasAccessBit))
         return;
@@ -263,7 +263,7 @@
 inline void Heap::stopIfNecessary()
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(expectDoesGC());
+        verifyCanGC();
 
     if (mayNeedToStop())
         stopIfNecessarySlow();

Modified: trunk/Source/_javascript_Core/heap/LocalAllocatorInlines.h (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/LocalAllocatorInlines.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/LocalAllocatorInlines.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -33,7 +33,7 @@
 ALWAYS_INLINE void* LocalAllocator::allocate(Heap& heap, GCDeferralContext* deferralContext, AllocationFailureMode failureMode)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(heap.expectDoesGC());
+        heap.verifyCanGC();
     return m_freeList.allocate(
         [&] () -> HeapCell* {
             sanitizeStackForVM(heap.vm());

Modified: trunk/Source/_javascript_Core/heap/PreciseAllocation.cpp (262474 => 262475)


--- trunk/Source/_javascript_Core/heap/PreciseAllocation.cpp	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/heap/PreciseAllocation.cpp	2020-06-03 04:47:30 UTC (rev 262475)
@@ -43,7 +43,7 @@
 PreciseAllocation* PreciseAllocation::tryCreate(Heap& heap, size_t size, Subspace* subspace, unsigned indexInSpace)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(heap.expectDoesGC());
+        heap.verifyCanGC();
 
     size_t adjustedAlignmentAllocationSize = headerSize() + size + halfAlignment;
     static_assert(halfAlignment == 8, "We assume that memory returned by malloc has alignment >= 8.");
@@ -123,7 +123,7 @@
 PreciseAllocation* PreciseAllocation::createForLowerTier(Heap& heap, size_t size, Subspace* subspace, uint8_t lowerTierIndex)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(heap.expectDoesGC());
+        heap.verifyCanGC();
 
     size_t adjustedAlignmentAllocationSize = headerSize() + size + halfAlignment;
     static_assert(halfAlignment == 8, "We assume that memory returned by malloc has alignment >= 8.");

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (262474 => 262475)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -733,7 +733,7 @@
 ALWAYS_INLINE JSString* jsSingleCharacterString(VM& vm, UChar c)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm.heap.expectDoesGC());
+        vm.heap.verifyCanGC();
     if (c <= maxSingleCharacterString)
         return vm.smallStrings.singleCharacterString(c);
     return JSString::create(vm, StringImpl::create(&c, 1));
@@ -763,7 +763,7 @@
 ALWAYS_INLINE AtomString JSString::toAtomString(JSGlobalObject* globalObject) const
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm().heap.expectDoesGC());
+        vm().heap.verifyCanGC();
     if (isRope())
         return static_cast<const JSRopeString*>(this)->resolveRopeToAtomString(globalObject);
     return AtomString(valueInternal());
@@ -772,7 +772,7 @@
 ALWAYS_INLINE RefPtr<AtomStringImpl> JSString::toExistingAtomString(JSGlobalObject* globalObject) const
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm().heap.expectDoesGC());
+        vm().heap.verifyCanGC();
     if (isRope())
         return static_cast<const JSRopeString*>(this)->resolveRopeToExistingAtomString(globalObject);
     if (valueInternal().impl()->isAtom())
@@ -783,7 +783,7 @@
 inline const String& JSString::value(JSGlobalObject* globalObject) const
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm().heap.expectDoesGC());
+        vm().heap.verifyCanGC();
     if (isRope())
         return static_cast<const JSRopeString*>(this)->resolveRope(globalObject);
     return valueInternal();
@@ -793,7 +793,7 @@
 {
     if (allocationAllowed) {
         if (validateDFGDoesGC)
-            RELEASE_ASSERT(vm().heap.expectDoesGC());
+            vm().heap.verifyCanGC();
         if (isRope()) {
             // Pass nullptr for the JSGlobalObject so that resolveRope does not throw in the event of an OOM error.
             return static_cast<const JSRopeString*>(this)->resolveRope(nullptr);
@@ -983,7 +983,7 @@
 ALWAYS_INLINE StringView JSRopeString::unsafeView(JSGlobalObject* globalObject) const
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm().heap.expectDoesGC());
+        vm().heap.verifyCanGC();
     if (isSubstring()) {
         auto& base = substringBase()->valueInternal();
         if (base.is8Bit())
@@ -996,7 +996,7 @@
 ALWAYS_INLINE StringViewWithUnderlyingString JSRopeString::viewWithUnderlyingString(JSGlobalObject* globalObject) const
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm().heap.expectDoesGC());
+        vm().heap.verifyCanGC();
     if (isSubstring()) {
         auto& base = substringBase()->valueInternal();
         if (base.is8Bit())
@@ -1010,7 +1010,7 @@
 ALWAYS_INLINE StringView JSString::unsafeView(JSGlobalObject* globalObject) const
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm().heap.expectDoesGC());
+        vm().heap.verifyCanGC();
     if (isRope())
         return static_cast<const JSRopeString*>(this)->unsafeView(globalObject);
     return valueInternal();

Modified: trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h (262474 => 262475)


--- trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h	2020-06-03 03:59:46 UTC (rev 262474)
+++ trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h	2020-06-03 04:47:30 UTC (rev 262475)
@@ -64,7 +64,7 @@
     RegExp* regExp, unsigned startOffset, MatchResult& result)
 {
     if (validateDFGDoesGC)
-        RELEASE_ASSERT(vm.heap.expectDoesGC());
+        vm.heap.verifyCanGC();
 
     Vector<int, 32> subpatternResults;
     int position = regExp->matchInline(globalObject, vm, inputValue, startOffset, subpatternResults);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to