Diff
Modified: trunk/JSTests/ChangeLog (262919 => 262920)
--- trunk/JSTests/ChangeLog 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/JSTests/ChangeLog 2020-06-11 20:11:34 UTC (rev 262920)
@@ -1,3 +1,17 @@
+2020-06-11 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Return DisposableCallSiteIndex when destroying GCAwareJITStubRoutineWithExceptionHandler
+ https://bugs.webkit.org/show_bug.cgi?id=213069
+ <rdar://problem/64205186>
+
+ Reviewed by Saam Barati.
+
+ * stress/dont-dispose-callsiteindex-while-executing.js: Added.
+ (emptyFunction):
+ (foo.bar.set catch):
+ (foo.bar):
+ (foo):
+
2020-06-11 Alexey Shvayka <shvaikal...@gmail.com>
RegExp.prototype getters should throw on cross-realm access
Added: trunk/JSTests/stress/dont-dispose-callsiteindex-while-executing.js (0 => 262920)
--- trunk/JSTests/stress/dont-dispose-callsiteindex-while-executing.js (rev 0)
+++ trunk/JSTests/stress/dont-dispose-callsiteindex-while-executing.js 2020-06-11 20:11:34 UTC (rev 262920)
@@ -0,0 +1,24 @@
+//@ runDefault("--jitPolicyScale=0")
+
+function emptyFunction() {}
+
+function foo(a0) {
+ function bar(a1) {
+ let o = Object(a0);
+ try {
+ o.x = 0;
+ new Set().values();
+ gc();
+ Object.defineProperty(a1, 'x', { set: bar });
+ } catch {}
+
+ try {
+ Function('function');
+ } catch {}
+ }
+ bar(emptyFunction);
+}
+
+foo(0);
+for (let i=0; i<100; i++)
+ foo(emptyFunction);
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (262919 => 262920)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2020-06-11 20:11:34 UTC (rev 262920)
@@ -563,6 +563,7 @@
debugger/DebuggerParseData.h
debugger/DebuggerPrimitives.h
+ dfg/DFGCodeOriginPool.h
dfg/DFGCommon.h
dfg/DFGCompilationMode.h
dfg/DFGDoesGCCheck.h
Modified: trunk/Source/_javascript_Core/ChangeLog (262919 => 262920)
--- trunk/Source/_javascript_Core/ChangeLog 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-06-11 20:11:34 UTC (rev 262920)
@@ -1,3 +1,87 @@
+2020-06-11 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Return DisposableCallSiteIndex when destroying GCAwareJITStubRoutineWithExceptionHandler
+ https://bugs.webkit.org/show_bug.cgi?id=213069
+ <rdar://problem/64205186>
+
+ Reviewed by Saam Barati.
+
+ Inside GCAwareJITStubRoutineWithExceptionHandler::observeZeroRefCount, we are returning DisposableCallSiteIndex to freelist.
+ However, GCAwareJITStubRoutineWithExceptionHandler::observeZeroRefCount can be called even if the code of GCAwareJITStubRoutineWithExceptionHandler is
+ on the stack. Let's consider the following scenario.
+
+ 1. Execute GCAwareJITStubRoutineWithExceptionHandler's code. Set CallSiteIndex to the stack.
+ 2. Execute more code. (1)'s GCAwareJITStubRoutineWithExceptionHandler's code is on the stack.
+ 3. (1)'s GCAwareJITStubRoutineWithExceptionHandler's refcount becomes zero.
+ 4. CallSiteIndex of GCAwareJITStubRoutineWithExceptionHandler is returned.
+ 5. Execute StackVisitor to construct frames. But we cannot find CodeOrigin corresponding to CallSiteIndex stored in (1) since it is already returned.
+
+ DisposableCallSiteIndex should be returned after ensuring that GCAwareJITStubRoutineWithExceptionHandler's code is not on the stack. Detecting this is the functionality
+ what GCAwareJITStubRoutineWithExceptionHandler can offer. It is destroyed after ensuring that GCAwareJITStubRoutineWithExceptionHandler's code is not on the stack.
+
+ This patch delays DisposableCallSiteIndex returning until we destroy owner GCAwareJITStubRoutineWithExceptionHandler. But it is possible that CodeBlock* corresponding to
+ GCAwareJITStubRoutineWithExceptionHandler is already destroyed. To avoid this condition, we extract CodeOrigins vector as Ref<DFG::CodeOriginPool> and keep it alive from
+ GCAwareJITStubRoutineWithExceptionHandler too. And since CodeOrigin addition / removal happens only from the main thread after finishing the compilation, and
+ GCAwareJITStubRoutineWithExceptionHandler's destructor is called from the Heap's finalizer, which must be executed from the main thread, we can just modify it without a lock.
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::newExceptionHandlingCallSiteIndex):
+ (JSC::CodeBlock::codeOrigins):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::codeOrigin):
+ * dfg/DFGCodeOriginPool.cpp: Added.
+ (JSC::DFG::CodeOriginPool::addCodeOrigin):
+ (JSC::DFG::CodeOriginPool::addUniqueCallSiteIndex):
+ (JSC::DFG::CodeOriginPool::lastCallSite const):
+ (JSC::DFG::CodeOriginPool::addDisposableCallSiteIndex):
+ (JSC::DFG::CodeOriginPool::removeDisposableCallSiteIndex):
+ (JSC::DFG::CodeOriginPool::shrinkToFit):
+ * dfg/DFGCodeOriginPool.h: Added.
+ (JSC::DFG::CodeOriginPool::create):
+ (JSC::DFG::CodeOriginPool::get):
+ (JSC::DFG::CodeOriginPool::size const):
+ * dfg/DFGCommonData.cpp:
+ (JSC::DFG::CommonData::shrinkToFit):
+ (JSC::DFG::CommonData::addCodeOrigin): Deleted.
+ (JSC::DFG::CommonData::addUniqueCallSiteIndex): Deleted.
+ (JSC::DFG::CommonData::lastCallSite const): Deleted.
+ (JSC::DFG::CommonData::addDisposableCallSiteIndex): Deleted.
+ (JSC::DFG::CommonData::removeDisposableCallSiteIndex): Deleted.
+ * dfg/DFGCommonData.h:
+ (JSC::DFG::CommonData::CommonData):
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::exceptionCheck):
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::addCallSite):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compilePutById):
+ (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
+ (JSC::FTL::DFG::LowerDFGToB3::compileDelBy):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstruct):
+ (JSC::FTL::DFG::LowerDFGToB3::compileDirectCallOrConstruct):
+ (JSC::FTL::DFG::LowerDFGToB3::compileTailCall):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargsSpread):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargs):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCallEval):
+ (JSC::FTL::DFG::LowerDFGToB3::compileInById):
+ (JSC::FTL::DFG::LowerDFGToB3::compileInstanceOf):
+ (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenTail):
+ (JSC::FTL::DFG::LowerDFGToB3::getById):
+ (JSC::FTL::DFG::LowerDFGToB3::getByIdWithThis):
+ (JSC::FTL::DFG::LowerDFGToB3::lazySlowPath):
+ (JSC::FTL::DFG::LowerDFGToB3::callPreflight):
+ * ftl/FTLSlowPathCall.cpp:
+ (JSC::FTL::callSiteIndexForCodeOrigin):
+ * jit/GCAwareJITStubRoutine.cpp:
+ (JSC::GCAwareJITStubRoutineWithExceptionHandler::GCAwareJITStubRoutineWithExceptionHandler):
+ (JSC::GCAwareJITStubRoutineWithExceptionHandler::~GCAwareJITStubRoutineWithExceptionHandler):
+ (JSC::GCAwareJITStubRoutineWithExceptionHandler::aboutToDie):
+ (JSC::GCAwareJITStubRoutineWithExceptionHandler::observeZeroRefCount):
+ * jit/GCAwareJITStubRoutine.h:
+
2020-06-11 Alexey Shvayka <shvaikal...@gmail.com>
RegExp.prototype getters should throw on cross-realm access
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (262919 => 262920)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2020-06-11 20:11:34 UTC (rev 262920)
@@ -1812,6 +1812,7 @@
E33F50811B8429A400413856 /* JSInternalPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F507F1B8429A400413856 /* JSInternalPromise.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33F50871B8449EF00413856 /* JSInternalPromiseConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */; };
E3400EC122A1CC7B009DED54 /* FunctionExecutableInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3400EC022A1CC78009DED54 /* FunctionExecutableInlines.h */; };
+ E349A7812491F161001BA336 /* DFGCodeOriginPool.h in Headers */ = {isa = PBXBuildFile; fileRef = E349A7802491F15A001BA336 /* DFGCodeOriginPool.h */; settings = {ATTRIBUTES = (Private, ); }; };
E34E657520668EAA00FB81AC /* ParseHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E34E657320668E8D00FB81AC /* ParseHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */; settings = {ATTRIBUTES = (Private, ); }; };
E34F930E2322D882002B8DB4 /* JSGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E34F930C2322D881002B8DB4 /* JSGenerator.h */; };
@@ -4972,6 +4973,8 @@
E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalPromiseConstructor.lut.h; sourceTree = "<group>"; };
E33F50881B844A1A00413856 /* InternalPromiseConstructor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = InternalPromiseConstructor.js; sourceTree = "<group>"; };
E3400EC022A1CC78009DED54 /* FunctionExecutableInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionExecutableInlines.h; sourceTree = "<group>"; };
+ E349A77F2491F159001BA336 /* DFGCodeOriginPool.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCodeOriginPool.cpp; path = dfg/DFGCodeOriginPool.cpp; sourceTree = "<group>"; };
+ E349A7802491F15A001BA336 /* DFGCodeOriginPool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DFGCodeOriginPool.h; path = dfg/DFGCodeOriginPool.h; sourceTree = "<group>"; };
E34E657320668E8D00FB81AC /* ParseHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseHash.h; sourceTree = "<group>"; };
E34E657420668E8E00FB81AC /* ParseHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseHash.cpp; sourceTree = "<group>"; };
E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameTracers.h; sourceTree = "<group>"; };
@@ -7864,6 +7867,8 @@
A77A423B17A0BBFD00A8DB81 /* DFGClobberSet.h */,
0F3C1F181B868E7900ABB08B /* DFGClobbersExitState.cpp */,
0F3C1F191B868E7900ABB08B /* DFGClobbersExitState.h */,
+ E349A77F2491F159001BA336 /* DFGCodeOriginPool.cpp */,
+ E349A7802491F15A001BA336 /* DFGCodeOriginPool.h */,
0F04396B1B03DC0B009598B7 /* DFGCombinedLiveness.cpp */,
0F04396C1B03DC0B009598B7 /* DFGCombinedLiveness.h */,
0FB4B51A16B62772003F696B /* DFGCommon.cpp */,
@@ -9327,6 +9332,7 @@
A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */,
+ E349A7812491F161001BA336 /* DFGCodeOriginPool.h in Headers */,
0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
0FEA0A32170D40BF00BB722C /* DFGCommonData.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (262919 => 262920)
--- trunk/Source/_javascript_Core/Sources.txt 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/Sources.txt 2020-06-11 20:11:34 UTC (rev 262920)
@@ -332,6 +332,7 @@
dfg/DFGClobberSet.cpp
dfg/DFGClobberize.cpp
dfg/DFGClobbersExitState.cpp
+dfg/DFGCodeOriginPool.cpp
dfg/DFGCombinedLiveness.cpp
dfg/DFGCommon.cpp
dfg/DFGCommonData.cpp
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (262919 => 262920)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -1875,7 +1875,7 @@
RELEASE_ASSERT(canGetCodeOrigin(originalCallSite));
ASSERT(!!handlerForIndex(originalCallSite.bits()));
CodeOrigin originalOrigin = codeOrigin(originalCallSite);
- return m_jitCode->dfgCommon()->addDisposableCallSiteIndex(originalOrigin);
+ return m_jitCode->dfgCommon()->codeOrigins->addDisposableCallSiteIndex(originalOrigin);
#else
// We never create new on-the-fly exception handling
// call sites outside the DFG/FTL inline caches.
@@ -2769,9 +2769,9 @@
}
#if ENABLE(DFG_JIT)
-Vector<CodeOrigin, 0, UnsafeVectorOverflow>& CodeBlock::codeOrigins()
+DFG::CodeOriginPool& CodeBlock::codeOrigins()
{
- return m_jitCode->dfgCommon()->codeOrigins;
+ return m_jitCode->dfgCommon()->codeOrigins.get();
}
size_t CodeBlock::numberOfDFGIdentifiers() const
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (262919 => 262920)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2020-06-11 20:11:34 UTC (rev 262920)
@@ -37,6 +37,7 @@
#include "CodeType.h"
#include "CompilationResult.h"
#include "ConcurrentJSLock.h"
+#include "DFGCodeOriginPool.h"
#include "DFGCommon.h"
#include "DirectEvalCodeCache.h"
#include "EvalExecutable.h"
@@ -533,7 +534,7 @@
bool hasExpressionInfo() { return m_unlinkedCode->hasExpressionInfo(); }
#if ENABLE(DFG_JIT)
- Vector<CodeOrigin, 0, UnsafeVectorOverflow>& codeOrigins();
+ DFG::CodeOriginPool& codeOrigins();
// Having code origins implies that there has been some inlining.
bool hasCodeOrigins()
@@ -550,7 +551,7 @@
CodeOrigin codeOrigin(CallSiteIndex index)
{
- return codeOrigins()[index.bits()];
+ return codeOrigins().get(index.bits());
}
CompressedLazyOperandValueProfileHolder& lazyOperandValueProfiles(const ConcurrentJSLocker&)
Added: trunk/Source/_javascript_Core/dfg/DFGCodeOriginPool.cpp (0 => 262920)
--- trunk/Source/_javascript_Core/dfg/DFGCodeOriginPool.cpp (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGCodeOriginPool.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -0,0 +1,86 @@
+/*
+ * 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 "DFGCodeOriginPool.h"
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+CallSiteIndex CodeOriginPool::addCodeOrigin(CodeOrigin codeOrigin)
+{
+ if (m_codeOrigins.isEmpty()
+ || m_codeOrigins.last() != codeOrigin)
+ m_codeOrigins.append(codeOrigin);
+ unsigned index = m_codeOrigins.size() - 1;
+ ASSERT(m_codeOrigins[index] == codeOrigin);
+ return CallSiteIndex(index);
+}
+
+CallSiteIndex CodeOriginPool::addUniqueCallSiteIndex(CodeOrigin codeOrigin)
+{
+ m_codeOrigins.append(codeOrigin);
+ unsigned index = m_codeOrigins.size() - 1;
+ ASSERT(m_codeOrigins[index] == codeOrigin);
+ return CallSiteIndex(index);
+}
+
+CallSiteIndex CodeOriginPool::lastCallSite() const
+{
+ RELEASE_ASSERT(m_codeOrigins.size());
+ return CallSiteIndex(m_codeOrigins.size() - 1);
+}
+
+DisposableCallSiteIndex CodeOriginPool::addDisposableCallSiteIndex(CodeOrigin codeOrigin)
+{
+ if (!m_callSiteIndexFreeList.isEmpty()) {
+ unsigned index = m_callSiteIndexFreeList.takeLast();
+ m_codeOrigins[index] = codeOrigin;
+ return DisposableCallSiteIndex(index);
+ }
+
+ m_codeOrigins.append(codeOrigin);
+ unsigned index = m_codeOrigins.size() - 1;
+ ASSERT(m_codeOrigins[index] == codeOrigin);
+ return DisposableCallSiteIndex(index);
+}
+
+void CodeOriginPool::removeDisposableCallSiteIndex(DisposableCallSiteIndex callSite)
+{
+ RELEASE_ASSERT(callSite.bits() < m_codeOrigins.size());
+ m_callSiteIndexFreeList.append(callSite.bits());
+ m_codeOrigins[callSite.bits()] = CodeOrigin();
+}
+
+void CodeOriginPool::shrinkToFit()
+{
+ m_codeOrigins.shrinkToFit();
+ m_callSiteIndexFreeList.shrinkToFit();
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
Added: trunk/Source/_javascript_Core/dfg/DFGCodeOriginPool.h (0 => 262920)
--- trunk/Source/_javascript_Core/dfg/DFGCodeOriginPool.h (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGCodeOriginPool.h 2020-06-11 20:11:34 UTC (rev 262920)
@@ -0,0 +1,56 @@
+/*
+ * 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
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class CodeOriginPool : public ThreadSafeRefCounted<CodeOriginPool> {
+public:
+ static Ref<CodeOriginPool> create()
+ {
+ return adoptRef(*new CodeOriginPool);
+ }
+
+ CallSiteIndex addCodeOrigin(CodeOrigin);
+ CallSiteIndex addUniqueCallSiteIndex(CodeOrigin);
+ CallSiteIndex lastCallSite() const;
+ DisposableCallSiteIndex addDisposableCallSiteIndex(CodeOrigin);
+ void removeDisposableCallSiteIndex(DisposableCallSiteIndex);
+ void shrinkToFit();
+
+ CodeOrigin get(unsigned index) { return m_codeOrigins[index]; }
+ unsigned size() const { return m_codeOrigins.size(); }
+
+private:
+ Vector<CodeOrigin, 0, UnsafeVectorOverflow> m_codeOrigins;
+ Vector<unsigned> m_callSiteIndexFreeList;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp (262919 => 262920)
--- trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -47,55 +47,9 @@
node->transition()->next.get());
}
-CallSiteIndex CommonData::addCodeOrigin(CodeOrigin codeOrigin)
-{
- if (codeOrigins.isEmpty()
- || codeOrigins.last() != codeOrigin)
- codeOrigins.append(codeOrigin);
- unsigned index = codeOrigins.size() - 1;
- ASSERT(codeOrigins[index] == codeOrigin);
- return CallSiteIndex(index);
-}
-
-CallSiteIndex CommonData::addUniqueCallSiteIndex(CodeOrigin codeOrigin)
-{
- codeOrigins.append(codeOrigin);
- unsigned index = codeOrigins.size() - 1;
- ASSERT(codeOrigins[index] == codeOrigin);
- return CallSiteIndex(index);
-}
-
-CallSiteIndex CommonData::lastCallSite() const
-{
- RELEASE_ASSERT(codeOrigins.size());
- return CallSiteIndex(codeOrigins.size() - 1);
-}
-
-DisposableCallSiteIndex CommonData::addDisposableCallSiteIndex(CodeOrigin codeOrigin)
-{
- if (callSiteIndexFreeList.size()) {
- unsigned index = callSiteIndexFreeList.takeAny();
- codeOrigins[index] = codeOrigin;
- return DisposableCallSiteIndex(index);
- }
-
- codeOrigins.append(codeOrigin);
- unsigned index = codeOrigins.size() - 1;
- ASSERT(codeOrigins[index] == codeOrigin);
- return DisposableCallSiteIndex(index);
-}
-
-
-void CommonData::removeDisposableCallSiteIndex(DisposableCallSiteIndex callSite)
-{
- RELEASE_ASSERT(callSite.bits() < codeOrigins.size());
- callSiteIndexFreeList.add(callSite.bits());
- codeOrigins[callSite.bits()] = CodeOrigin();
-}
-
void CommonData::shrinkToFit()
{
- codeOrigins.shrinkToFit();
+ codeOrigins->shrinkToFit();
dfgIdentifiers.shrinkToFit();
weakReferences.shrinkToFit();
weakStructureReferences.shrinkToFit();
Modified: trunk/Source/_javascript_Core/dfg/DFGCommonData.h (262919 => 262920)
--- trunk/Source/_javascript_Core/dfg/DFGCommonData.h 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/dfg/DFGCommonData.h 2020-06-11 20:11:34 UTC (rev 262920)
@@ -30,6 +30,7 @@
#include "CodeBlockJettisoningWatchpoint.h"
#include "DFGAdaptiveInferredPropertyValueWatchpoint.h"
#include "DFGAdaptiveStructureWatchpoint.h"
+#include "DFGCodeOriginPool.h"
#include "DFGJumpReplacement.h"
#include "DFGOSREntry.h"
#include "InlineCallFrameSet.h"
@@ -73,20 +74,12 @@
WTF_MAKE_NONCOPYABLE(CommonData);
public:
CommonData()
- : isStillValid(true)
- , frameRegisterCount(std::numeric_limits<unsigned>::max())
- , requiredRegisterCountForExit(std::numeric_limits<unsigned>::max())
+ : codeOrigins(CodeOriginPool::create())
{ }
~CommonData();
void notifyCompilingStructureTransition(Plan&, CodeBlock*, Node*);
- CallSiteIndex addCodeOrigin(CodeOrigin);
- CallSiteIndex addUniqueCallSiteIndex(CodeOrigin);
- CallSiteIndex lastCallSite() const;
- DisposableCallSiteIndex addDisposableCallSiteIndex(CodeOrigin);
- void removeDisposableCallSiteIndex(DisposableCallSiteIndex);
-
void shrinkToFit();
bool invalidate(); // Returns true if we did invalidate, or false if the code block was already invalidated.
@@ -120,7 +113,7 @@
void clearWatchpoints();
RefPtr<InlineCallFrameSet> inlineCallFrames;
- Vector<CodeOrigin, 0, UnsafeVectorOverflow> codeOrigins;
+ Ref<CodeOriginPool> codeOrigins;
Vector<Identifier> dfgIdentifiers;
Vector<WeakReferenceTransition> transitions;
@@ -137,7 +130,7 @@
RefPtr<Profiler::Compilation> compilation;
bool livenessHasBeenProved; // Initialized and used on every GC.
bool allTransitionsHaveBeenMarked; // Initialized and used on every GC.
- bool isStillValid;
+ bool isStillValid { true };
bool hasVMTrapsBreakpointsInstalled { false };
#if USE(JSVALUE32_64)
@@ -144,12 +137,8 @@
std::unique_ptr<Bag<double>> doubleConstants;
#endif
- unsigned frameRegisterCount;
- unsigned requiredRegisterCountForExit;
-
-private:
- HashSet<unsigned, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> callSiteIndexFreeList;
-
+ unsigned frameRegisterCount { std::numeric_limits<unsigned>::max() };
+ unsigned requiredRegisterCountForExit { std::numeric_limits<unsigned>::max() };
};
CodeBlock* codeBlockForVMTrapPC(void* pc);
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (262919 => 262920)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -626,7 +626,7 @@
unsigned streamIndex = m_speculative->m_outOfLineStreamIndex ? *m_speculative->m_outOfLineStreamIndex : m_speculative->m_stream->size();
MacroAssembler::Jump hadException = emitNonPatchableExceptionCheck(vm());
// We assume here that this is called after callOpeartion()/appendCall() is called.
- appendExceptionHandlingOSRExit(ExceptionCheck, streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.lastCallSite(), hadException);
+ appendExceptionHandlingOSRExit(ExceptionCheck, streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.codeOrigins->lastCallSite(), hadException);
} else
m_exceptionChecks.append(emitExceptionCheck(vm()));
}
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (262919 => 262920)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2020-06-11 20:11:34 UTC (rev 262920)
@@ -123,7 +123,7 @@
CallSiteIndex addCallSite(CodeOrigin codeOrigin)
{
- return m_jitCode->common.addCodeOrigin(codeOrigin);
+ return m_jitCode->common.codeOrigins->addCodeOrigin(codeOrigin);
}
CallSiteIndex emitStoreCodeOrigin(CodeOrigin codeOrigin)
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (262919 => 262920)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -4197,7 +4197,7 @@
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
Box<CCallHelpers::JumpList> exceptions =
exceptionHandle->scheduleExitCreation(params)->jumps(jit);
@@ -4810,7 +4810,7 @@
patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
- CallSiteIndex callSiteIndex = state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
// This is the direct exit target for operation calls.
Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit);
@@ -5408,7 +5408,7 @@
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
Box<CCallHelpers::JumpList> exceptions =
exceptionHandle->scheduleExitCreation(params)->jumps(jit);
@@ -9266,7 +9266,7 @@
patchpoint->setGenerator(
[=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
- CallSiteIndex callSiteIndex = state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
+ CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(codeOrigin);
exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
@@ -9386,7 +9386,7 @@
patchpoint->setGenerator(
[=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
- CallSiteIndex callSiteIndex = state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
+ CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(codeOrigin);
GPRReg calleeGPR = params[!isTail].gpr();
@@ -9574,7 +9574,7 @@
patchpoint->setGenerator(
[=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
- CallSiteIndex callSiteIndex = state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
+ CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(codeOrigin);
// Yes, this is really necessary. You could throw an exception in a host call on the
// slow path. That'll route us to operationLookupExceptionHandler(), which unwinds starting
@@ -9718,7 +9718,7 @@
[=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(codeOrigin);
Box<CCallHelpers::JumpList> exceptions =
exceptionHandle->scheduleExitCreation(params)->jumps(jit);
@@ -10020,7 +10020,7 @@
[=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(codeOrigin);
Box<CCallHelpers::JumpList> exceptions =
exceptionHandle->scheduleExitCreation(params)->jumps(jit);
@@ -10274,7 +10274,7 @@
patchpoint->setGenerator(
[=, &vm] (CCallHelpers& jit, const StackmapGenerationParams& params) {
AllowMacroScratchRegisterUsage allowScratch(jit);
- CallSiteIndex callSiteIndex = state->jitCode->common.addUniqueCallSiteIndex(codeOrigin);
+ CallSiteIndex callSiteIndex = state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(codeOrigin);
Box<CCallHelpers::JumpList> exceptions = exceptionHandle->scheduleExitCreation(params)->jumps(jit);
@@ -11773,7 +11773,7 @@
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
// This is the direct exit target for operation calls.
Box<CCallHelpers::JumpList> exceptions =
@@ -12035,7 +12035,7 @@
slowCases.append(jit.branchIfNotCell(prototypeGPR));
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
// This is the direct exit target for operation calls.
Box<CCallHelpers::JumpList> exceptions =
@@ -13109,7 +13109,7 @@
LValue packet = ensureShadowChickenPacket();
LValue thisValue = lowJSValue(m_node->child1());
LValue scope = lowCell(m_node->child2());
- CallSiteIndex callSiteIndex = m_ftlState.jitCode->common.addCodeOrigin(m_node->origin.semantic);
+ CallSiteIndex callSiteIndex = m_ftlState.jitCode->common.codeOrigins->addCodeOrigin(m_node->origin.semantic);
m_out.storePtr(m_callFrame, packet, m_heaps.ShadowChicken_Packet_frame);
m_out.storePtr(m_out.constIntPtr(bitwise_cast<intptr_t>(ShadowChicken::Packet::tailMarker())), packet, m_heaps.ShadowChicken_Packet_callee);
@@ -13524,7 +13524,7 @@
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
// This is the direct exit target for operation calls.
Box<CCallHelpers::JumpList> exceptions =
@@ -13593,7 +13593,7 @@
AllowMacroScratchRegisterUsage allowScratch(jit);
CallSiteIndex callSiteIndex =
- state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
+ state->jitCode->common.codeOrigins->addUniqueCallSiteIndex(node->origin.semantic);
// This is the direct exit target for operation calls.
Box<CCallHelpers::JumpList> exceptions =
@@ -16736,7 +16736,7 @@
CodeLocationLabel<JSInternalPtrTag> linkedDone = linkBuffer.locationOf<JSInternalPtrTag>(done);
CallSiteIndex callSiteIndex =
- jitCode->common.addUniqueCallSiteIndex(origin);
+ jitCode->common.codeOrigins->addUniqueCallSiteIndex(origin);
lazySlowPath->initialize(
linkedPatchableJump, linkedDone,
@@ -18665,7 +18665,7 @@
void callPreflight(CodeOrigin codeOrigin)
{
- CallSiteIndex callSiteIndex = m_ftlState.jitCode->common.addCodeOrigin(codeOrigin);
+ CallSiteIndex callSiteIndex = m_ftlState.jitCode->common.codeOrigins->addCodeOrigin(codeOrigin);
m_out.store32(
m_out.constInt32(callSiteIndex.bits()),
tagFor(VirtualRegister(CallFrameSlot::argumentCountIncludingThis)));
Modified: trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.cpp (262919 => 262920)
--- trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.cpp 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/ftl/FTLSlowPathCall.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -136,7 +136,7 @@
CallSiteIndex callSiteIndexForCodeOrigin(State& state, CodeOrigin codeOrigin)
{
if (codeOrigin)
- return state.jitCode->common.addCodeOrigin(codeOrigin);
+ return state.jitCode->common.codeOrigins->addCodeOrigin(codeOrigin);
return CallSiteIndex();
}
Modified: trunk/Source/_javascript_Core/jit/GCAwareJITStubRoutine.cpp (262919 => 262920)
--- trunk/Source/_javascript_Core/jit/GCAwareJITStubRoutine.cpp 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/jit/GCAwareJITStubRoutine.cpp 2020-06-11 20:11:34 UTC (rev 262920)
@@ -104,6 +104,9 @@
CodeBlock* codeBlockForExceptionHandlers, DisposableCallSiteIndex exceptionHandlerCallSiteIndex)
: MarkingGCAwareJITStubRoutine(code, vm, owner, cells, WTFMove(callLinkInfos))
, m_codeBlockWithExceptionHandler(codeBlockForExceptionHandlers)
+#if ENABLE(DFG_JIT)
+ , m_codeOriginPool(&m_codeBlockWithExceptionHandler->codeOrigins())
+#endif
, m_exceptionHandlerCallSiteIndex(exceptionHandlerCallSiteIndex)
{
RELEASE_ASSERT(m_codeBlockWithExceptionHandler);
@@ -110,9 +113,24 @@
ASSERT(!!m_codeBlockWithExceptionHandler->handlerForIndex(exceptionHandlerCallSiteIndex.bits()));
}
+GCAwareJITStubRoutineWithExceptionHandler::~GCAwareJITStubRoutineWithExceptionHandler()
+{
+#if ENABLE(DFG_JIT)
+ // We delay deallocation of m_exceptionHandlerCallSiteIndex until GCAwareJITStubRoutineWithExceptionHandler gets destroyed.
+ // This means that CallSiteIndex can be reserved correctly so long as the code owned by GCAwareJITStubRoutineWithExceptionHandler is on the stack.
+ // This is important since CallSite can be queried so long as this code is on the stack: StackVisitor can retreive CallSiteIndex from the stack.
+ ASSERT(!isCompilationThread() && !Thread::mayBeGCThread());
+ if (m_codeOriginPool)
+ m_codeOriginPool->removeDisposableCallSiteIndex(m_exceptionHandlerCallSiteIndex);
+#endif
+}
+
void GCAwareJITStubRoutineWithExceptionHandler::aboutToDie()
{
m_codeBlockWithExceptionHandler = nullptr;
+#if ENABLE(DFG_JIT)
+ m_codeOriginPool = nullptr;
+#endif
}
void GCAwareJITStubRoutineWithExceptionHandler::observeZeroRefCount()
@@ -119,7 +137,6 @@
{
#if ENABLE(DFG_JIT)
if (m_codeBlockWithExceptionHandler) {
- m_codeBlockWithExceptionHandler->jitCode()->dfgCommon()->removeDisposableCallSiteIndex(m_exceptionHandlerCallSiteIndex);
m_codeBlockWithExceptionHandler->removeExceptionHandlerForCallSite(m_exceptionHandlerCallSiteIndex);
m_codeBlockWithExceptionHandler = nullptr;
}
Modified: trunk/Source/_javascript_Core/jit/GCAwareJITStubRoutine.h (262919 => 262920)
--- trunk/Source/_javascript_Core/jit/GCAwareJITStubRoutine.h 2020-06-11 19:56:57 UTC (rev 262919)
+++ trunk/Source/_javascript_Core/jit/GCAwareJITStubRoutine.h 2020-06-11 20:11:34 UTC (rev 262920)
@@ -33,6 +33,9 @@
#include <wtf/Vector.h>
namespace JSC {
+namespace DFG {
+class CodeOriginPool;
+}
class CallLinkInfo;
class JITStubRoutineSet;
@@ -102,6 +105,7 @@
typedef GCAwareJITStubRoutine Base;
GCAwareJITStubRoutineWithExceptionHandler(const MacroAssemblerCodeRef<JITStubRoutinePtrTag>&, VM&, const JSCell* owner, const Vector<JSCell*>&, Bag<CallLinkInfo>&&, CodeBlock*, DisposableCallSiteIndex);
+ ~GCAwareJITStubRoutineWithExceptionHandler() final;
void aboutToDie() final;
void observeZeroRefCount() final;
@@ -108,6 +112,9 @@
private:
CodeBlock* m_codeBlockWithExceptionHandler;
+#if ENABLE(DFG_JIT)
+ RefPtr<DFG::CodeOriginPool> m_codeOriginPool;
+#endif
DisposableCallSiteIndex m_exceptionHandlerCallSiteIndex;
};