Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (99632 => 99633)
--- trunk/Source/_javascript_Core/ChangeLog 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-11-09 00:43:15 UTC (rev 99633)
@@ -1,3 +1,37 @@
+2011-11-08 Gavin Barraclough <barraclo...@apple.com>
+
+ Fix OSR entry points to calculate offsets correctly WRT to branch compaction.
+ https://bugs.webkit.org/show_bug.cgi?id=71864
+
+ Reviewed by Filip Pizlo.
+
+ * assembler/LinkBuffer.h:
+ (JSC::LinkBuffer::offsetOf):
+ - We use this to return the offsets into the code of the entry points.
+ * dfg/DFGJITCompiler.cpp:
+ (JSC::DFG::JITCompiler::compileEntry):
+ (JSC::DFG::JITCompiler::compileBody):
+ (JSC::DFG::JITCompiler::compile):
+ (JSC::DFG::JITCompiler::compileFunction):
+ - Move the construction of the speculative JIT outside of
+ compileBody, such that it is still available to link the
+ OSR entry points at the point we are linking.
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::noticeOSREntry):
+ - Pass the label of the block & linkbuffer into noticeOSREntry.
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ (JSC::DFG::SpeculativeJIT::linkOSREntries):
+ - Moved call to noticeOSREntry until we we linking.
+ * dfg/DFGSpeculativeJIT.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ - Moved calculation of entries until we we linking.
+ * jit/JIT.h:
+ - Removed some members.
+
2011-11-08 Filip Pizlo <fpi...@apple.com>
DFG OSR exit code should be generated by a separate compiler, not
Modified: trunk/Source/_javascript_Core/assembler/LinkBuffer.h (99632 => 99633)
--- trunk/Source/_javascript_Core/assembler/LinkBuffer.h 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/assembler/LinkBuffer.h 2011-11-09 00:43:15 UTC (rev 99633)
@@ -168,6 +168,11 @@
return MacroAssembler::getLinkerCallReturnOffset(call);
}
+ uint32_t offsetOf(Label label)
+ {
+ return applyOffset(label.m_label).m_offset;
+ }
+
// Upon completion of all patching either 'finalizeCode()' or 'finalizeCodeAddendum()' should be called
// once to complete generation of the code. 'finalizeCode()' is suited to situations
// where the executable pool must also be retained, the lighter-weight 'finalizeCodeAddendum()' is
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (99632 => 99633)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-11-09 00:43:15 UTC (rev 99633)
@@ -55,8 +55,6 @@
void JITCompiler::compileEntry()
{
- m_startOfCode = label();
-
// This code currently matches the old JIT. In the function header we need to
// pop the return address (since we do not allow any recursion on the machine
// stack), and perform a fast register file check.
@@ -68,7 +66,7 @@
emitPutToCallFrameHeader(GPRInfo::regT2, RegisterFile::ReturnPC);
}
-void JITCompiler::compileBody()
+void JITCompiler::compileBody(SpeculativeJIT& speculative)
{
// We generate the speculative code path, followed by OSR exit code to return
// to the old JIT code if speculations fail.
@@ -80,8 +78,6 @@
addPtr(Imm32(1), AbsoluteAddress(codeBlock()->addressOfSpeculativeSuccessCounter()));
- Label speculativePathBegin = label();
- SpeculativeJIT speculative(*this);
bool compiledSpeculative = speculative.compile();
ASSERT_UNUSED(compiledSpeculative, compiledSpeculative);
@@ -208,10 +204,12 @@
// Preserve the return address to the callframe.
compileEntry();
// Generate the body of the program.
- compileBody();
+ SpeculativeJIT speculative(*this);
+ compileBody(speculative);
// Link
LinkBuffer linkBuffer(*m_globalData, this);
link(linkBuffer);
+ speculative.linkOSREntries(linkBuffer);
entry = JITCode(linkBuffer.finalizeCode(), JITCode::DFGJIT);
}
@@ -235,7 +233,8 @@
// === Function body code generation ===
- compileBody();
+ SpeculativeJIT speculative(*this);
+ compileBody(speculative);
// === Function footer code generation ===
//
@@ -270,6 +269,7 @@
// === Link ===
LinkBuffer linkBuffer(*m_globalData, this);
link(linkBuffer);
+ speculative.linkOSREntries(linkBuffer);
// FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs.
linkBuffer.link(callRegisterFileCheck, cti_register_file_check);
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (99632 => 99633)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h 2011-11-09 00:43:15 UTC (rev 99633)
@@ -28,6 +28,7 @@
#if ENABLE(DFG_JIT)
+#include <assembler/LinkBuffer.h>
#include <assembler/MacroAssembler.h>
#include <bytecode/CodeBlock.h>
#include <dfg/DFGAssemblyHelpers.h>
@@ -262,10 +263,10 @@
m_jsCalls.append(JSCallRecord(fastCall, slowCall, targetToCheck, isCall, codeOrigin));
}
- void noticeOSREntry(BasicBlock& basicBlock)
+ void noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer)
{
#if DFG_ENABLE(OSR_ENTRY)
- OSREntryData* entry = codeBlock()->appendDFGOSREntryData(basicBlock.bytecodeBegin, differenceBetween(m_startOfCode, label()));
+ OSREntryData* entry = codeBlock()->appendDFGOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead));
entry->m_expectedValues = basicBlock.valuesAtHead;
@@ -282,6 +283,8 @@
}
#else
UNUSED_PARAM(basicBlock);
+ UNUSED_PARAM(blockHead);
+ UNUSED_PARAM(linkBuffer);
#endif
}
@@ -296,7 +299,7 @@
private:
// Internal implementation to compile.
void compileEntry();
- void compileBody();
+ void compileBody(SpeculativeJIT&);
void link(LinkBuffer&);
void exitSpeculativeWithOSR(const OSRExit&, SpeculationRecovery*);
@@ -310,9 +313,6 @@
Vector<CallLinkRecord> m_calls;
Vector<CallExceptionRecord> m_exceptionChecks;
- // JIT code map for OSR entrypoints.
- Label m_startOfCode;
-
struct MethodGetRecord {
MethodGetRecord(Call slowCall, DataLabelPtr structToCompare, DataLabelPtr protoObj, DataLabelPtr protoStructToCompare, DataLabelPtr putFunction)
: m_slowCall(slowCall)
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (99632 => 99633)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-11-09 00:43:15 UTC (rev 99633)
@@ -224,9 +224,6 @@
return;
}
- if (block.isOSRTarget)
- m_jit.noticeOSREntry(block);
-
m_blockHeads[m_block] = m_jit.label();
#if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK)
m_jit.breakpoint();
@@ -410,6 +407,15 @@
return true;
}
+void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
+{
+ for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
+ BasicBlock& block = *m_jit.graph().m_blocks[blockIndex];
+ if (block.isOSRTarget)
+ m_jit.noticeOSREntry(block, m_blockHeads[blockIndex], linkBuffer);
+ }
+}
+
ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
{
switch (valueSource.kind()) {
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (99632 => 99633)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-11-09 00:43:15 UTC (rev 99633)
@@ -131,6 +131,7 @@
SpeculativeJIT(JITCompiler&);
bool compile();
+ void linkOSREntries(LinkBuffer&);
// Retrieve the list of bail-outs from the speculative path,
// and additional recovery information.
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (99632 => 99633)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2011-11-09 00:43:15 UTC (rev 99633)
@@ -218,13 +218,8 @@
m_labels[m_bytecodeOffset] = label();
-#if ENABLE(DFG_JIT)
- if (m_canBeOptimized)
- m_jitCodeMapEncoder.append(m_bytecodeOffset, differenceBetween(m_startOfCode, label()));
-#endif
-
#if ENABLE(JIT_VERBOSE)
- printf("Old JIT emitting code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, differenceBetween(m_startOfCode, label()));
+ printf("Old JIT emitting code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, (long)debugOffset());
#endif
switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
@@ -436,7 +431,7 @@
#endif
#if ENABLE(JIT_VERBOSE)
- printf("Old JIT emitting slow code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, differenceBetween(m_startOfCode, label()));
+ printf("Old JIT emitting slow code for bc#%u at offset 0x%lx.\n", m_bytecodeOffset, (long)debugOffset());
#endif
switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
@@ -536,9 +531,6 @@
#if ENABLE(VALUE_PROFILER)
m_canBeOptimized = m_codeBlock->canCompileWithDFG();
#endif
-#if ENABLE(DFG_JIT) || ENABLE(JIT_VERBOSE)
- m_startOfCode = label();
-#endif
// Just add a little bit of randomness to the codegen
if (m_randomGenerator.getUint32() & 1)
@@ -699,8 +691,14 @@
}
#if ENABLE(DFG_JIT)
- if (m_canBeOptimized)
- m_codeBlock->setJITCodeMap(m_jitCodeMapEncoder.finish());
+ if (m_canBeOptimized) {
+ CompactJITCodeMap::Encoder jitCodeMapEncoder;
+ for (unsigned bytecodeOffset = 0; bytecodeOffset < m_labels.size(); ++bytecodeOffset) {
+ if (m_labels[bytecodeOffset].isSet())
+ jitCodeMapEncoder.append(bytecodeOffset, patchBuffer.offsetOf(m_labels[bytecodeOffset]));
+ }
+ m_codeBlock->setJITCodeMap(jitCodeMapEncoder.finish());
+ }
#endif
if (m_codeBlock->codeType() == FunctionCode && functionEntryArityCheck)
Modified: trunk/Source/_javascript_Core/jit/JIT.h (99632 => 99633)
--- trunk/Source/_javascript_Core/jit/JIT.h 2011-11-09 00:43:07 UTC (rev 99632)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2011-11-09 00:43:15 UTC (rev 99633)
@@ -1087,12 +1087,6 @@
#if ENABLE(VALUE_PROFILER)
bool m_canBeOptimized;
#endif
-#if ENABLE(DFG_JIT) || ENABLE(JIT_VERBOSE)
- Label m_startOfCode;
-#endif
-#if ENABLE(DFG_JIT)
- CompactJITCodeMap::Encoder m_jitCodeMapEncoder;
-#endif
} JIT_CLASS_ALIGNMENT;
inline void JIT::emit_op_loop(Instruction* currentInstruction)