Commit 6931c476 authored by fpizlo@apple.com's avatar fpizlo@apple.com

Teach DFG::Worklist and its clients that it may be reused for different kinds of compilations

https://bugs.webkit.org/show_bug.cgi?id=120489

Reviewed by Geoffrey Garen.
        
If the baseline JIT hits an OSR entry trigger into the DFG and we already have a
DFG compilation but we've also started one or more FTL compilations, then we
shouldn't get confused. Previously we would have gotten confused because we would
see an in-process deferred compile (the FTL compile) and also an optimized
replacement (the DFG code).
        
If the baseline JIT hits an OSR entry trigger into the DFG and we previously
did two things in this order: triggered a tier-up compilation from the DFG into
the FTL, and then jettisoned the DFG code because it exited a bunch, then we
shouldn't be confused by the presence of an in-process deferred compile (the FTL
compile). Previously we would have waited for that compile to finish; but the more
sensible thing to do is to let it complete and then invalidate it, while at the
same time enqueueing a DFG compile to create a new, more valid, DFG code block.
        
If the DFG JIT hits a loop OSR entry trigger (into the FTL) and it has already
triggered an FTL compile for replacement, then it should fire off a second compile
instead of thinking that it can wait for that one to finish. Or vice-versa. We
need to allow for two FTL compiles to be enqueued at the same time (one for
replacement and one for OSR entry in a loop).
        
Then there's also the problem that DFG::compile() is almost certainly going to be
the hook for triggering both DFG compiles and the two kinds of FTL compiles, but
right now there is no way to tell it which one you want.
        
This fixes these problems and removes a bunch of potential confusion by making the
key for a compile in the DFG::Worklist be a CompilationMode (one of DFGMode,
FTLMode, or FTLForOSREntryMode). That mode is also passed to DFG::compile().
        
Awkwardly, this still leaves us in a no DFG->FTL tier-up situation - so
DFG::compile() is always passed DFGMode and then it might do an FTL compile if
possible. Fixing that is a bigger issue for a later changeset.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::checkIfOptimizationThresholdReached):
* dfg/DFGCompilationKey.cpp: Added.
(JSC::DFG::CompilationKey::dump):
* dfg/DFGCompilationKey.h: Added.
(JSC::DFG::CompilationKey::CompilationKey):
(JSC::DFG::CompilationKey::operator!):
(JSC::DFG::CompilationKey::isHashTableDeletedValue):
(JSC::DFG::CompilationKey::profiledBlock):
(JSC::DFG::CompilationKey::mode):
(JSC::DFG::CompilationKey::operator==):
(JSC::DFG::CompilationKey::hash):
(JSC::DFG::CompilationKeyHash::hash):
(JSC::DFG::CompilationKeyHash::equal):
* dfg/DFGCompilationMode.cpp: Added.
(WTF::printInternal):
* dfg/DFGCompilationMode.h: Added.
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
(JSC::DFG::compile):
* dfg/DFGDriver.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::key):
* dfg/DFGPlan.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::enqueue):
(JSC::DFG::Worklist::compilationState):
(JSC::DFG::Worklist::completeAllReadyPlansForVM):
(JSC::DFG::Worklist::runThread):
* dfg/DFGWorklist.h:
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154854 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 59af0f55
......@@ -96,6 +96,8 @@ set(JavaScriptCore_SOURCES
dfg/DFGClobberize.cpp
dfg/DFGCommon.cpp
dfg/DFGCommonData.cpp
dfg/DFGCompilationKey.cpp
dfg/DFGCompilationMode.cpp
dfg/DFGConstantFoldingPhase.cpp
dfg/DFGCriticalEdgeBreakingPhase.cpp
dfg/DFGDCEPhase.cpp
......
2013-08-29 Filip Pizlo <fpizlo@apple.com>
Teach DFG::Worklist and its clients that it may be reused for different kinds of compilations
https://bugs.webkit.org/show_bug.cgi?id=120489
Reviewed by Geoffrey Garen.
If the baseline JIT hits an OSR entry trigger into the DFG and we already have a
DFG compilation but we've also started one or more FTL compilations, then we
shouldn't get confused. Previously we would have gotten confused because we would
see an in-process deferred compile (the FTL compile) and also an optimized
replacement (the DFG code).
If the baseline JIT hits an OSR entry trigger into the DFG and we previously
did two things in this order: triggered a tier-up compilation from the DFG into
the FTL, and then jettisoned the DFG code because it exited a bunch, then we
shouldn't be confused by the presence of an in-process deferred compile (the FTL
compile). Previously we would have waited for that compile to finish; but the more
sensible thing to do is to let it complete and then invalidate it, while at the
same time enqueueing a DFG compile to create a new, more valid, DFG code block.
If the DFG JIT hits a loop OSR entry trigger (into the FTL) and it has already
triggered an FTL compile for replacement, then it should fire off a second compile
instead of thinking that it can wait for that one to finish. Or vice-versa. We
need to allow for two FTL compiles to be enqueued at the same time (one for
replacement and one for OSR entry in a loop).
Then there's also the problem that DFG::compile() is almost certainly going to be
the hook for triggering both DFG compiles and the two kinds of FTL compiles, but
right now there is no way to tell it which one you want.
This fixes these problems and removes a bunch of potential confusion by making the
key for a compile in the DFG::Worklist be a CompilationMode (one of DFGMode,
FTLMode, or FTLForOSREntryMode). That mode is also passed to DFG::compile().
Awkwardly, this still leaves us in a no DFG->FTL tier-up situation - so
DFG::compile() is always passed DFGMode and then it might do an FTL compile if
possible. Fixing that is a bigger issue for a later changeset.
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::checkIfOptimizationThresholdReached):
* dfg/DFGCompilationKey.cpp: Added.
(JSC::DFG::CompilationKey::dump):
* dfg/DFGCompilationKey.h: Added.
(JSC::DFG::CompilationKey::CompilationKey):
(JSC::DFG::CompilationKey::operator!):
(JSC::DFG::CompilationKey::isHashTableDeletedValue):
(JSC::DFG::CompilationKey::profiledBlock):
(JSC::DFG::CompilationKey::mode):
(JSC::DFG::CompilationKey::operator==):
(JSC::DFG::CompilationKey::hash):
(JSC::DFG::CompilationKeyHash::hash):
(JSC::DFG::CompilationKeyHash::equal):
* dfg/DFGCompilationMode.cpp: Added.
(WTF::printInternal):
* dfg/DFGCompilationMode.h: Added.
* dfg/DFGDriver.cpp:
(JSC::DFG::compileImpl):
(JSC::DFG::compile):
* dfg/DFGDriver.h:
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::Plan):
(JSC::DFG::Plan::key):
* dfg/DFGPlan.h:
* dfg/DFGWorklist.cpp:
(JSC::DFG::Worklist::enqueue):
(JSC::DFG::Worklist::compilationState):
(JSC::DFG::Worklist::completeAllReadyPlansForVM):
(JSC::DFG::Worklist::runThread):
* dfg/DFGWorklist.h:
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
2013-08-29 Brent Fulgham <bfulgham@apple.com>
[Windows] Unreviewed build fix after r154847.
......
......@@ -226,6 +226,10 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGCommon.h \
Source/JavaScriptCore/dfg/DFGCommonData.cpp \
Source/JavaScriptCore/dfg/DFGCommonData.h \
Source/JavaScriptCore/dfg/DFGCompilationKey.cpp \
Source/JavaScriptCore/dfg/DFGCompilationKey.h \
Source/JavaScriptCore/dfg/DFGCompilationMode.cpp \
Source/JavaScriptCore/dfg/DFGCompilationMode.h \
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp \
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.h \
Source/JavaScriptCore/dfg/DFGCriticalEdgeBreakingPhase.cpp \
......
......@@ -325,6 +325,9 @@
<ClCompile Include="..\debugger\Debugger.cpp" />
<ClCompile Include="..\debugger\DebuggerActivation.cpp" />
<ClCompile Include="..\debugger\DebuggerCallFrame.cpp" />
<ClCompile Include="..\dfg\DFGCompilationKey.cpp" />
<ClCompile Include="..\dfg\DFGCompilationMode.cpp" />
<ClCompile Include="..\dfg\DFGDriver.cpp" />
<ClCompile Include="..\disassembler\Disassembler.cpp" />
<ClCompile Include="..\heap\BlockAllocator.cpp" />
<ClCompile Include="..\heap\ConservativeRoots.cpp" />
......@@ -663,6 +666,8 @@
<ClInclude Include="..\debugger\Debugger.h" />
<ClInclude Include="..\debugger\DebuggerActivation.h" />
<ClInclude Include="..\debugger\DebuggerCallFrame.h" />
<ClInclude Include="..\dfg\DFGCompilationKey.h" />
<ClInclude Include="..\dfg\DFGCompilationMode.h" />
<ClInclude Include="..\dfg\DFGDriver.h" />
<ClInclude Include="..\dfg\DFGOSREntry.h" />
<ClInclude Include="..\disassembler\Disassembler.h" />
......
......@@ -189,6 +189,10 @@
0F34B14C16D43E0D001CDA5A /* PolymorphicAccessStructureList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };
0F38B01217CF078300B144D3 /* LLIntEntrypoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F38B01717CFE75500B144D3 /* DFGCompilationKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */; };
0F38B01817CFE75500B144D3 /* DFGCompilationKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01417CFE75500B144D3 /* DFGCompilationKey.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F38B01917CFE75500B144D3 /* DFGCompilationMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */; };
0F38B01A17CFE75500B144D3 /* DFGCompilationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F3B3A1A153E68F2003ED0FF /* DFGConstantFoldingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */; };
0F3B3A1B153E68F4003ED0FF /* DFGConstantFoldingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F3B3A271544C995003ED0FF /* DFGCFGSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */; };
......@@ -1345,6 +1349,10 @@
0F34B14B16D43E0C001CDA5A /* PolymorphicAccessStructureList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolymorphicAccessStructureList.h; sourceTree = "<group>"; };
0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = "<group>"; };
0F38B01017CF077F00B144D3 /* LLIntEntrypoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLIntEntrypoint.h; path = llint/LLIntEntrypoint.h; sourceTree = "<group>"; };
0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCompilationKey.cpp; path = dfg/DFGCompilationKey.cpp; sourceTree = "<group>"; };
0F38B01417CFE75500B144D3 /* DFGCompilationKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCompilationKey.h; path = dfg/DFGCompilationKey.h; sourceTree = "<group>"; };
0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCompilationMode.cpp; path = dfg/DFGCompilationMode.cpp; sourceTree = "<group>"; };
0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCompilationMode.h; path = dfg/DFGCompilationMode.h; sourceTree = "<group>"; };
0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGConstantFoldingPhase.cpp; path = dfg/DFGConstantFoldingPhase.cpp; sourceTree = "<group>"; };
0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGConstantFoldingPhase.h; path = dfg/DFGConstantFoldingPhase.h; sourceTree = "<group>"; };
0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCFGSimplificationPhase.cpp; path = dfg/DFGCFGSimplificationPhase.cpp; sourceTree = "<group>"; };
......@@ -3336,6 +3344,10 @@
86EC9DB31328DF44002B2AD7 /* dfg */ = {
isa = PBXGroup;
children = (
0F38B01317CFE75500B144D3 /* DFGCompilationKey.cpp */,
0F38B01417CFE75500B144D3 /* DFGCompilationKey.h */,
0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */,
0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */,
A77A423617A0BBFD00A8DB81 /* DFGAbstractHeap.cpp */,
A77A423717A0BBFD00A8DB81 /* DFGAbstractHeap.h */,
A704D8FE17A0BAA8006BA554 /* DFGAbstractInterpreter.h */,
......@@ -4076,6 +4088,7 @@
978801411471AD920041B016 /* JSDateMath.h in Headers */,
C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */,
86E3C614167BABD7006D760A /* JSExport.h in Headers */,
0F38B01A17CFE75500B144D3 /* DFGCompilationMode.h in Headers */,
A7B4ACAF1484C9CE00B38A36 /* JSExportMacros.h in Headers */,
0F2B66EF17B6B5AB00A7AE3F /* JSFloat32Array.h in Headers */,
0F2B66F017B6B5AB00A7AE3F /* JSFloat64Array.h in Headers */,
......@@ -4233,6 +4246,7 @@
0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */,
0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */,
0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */,
0F38B01817CFE75500B144D3 /* DFGCompilationKey.h in Headers */,
0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */,
0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */,
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */,
......@@ -4725,6 +4739,7 @@
A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */,
0F38B01917CFE75500B144D3 /* DFGCompilationMode.cpp in Sources */,
86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
......@@ -4774,6 +4789,7 @@
C2C0F7CD17BBFC5B00464FE4 /* DFGDesiredTransitions.cpp in Sources */,
0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */,
C2981FD817BAEE4B00A3BC98 /* DFGDesiredWeakReferences.cpp in Sources */,
0F38B01717CFE75500B144D3 /* DFGCompilationKey.cpp in Sources */,
C2981FDC17BAFF4400A3BC98 /* DFGDesiredWriteBarriers.cpp in Sources */,
0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */,
7C3BA29817C039560072DDC9 /* JSPromiseResolverPrototype.cpp in Sources */,
......
......@@ -129,6 +129,8 @@ SOURCES += \
dfg/DFGClobberSet.cpp \
dfg/DFGCommon.cpp \
dfg/DFGCommonData.cpp \
dfg/DFGCompilationKey.cpp \
dfg/DFGCompilationMode.cpp \
dfg/DFGCFAPhase.cpp \
dfg/DFGCFGSimplificationPhase.cpp \
dfg/DFGCPSRethreadingPhase.cpp \
......
......@@ -2973,10 +2973,12 @@ int32_t CodeBlock::adjustedCounterValue(int32_t desiredThreshold)
bool CodeBlock::checkIfOptimizationThresholdReached()
{
#if ENABLE(DFG_JIT)
if (m_vm->worklist
&& m_vm->worklist->compilationState(this) == DFG::Worklist::Compiled) {
optimizeNextInvocation();
return true;
if (DFG::Worklist* worklist = m_vm->worklist.get()) {
if (worklist->compilationState(DFG::CompilationKey(this, DFG::DFGMode))
== DFG::Worklist::Compiled) {
optimizeNextInvocation();
return true;
}
}
#endif
......
/*
* Copyright (C) 2013 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 "DFGCompilationKey.h"
#include "CodeBlock.h"
namespace JSC { namespace DFG {
void CompilationKey::dump(PrintStream& out) const
{
if (!*this) {
out.print("<empty>");
return;
}
out.print("(Compile of ", *m_profiledBlock, " with ", m_mode, ")");
}
} } // namespace JSC::DFG
/*
* Copyright (C) 2013 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.
*/
#ifndef DFGCompilationKey_h
#define DFGCompilationKey_h
#include "DFGCompilationMode.h"
#include <wtf/HashMap.h>
namespace JSC {
class CodeBlock;
namespace DFG {
class CompilationKey {
public:
CompilationKey()
: m_profiledBlock(0)
, m_mode(InvalidCompilationMode)
{
}
CompilationKey(WTF::HashTableDeletedValueType)
: m_profiledBlock(0)
, m_mode(DFGMode)
{
}
CompilationKey(CodeBlock* profiledBlock, CompilationMode mode)
: m_profiledBlock(profiledBlock)
, m_mode(mode)
{
}
bool operator!() const
{
return !m_profiledBlock && m_mode == InvalidCompilationMode;
}
bool isHashTableDeletedValue() const
{
return !m_profiledBlock && m_mode != InvalidCompilationMode;
}
CodeBlock* profiledBlock() const { return m_profiledBlock; }
CompilationMode mode() const { return m_mode; }
bool operator==(const CompilationKey& other) const
{
return m_profiledBlock == other.m_profiledBlock
&& m_mode == other.m_mode;
}
unsigned hash() const
{
return WTF::pairIntHash(WTF::PtrHash<CodeBlock*>::hash(m_profiledBlock), m_mode);
}
void dump(PrintStream&) const;
private:
CodeBlock* m_profiledBlock;
CompilationMode m_mode;
};
struct CompilationKeyHash {
static unsigned hash(const CompilationKey& key) { return key.hash(); }
static bool equal(const CompilationKey& a, const CompilationKey& b) { return a == b; }
static const bool safeToCompareToEmptyOrDeleted = true;
};
} } // namespace JSC::DFG
namespace WTF {
template<typename T> struct DefaultHash;
template<> struct DefaultHash<JSC::DFG::CompilationKey> {
typedef JSC::DFG::CompilationKeyHash Hash;
};
template<typename T> struct HashTraits;
template<> struct HashTraits<JSC::DFG::CompilationKey> : SimpleClassHashTraits<JSC::DFG::CompilationKey> { };
} // namespace WTF
#endif // DFGCompilationKey_h
/*
* Copyright (C) 2013 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 "DFGCompilationMode.h"
namespace WTF {
using namespace JSC::DFG;
void printInternal(PrintStream& out, CompilationMode mode)
{
switch (mode) {
case InvalidCompilationMode:
out.print("InvalidCompilationMode");
return;
case DFGMode:
out.print("DFGMode");
return;
case FTLMode:
out.print("FTLMode");
return;
case FTLForOSREntryMode:
out.print("FTLForOSREntryMode");
return;
}
RELEASE_ASSERT_NOT_REACHED();
}
} // namespace WTF
/*
* Copyright (C) 2013 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.
*/
#ifndef DFGCompilationMode_h
#define DFGCompilationMode_h
#include <wtf/PrintStream.h>
namespace JSC { namespace DFG {
enum CompilationMode {
InvalidCompilationMode,
DFGMode,
FTLMode,
FTLForOSREntryMode
};
} } // namespace JSC::DFG
namespace WTF {
void printInternal(PrintStream&, JSC::DFG::CompilationMode);
} // namespace WTF
#endif // DFGCompilationMode_h
......@@ -54,7 +54,10 @@ unsigned getNumCompilations()
}
#if ENABLE(DFG_JIT)
static CompilationResult compileImpl(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback, Worklist* worklist)
static CompilationResult compileImpl(
ExecState* exec, CodeBlock* codeBlock, CompilationMode mode,
unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> callback,
Worklist* worklist)
{
SamplingRegion samplingRegion("DFG Compilation (Driver)");
......@@ -98,7 +101,7 @@ static CompilationResult compileImpl(ExecState* exec, CodeBlock* codeBlock, unsi
else
numVarsWithValues = 0;
RefPtr<Plan> plan = adoptRef(
new Plan(codeBlock, osrEntryBytecodeIndex, numVarsWithValues));
new Plan(codeBlock, mode, osrEntryBytecodeIndex, numVarsWithValues));
for (size_t i = 0; i < plan->mustHandleValues.size(); ++i) {
int operand = plan->mustHandleValues.operandForIndex(i);
if (operandIsArgument(operand)
......@@ -126,16 +129,22 @@ static CompilationResult compileImpl(ExecState* exec, CodeBlock* codeBlock, unsi
return plan->finalizeWithoutNotifyingCallback();
}
#else // ENABLE(DFG_JIT)
static CompilationResult compileImpl(ExecState*, CodeBlock*, unsigned, PassRefPtr<DeferredCompilationCallback>, Worklist*)
static CompilationResult compileImpl(
ExecState*, CodeBlock*, CompilationMode, unsigned,
PassRefPtr<DeferredCompilationCallback>, Worklist*)
{
return CompilationFailed;
}
#endif // ENABLE(DFG_JIT)
CompilationResult compile(ExecState* exec, CodeBlock* codeBlock, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> passedCallback, Worklist* worklist)
CompilationResult compile(
ExecState* exec, CodeBlock* codeBlock, CompilationMode mode,
unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback> passedCallback,
Worklist* worklist)
{
RefPtr<DeferredCompilationCallback> callback = passedCallback;
CompilationResult result = compileImpl(exec, codeBlock, osrEntryBytecodeIndex, callback, worklist);
CompilationResult result = compileImpl(
exec, codeBlock, mode, osrEntryBytecodeIndex, callback, worklist);
if (result != CompilationDeferred)
callback->compilationDidComplete(codeBlock, result);
return result;
......
......@@ -27,6 +27,7 @@
#define DFGDriver_h
#include "CallFrame.h"
#include "DFGCompilationMode.h"
#include "DFGPlan.h"
#include <wtf/Platform.h>
......@@ -45,7 +46,7 @@ JS_EXPORT_PRIVATE unsigned getNumCompilations();
// If the worklist is non-null, we do a concurrent compile. Otherwise we do a synchronous
// compile. Even if we do a synchronous compile, we call the callback with the result.
CompilationResult compile(ExecState*, CodeBlock*, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>, Worklist*);
CompilationResult compile(ExecState*, CodeBlock*, CompilationMode, unsigned osrEntryBytecodeIndex, PassRefPtr<DeferredCompilationCallback>, Worklist*);
} } // namespace JSC::DFG
......
......@@ -80,10 +80,11 @@ static void dumpAndVerifyGraph(Graph& graph, const char* text)
}
Plan::Plan(
PassRefPtr<CodeBlock> passedCodeBlock, unsigned osrEntryBytecodeIndex,
unsigned numVarsWithValues)
PassRefPtr<CodeBlock> passedCodeBlock, CompilationMode mode,
unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues)
: vm(*passedCodeBlock->vm())
, codeBlock(passedCodeBlock)
, mode(mode)
, osrEntryBytecodeIndex(osrEntryBytecodeIndex)
, numVarsWithValues(numVarsWithValues)
, mustHandleValues(codeBlock->numParameters(), numVarsWithValues)
......@@ -310,9 +311,9 @@ void Plan::finalizeAndNotifyCallback()
callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback());
}
CodeBlock* Plan::key()
CompilationKey Plan::key()
{
return codeBlock->alternative();
return CompilationKey(codeBlock->alternative(), mode);
}
} } // namespace JSC::DFG
......
......@@ -29,6 +29,8 @@
#include <wtf/Platform.h>
#include "CompilationResult.h"
#include "DFGCompilationKey.h"
#include "DFGCompilationMode.h"
#include "DFGDesiredIdentifiers.h"
#include "DFGDesiredStructureChains.h"
#include "DFGDesiredTransitions.h"
......@@ -53,7 +55,8 @@ class LongLivedState;
struct Plan : public ThreadSafeRefCounted<Plan> {
Plan(
PassRefPtr<CodeBlock>, unsigned osrEntryBytecodeIndex, unsigned numVarsWithValues);
PassRefPtr<CodeBlock>, CompilationMode, unsigned osrEntryBytecodeIndex,
unsigned numVarsWithValues);
~Plan();
void compileInThread(LongLivedState&);
......@@ -63,10 +66,11 @@ struct Plan : public ThreadSafeRefCounted<Plan> {
void notifyReady();
CodeBlock* key();
CompilationKey key();
VM& vm;
RefPtr<CodeBlock> codeBlock;
CompilationMode mode;
const unsigned osrEntryBytecodeIndex;
const unsigned numVarsWithValues;
Operands<JSValue> mustHandleValues;
......
......@@ -72,7 +72,7 @@ void Worklist::enqueue(PassRefPtr<Plan> passedPlan)
MutexLocker locker(m_lock);
if (Options::verboseCompilationQueue()) {
dump(locker, WTF::dataFile());
dataLog(": Enqueueing plan to optimize ", *plan->key(), "\n");
dataLog(": Enqueueing plan to optimize ", plan->key(), "\n");
}
ASSERT(m_plans.find(plan->key()) == m_plans.end());
m_plans.add(plan->key(), plan);
......@@ -80,10 +80,10 @@ void Worklist::enqueue(PassRefPtr<Plan> passedPlan)
m_planEnqueued.signal();
}
Worklist::State Worklist::compilationState(CodeBlock* profiledBlock)
Worklist::State Worklist::compilationState(CompilationKey key)
{
MutexLocker locker(m_lock);
PlanMap::iterator iter = m_plans.find(profiledBlock);
PlanMap::iterator iter = m_plans.find(key);
if (iter == m_plans.end())
return NotKnown;
return iter->value->isCompiled ? Compiled : Compiling;
......@@ -147,7 +147,7 @@ void Worklist::removeAllReadyPlansForVM(VM& vm)
removeAllReadyPlansForVM(vm, myReadyPlans);
}
Worklist::State Worklist::completeAllReadyPlansForVM(VM& vm, CodeBlock* requestedProfiledBlock)
Worklist::State Worklist::completeAllReadyPlansForVM(VM& vm, CompilationKey requestedKey)
{
DeferGC deferGC(vm.heap);
Vector<RefPtr<Plan>, 8> myReadyPlans;
......@@ -158,22 +158,22 @@ Worklist::State Worklist::completeAllReadyPlansForVM(VM& vm, CodeBlock* requeste
while (!myReadyPlans.isEmpty()) {
RefPtr<Plan> plan = myReadyPlans.takeLast();
CodeBlock* profiledBlock = plan->key();
CompilationKey currentKey = plan->key();
if (Options::verboseCompilationQueue())
dataLog(*this, ": Completing ", *profiledBlock, "\n");
dataLog(*this, ": Completing ", currentKey, "\n");
RELEASE_ASSERT(plan->isCompiled);
plan->finalizeAndNotifyCallback();
if (profiledBlock == requestedProfiledBlock)
if (currentKey == requestedKey)
resultingState = Compiled;
}
if (requestedProfiledBlock && resultingState == NotKnown) {
if (!!requestedKey && resultingState == NotKnown) {
MutexLocker locker(m_lock);
if (m_plans.contains(requestedProfiledBlock))
if (m_plans.contains(requestedKey))
resultingState = Compiling;
}
......@@ -234,7 +234,7 @@ void Worklist::runThread()
}
if (Options::verboseCompilationQueue())