Commit 4621171a authored by fpizlo@apple.com's avatar fpizlo@apple.com

DFG OSR exit code should be lazily generated

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

Reviewed by Gavin Barraclough.
        
The OSR exit code is now generated the first time it is executed,
rather than right after speculative compilation. Because most OSR
exits are never taken, this should greatly reduce both code size
and compilation time.
        
This is a 1% win on SunSpider, and a 1% win on V8 when running in
my harness. No change in V8 in V8's harness (due to the long runs,
so compile time is not an issue) and no change in Kraken (again,
long runs of small code so compile time has no measurable effect).

* CMakeListsEfl.txt:
* GNUmakefile.list.am:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* assembler/AbstractMacroAssembler.h:
* assembler/MacroAssemblerX86.h:
(JSC::MacroAssemblerX86::jump):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::jump):
* assembler/X86Assembler.h:
(JSC::X86Assembler::jmp_m):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::createDFGDataIfNecessary):
(JSC::CodeBlock::appendDFGOSREntryData):
(JSC::CodeBlock::numberOfDFGOSREntries):
(JSC::CodeBlock::dfgOSREntryData):
(JSC::CodeBlock::dfgOSREntryDataForBytecodeIndex):
(JSC::CodeBlock::appendOSRExit):
(JSC::CodeBlock::appendSpeculationRecovery):
(JSC::CodeBlock::numberOfOSRExits):
(JSC::CodeBlock::numberOfSpeculationRecoveries):
(JSC::CodeBlock::osrExit):
(JSC::CodeBlock::speculationRecovery):
* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::debugCall):
* dfg/DFGCorrectableJumpPoint.cpp: Added.
(JSC::DFG::CorrectableJumpPoint::codeLocationForRepatch):
* dfg/DFGCorrectableJumpPoint.h: Added.
(JSC::DFG::CorrectableJumpPoint::CorrectableJumpPoint):
(JSC::DFG::CorrectableJumpPoint::switchToLateJump):
(JSC::DFG::CorrectableJumpPoint::correctInitialJump):
(JSC::DFG::CorrectableJumpPoint::correctLateJump):
(JSC::DFG::CorrectableJumpPoint::initialJump):
(JSC::DFG::CorrectableJumpPoint::lateJump):
(JSC::DFG::CorrectableJumpPoint::correctJump):
(JSC::DFG::CorrectableJumpPoint::getJump):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
* dfg/DFGOSRExit.cpp: Added.
(JSC::DFG::OSRExit::OSRExit):
(JSC::DFG::OSRExit::dump):
* dfg/DFGOSRExit.h:
* dfg/DFGOSRExitCompiler.cpp: Added.
* dfg/DFGOSRExitCompiler.h:
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::speculationCheck):
* dfg/DFGThunks.cpp: Added.
(JSC::DFG::osrExitGenerationThunkGenerator):
* dfg/DFGThunks.h: Added.
* jit/JITCode.h:
(JSC::JITCode::dataAddressAtOffset):
* runtime/JSGlobalData.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@99787 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 837482d8
......@@ -26,6 +26,7 @@ LIST(APPEND JavaScriptCore_SOURCES
dfg/DFGAssemblyHelpers.cpp
dfg/DFGByteCodeParser.cpp
dfg/DFGCapabilities.cpp
dfg/DFGCorrectableJumpPoint.cpp
dfg/DFGDriver.cpp
dfg/DFGGraph.cpp
dfg/DFGJITCodeGenerator.cpp
......@@ -34,6 +35,8 @@ LIST(APPEND JavaScriptCore_SOURCES
dfg/DFGJITCompiler.cpp
dfg/DFGOperations.cpp
dfg/DFGOSREntry.cpp
dfg/DFGOSRExit.cpp
dfg/DFGOSRExitCompiler.cpp
dfg/DFGOSRExitCompiler64.cpp
dfg/DFGOSRExitCompiler32_64.cpp
dfg/DFGPropagator.cpp
......@@ -41,4 +44,5 @@ LIST(APPEND JavaScriptCore_SOURCES
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT64.cpp
dfg/DFGSpeculativeJIT32_64.cpp
dfg/DFGThunks.cpp
)
2011-11-09 Filip Pizlo <fpizlo@apple.com>
DFG OSR exit code should be lazily generated
https://bugs.webkit.org/show_bug.cgi?id=71744
Reviewed by Gavin Barraclough.
The OSR exit code is now generated the first time it is executed,
rather than right after speculative compilation. Because most OSR
exits are never taken, this should greatly reduce both code size
and compilation time.
This is a 1% win on SunSpider, and a 1% win on V8 when running in
my harness. No change in V8 in V8's harness (due to the long runs,
so compile time is not an issue) and no change in Kraken (again,
long runs of small code so compile time has no measurable effect).
* CMakeListsEfl.txt:
* GNUmakefile.list.am:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* assembler/AbstractMacroAssembler.h:
* assembler/MacroAssemblerX86.h:
(JSC::MacroAssemblerX86::jump):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::jump):
* assembler/X86Assembler.h:
(JSC::X86Assembler::jmp_m):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::createDFGDataIfNecessary):
(JSC::CodeBlock::appendDFGOSREntryData):
(JSC::CodeBlock::numberOfDFGOSREntries):
(JSC::CodeBlock::dfgOSREntryData):
(JSC::CodeBlock::dfgOSREntryDataForBytecodeIndex):
(JSC::CodeBlock::appendOSRExit):
(JSC::CodeBlock::appendSpeculationRecovery):
(JSC::CodeBlock::numberOfOSRExits):
(JSC::CodeBlock::numberOfSpeculationRecoveries):
(JSC::CodeBlock::osrExit):
(JSC::CodeBlock::speculationRecovery):
* dfg/DFGAssemblyHelpers.h:
(JSC::DFG::AssemblyHelpers::debugCall):
* dfg/DFGCorrectableJumpPoint.cpp: Added.
(JSC::DFG::CorrectableJumpPoint::codeLocationForRepatch):
* dfg/DFGCorrectableJumpPoint.h: Added.
(JSC::DFG::CorrectableJumpPoint::CorrectableJumpPoint):
(JSC::DFG::CorrectableJumpPoint::switchToLateJump):
(JSC::DFG::CorrectableJumpPoint::correctInitialJump):
(JSC::DFG::CorrectableJumpPoint::correctLateJump):
(JSC::DFG::CorrectableJumpPoint::initialJump):
(JSC::DFG::CorrectableJumpPoint::lateJump):
(JSC::DFG::CorrectableJumpPoint::correctJump):
(JSC::DFG::CorrectableJumpPoint::getJump):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::linkOSRExits):
(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::link):
* dfg/DFGJITCompiler.h:
* dfg/DFGOSRExit.cpp: Added.
(JSC::DFG::OSRExit::OSRExit):
(JSC::DFG::OSRExit::dump):
* dfg/DFGOSRExit.h:
* dfg/DFGOSRExitCompiler.cpp: Added.
* dfg/DFGOSRExitCompiler.h:
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::speculationCheck):
* dfg/DFGThunks.cpp: Added.
(JSC::DFG::osrExitGenerationThunkGenerator):
* dfg/DFGThunks.h: Added.
* jit/JITCode.h:
(JSC::JITCode::dataAddressAtOffset):
* runtime/JSGlobalData.h:
2011-11-09 Mark Hahnenberg <mhahnenberg@apple.com>
Fixing build breakage
......@@ -115,6 +115,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGByteCodeParser.h \
Source/JavaScriptCore/dfg/DFGCapabilities.cpp \
Source/JavaScriptCore/dfg/DFGCapabilities.h \
Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.cpp \
Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h \
Source/JavaScriptCore/dfg/DFGDriver.cpp \
Source/JavaScriptCore/dfg/DFGDriver.h \
Source/JavaScriptCore/dfg/DFGFPRInfo.h \
......@@ -138,8 +140,10 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGOSREntry.h \
Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp \
Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp \
Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp \
Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h \
Source/JavaScriptCore/dfg/DFGOSRExit.h \
Source/JavaScriptCore/dfg/DFGOSRExit.cpp \
Source/JavaScriptCore/dfg/DFGPropagator.cpp \
Source/JavaScriptCore/dfg/DFGPropagator.h \
Source/JavaScriptCore/dfg/DFGRegisterBank.h \
......@@ -151,6 +155,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp \
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \
Source/JavaScriptCore/dfg/DFGStructureSet.h \
Source/JavaScriptCore/dfg/DFGThunks.cpp \
Source/JavaScriptCore/dfg/DFGThunks.h \
Source/JavaScriptCore/dfg/DFGVariableAccessData.h \
Source/JavaScriptCore/heap/AllocationSpace.cpp \
Source/JavaScriptCore/heap/AllocationSpace.h \
......
......@@ -74,6 +74,12 @@
0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */; };
0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC09775146943AD00CF2442 /* DFGOSRExitCompiler32_64.cpp */; };
0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */; };
0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */; };
0FC0979C146A772500CF2442 /* DFGCorrectableJumpPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0979E146B272100CF2442 /* DFGCorrectableJumpPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */; };
0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */; };
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150A14043BF500CFA603 /* WriteBarrierSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC8150B14043C0E00CFA603 /* WriteBarrierSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */; };
0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC815141405118D00CFA603 /* VTableSpectrum.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -845,6 +851,12 @@
0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler64.cpp; path = dfg/DFGOSRExitCompiler64.cpp; sourceTree = "<group>"; };
0FC09775146943AD00CF2442 /* DFGOSRExitCompiler32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler32_64.cpp; path = dfg/DFGOSRExitCompiler32_64.cpp; sourceTree = "<group>"; };
0FC0977E1469EBC400CF2442 /* DFGCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCommon.h; path = dfg/DFGCommon.h; sourceTree = "<group>"; };
0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExit.cpp; path = dfg/DFGOSRExit.cpp; sourceTree = "<group>"; };
0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler.cpp; path = dfg/DFGOSRExitCompiler.cpp; sourceTree = "<group>"; };
0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCorrectableJumpPoint.h; path = dfg/DFGCorrectableJumpPoint.h; sourceTree = "<group>"; };
0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCorrectableJumpPoint.cpp; path = dfg/DFGCorrectableJumpPoint.cpp; sourceTree = "<group>"; };
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGThunks.cpp; path = dfg/DFGThunks.cpp; sourceTree = "<group>"; };
0FC097A0146B28C700CF2442 /* DFGThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGThunks.h; path = dfg/DFGThunks.h; sourceTree = "<group>"; };
0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; };
0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; };
0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; };
......@@ -2305,6 +2317,12 @@
86EC9DB31328DF44002B2AD7 /* dfg */ = {
isa = PBXGroup;
children = (
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
0FC097A0146B28C700CF2442 /* DFGThunks.h */,
0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */,
0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */,
0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */,
0FC0978F146A6F6300CF2442 /* DFGOSRExitCompiler.cpp */,
0FC09775146943AD00CF2442 /* DFGOSRExitCompiler32_64.cpp */,
0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */,
0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */,
......@@ -2923,6 +2941,8 @@
0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
0FC0976D1468AB4E00CF2442 /* DFGAssemblyHelpers.h in Headers */,
0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */,
0FC0979C146A772500CF2442 /* DFGCorrectableJumpPoint.h in Headers */,
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -3456,6 +3476,10 @@
0FC0976E1468AB5100CF2442 /* DFGAssemblyHelpers.cpp in Sources */,
0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
0FC0979E146B272100CF2442 /* DFGCorrectableJumpPoint.cpp in Sources */,
0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -86,6 +86,7 @@ SOURCES += \
dfg/DFGAssemblyHelpers.cpp \
dfg/DFGByteCodeParser.cpp \
dfg/DFGCapabilities.cpp \
dfg/DFGCorrectableJumpPoint.cpp \
dfg/DFGDriver.cpp \
dfg/DFGGraph.cpp \
dfg/DFGJITCodeGenerator.cpp \
......@@ -94,6 +95,8 @@ SOURCES += \
dfg/DFGJITCompiler.cpp \
dfg/DFGOperations.cpp \
dfg/DFGOSREntry.cpp \
dfg/DFGOSRExit.cpp \
dfg/DFGOSRExitCompiler.cpp \
dfg/DFGOSRExitCompiler64.cpp \
dfg/DFGOSRExitCompiler32_64.cpp \
dfg/DFGPropagator.cpp \
......@@ -101,6 +104,7 @@ SOURCES += \
dfg/DFGSpeculativeJIT.cpp \
dfg/DFGSpeculativeJIT32_64.cpp \
dfg/DFGSpeculativeJIT64.cpp \
dfg/DFGThunks.cpp \
interpreter/CallFrame.cpp \
interpreter/Interpreter.cpp \
interpreter/RegisterFile.cpp \
......
......@@ -37,6 +37,9 @@ namespace JSC {
class LinkBuffer;
class RepatchBuffer;
namespace DFG {
class CorrectableJumpPoint;
}
template <class AssemblerType>
class AbstractMacroAssembler {
......@@ -257,6 +260,7 @@ public:
class Label {
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
friend class DFG::CorrectableJumpPoint;
friend class Jump;
friend class MacroAssemblerCodeRef;
friend class LinkBuffer;
......@@ -405,6 +409,7 @@ public:
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
friend class Call;
friend class DFG::CorrectableJumpPoint;
friend class LinkBuffer;
public:
Jump()
......
......@@ -1031,6 +1031,13 @@ public:
load32(address, dataTempRegister);
m_assembler.bx(dataTempRegister);
}
void jump(AbsoluteAddress address)
{
move(TrusteddImmPtr(address.m_ptr), dataTempRegister);
load32(Address(dataTempRegister), dataTempRegister);
m_assembler.bx(dataTempRegister);
}
// Arithmetic control flow operations:
......
......@@ -46,6 +46,7 @@ public:
using MacroAssemblerX86Common::store32;
using MacroAssemblerX86Common::branch32;
using MacroAssemblerX86Common::call;
using MacroAssemblerX86Common::jump;
using MacroAssemblerX86Common::addDouble;
using MacroAssemblerX86Common::loadDouble;
using MacroAssemblerX86Common::storeDouble;
......@@ -155,6 +156,12 @@ public:
return Call(m_assembler.call(), Call::Linkable);
}
// Address is a memory location containing the address to jump to
void jump(AbsoluteAddress address)
{
m_assembler.jmp_m(address.m_ptr);
}
Call tailRecursiveCall()
{
return Call::fromTailJump(jump());
......
......@@ -49,6 +49,7 @@ public:
using MacroAssemblerX86Common::load32;
using MacroAssemblerX86Common::store32;
using MacroAssemblerX86Common::call;
using MacroAssemblerX86Common::jump;
using MacroAssemblerX86Common::addDouble;
using MacroAssemblerX86Common::loadDouble;
using MacroAssemblerX86Common::convertInt32ToDouble;
......@@ -127,6 +128,13 @@ public:
return result;
}
// Address is a memory location containing the address to jump to
void jump(AbsoluteAddress address)
{
move(TrustedImmPtr(address.m_ptr), scratchRegister);
jump(Address(scratchRegister));
}
Call tailRecursiveCall()
{
DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister);
......
......@@ -1280,6 +1280,13 @@ public:
{
m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
}
#if !CPU(X86_64)
void jmp_m(const void* address)
{
m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, address);
}
#endif
AssemblerLabel jne()
{
......
......@@ -33,6 +33,7 @@
#include "CodeOrigin.h"
#include "CompactJITCodeMap.h"
#include "DFGOSREntry.h"
#include "DFGOSRExit.h"
#include "EvalCodeCache.h"
#include "Heuristics.h"
#include "Instruction.h"
......@@ -361,19 +362,69 @@ namespace JSC {
return m_jitCodeMap.get();
}
void createDFGDataIfNecessary()
{
if (!!m_dfgData)
return;
m_dfgData = adoptPtr(new DFGData);
}
DFG::OSREntryData* appendDFGOSREntryData(unsigned bytecodeIndex, unsigned machineCodeOffset)
{
createDFGDataIfNecessary();
DFG::OSREntryData entry;
entry.m_bytecodeIndex = bytecodeIndex;
entry.m_machineCodeOffset = machineCodeOffset;
m_dfgOSREntry.append(entry);
return &m_dfgOSREntry.last();
m_dfgData->osrEntry.append(entry);
return &m_dfgData->osrEntry.last();
}
unsigned numberOfDFGOSREntries() const { return m_dfgOSREntry.size(); }
DFG::OSREntryData* dfgOSREntryData(unsigned i) { return &m_dfgOSREntry[i]; }
unsigned numberOfDFGOSREntries() const
{
if (!m_dfgData)
return 0;
return m_dfgData->osrEntry.size();
}
DFG::OSREntryData* dfgOSREntryData(unsigned i) { return &m_dfgData->osrEntry[i]; }
DFG::OSREntryData* dfgOSREntryDataForBytecodeIndex(unsigned bytecodeIndex)
{
return binarySearch<DFG::OSREntryData, unsigned, DFG::getOSREntryDataBytecodeIndex>(m_dfgOSREntry.begin(), m_dfgOSREntry.size(), bytecodeIndex);
return binarySearch<DFG::OSREntryData, unsigned, DFG::getOSREntryDataBytecodeIndex>(m_dfgData->osrEntry.begin(), m_dfgData->osrEntry.size(), bytecodeIndex);
}
void appendOSRExit(const DFG::OSRExit& osrExit)
{
createDFGDataIfNecessary();
m_dfgData->osrExit.append(osrExit);
}
void appendSpeculationRecovery(const DFG::SpeculationRecovery& recovery)
{
createDFGDataIfNecessary();
m_dfgData->speculationRecovery.append(recovery);
}
unsigned numberOfOSRExits()
{
if (!m_dfgData)
return 0;
return m_dfgData->osrExit.size();
}
unsigned numberOfSpeculationRecoveries()
{
if (!m_dfgData)
return 0;
return m_dfgData->speculationRecovery.size();
}
DFG::OSRExit& osrExit(unsigned index)
{
return m_dfgData->osrExit[index];
}
DFG::SpeculationRecovery& speculationRecovery(unsigned index)
{
return m_dfgData->speculationRecovery[index];
}
#endif
......@@ -996,7 +1047,14 @@ namespace JSC {
#endif
#if ENABLE(DFG_JIT)
OwnPtr<CompactJITCodeMap> m_jitCodeMap;
Vector<DFG::OSREntryData> m_dfgOSREntry;
struct DFGData {
Vector<DFG::OSREntryData, 4> osrEntry;
SegmentedVector<DFG::OSRExit, 16> osrExit;
Vector<DFG::SpeculationRecovery, 4> speculationRecovery;
};
OwnPtr<DFGData> m_dfgData;
#endif
#if ENABLE(VALUE_PROFILER)
SegmentedVector<ValueProfile, 8> m_valueProfiles;
......
......@@ -134,10 +134,12 @@ public:
// Add a debug call. This call has no effect on JIT code execution state.
void debugCall(V_DFGDebugOperation_EP function, void* argument)
{
EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_globalData->scratchBufferForSize(sizeof(EncodedJSValue) * (GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters)));
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
storePtr(GPRInfo::toRegister(i), m_globalData->debugDataBuffer + i);
storePtr(GPRInfo::toRegister(i), buffer + i);
for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
move(TrustedImmPtr(m_globalData->debugDataBuffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
storeDouble(FPRInfo::toRegister(i), GPRInfo::regT0);
}
#if CPU(X86_64)
......@@ -152,11 +154,11 @@ public:
move(TrustedImmPtr(reinterpret_cast<void*>(function)), GPRInfo::regT0);
call(GPRInfo::regT0);
for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
move(TrustedImmPtr(m_globalData->debugDataBuffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
loadDouble(GPRInfo::regT0, FPRInfo::toRegister(i));
}
for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i)
loadPtr(m_globalData->debugDataBuffer + i, GPRInfo::toRegister(i));
loadPtr(buffer + i, GPRInfo::toRegister(i));
}
#endif
......
/*
* Copyright (C) 2011 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 "DFGCorrectableJumpPoint.h"
#include "CodeBlock.h"
namespace JSC { namespace DFG {
CodeLocationJump CorrectableJumpPoint::codeLocationForRepatch(CodeBlock* codeBlock) const
{
ASSERT(m_mode == CorrectedJump);
return CodeLocationJump(codeBlock->getJITCode().dataAddressAtOffset(m_codeOffset));
}
} } // namespace JSC::DFG
/*
* Copyright (C) 2011 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 DFGCorrectableJumpPoint_h
#define DFGCorrectableJumpPoint_h
#include "LinkBuffer.h"
#include "MacroAssembler.h"
namespace JSC { namespace DFG {
// This is a type-safe union of MacroAssembler::Jump and CodeLocationJump.
// Furthermore, it supports the notion of branching (possibly conditionally, but
// also possibly jumping unconditionally) to an out-of-line patchable jump.
// Thus it goes through three states:
//
// 1) Label of unpatchable branch or jump (i.e. MacroAssembler::Jump).
// 2) Label of patchable jump (i.e. MacroAssembler::Jump).
// 3) Corrected post-linking label of patchable jump (i.e. CodeLocationJump).
//
// The setting of state (1) corresponds to planting the in-line unpatchable
// branch or jump. The state transition (1)->(2) corresponds to linking the
// in-line branch or jump to the out-of-line patchable jump, and recording
// the latter's label. The state transition (2)->(3) corresponds to recording
// the out-of-line patchable jump's location after branch compaction has
// completed.
//
// You can also go directly from the first state to the third state, if you
// wish to use this class for in-line patchable jumps.
class CorrectableJumpPoint {
public:
CorrectableJumpPoint(MacroAssembler::Jump check)
: m_codeOffset(check.m_label.m_offset)
#ifndef NDEBUG
, m_mode(InitialJump)
#endif
{
#if CPU(ARM_THUMB2)
m_type = check.m_type;
m_condition = check.m_condition;
#endif
}
void switchToLateJump(MacroAssembler::Jump check)
{
#ifndef NDEBUG
ASSERT(m_mode == InitialJump);
m_mode = LateJump;
#endif
// Late jumps should only ever be real jumps.
#if CPU(ARM_THUMB2)
ASSERT(check.m_type == ARMv7Assembler::JumpNoConditionFixedSize);
ASSERT(check.m_condition == ARMv7Assembler::ConditionInvalid);
m_type = ARMv7Assembler::JumpNoConditionFixedSize;
m_condition = ARMv7Assembler::ConditionInvalid;
#endif
m_codeOffset = check.m_label.m_offset;
}
void correctInitialJump(LinkBuffer& linkBuffer)
{
ASSERT(m_mode == InitialJump);
#if CPU(ARM_THUMB2)
ASSERT(m_type == ARMv7Assembler::JumpNoConditionFixedSize);
ASSERT(m_condition == ARMv7Assembler::ConditionInvalid);
#endif
correctJump(linkBuffer);
}
void correctLateJump(LinkBuffer& linkBuffer)
{
ASSERT(m_mode == LateJump);
correctJump(linkBuffer);
}
MacroAssembler::Jump initialJump() const
{
ASSERT(m_mode == InitialJump);
return getJump();
}
MacroAssembler::Jump lateJump() const
{
ASSERT(m_mode == LateJump);
return getJump();
}
CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
private:
void correctJump(LinkBuffer& linkBuffer)
{
#ifndef NDEBUG
m_mode = CorrectedJump;
#endif
MacroAssembler::Label label;
label.m_label.m_offset = m_codeOffset;
m_codeOffset = linkBuffer.offsetOf(label);
}
MacroAssembler::Jump getJump() const
{
MacroAssembler::Jump jump;
jump.m_label.m_offset = m_codeOffset;
#if CPU(ARM_THUMB2)