Diff
Modified: branches/jsc-tailcall/Source/_javascript_Core/ChangeLog (187353 => 187354)
--- branches/jsc-tailcall/Source/_javascript_Core/ChangeLog 2015-07-24 18:51:48 UTC (rev 187353)
+++ branches/jsc-tailcall/Source/_javascript_Core/ChangeLog 2015-07-24 18:56:48 UTC (rev 187354)
@@ -1,3 +1,37 @@
+2015-07-23 Basile Clement <[email protected]>
+
+ jsc-tailcall: Repatching tail calls as jump should depend on the opcode, not the JS CallLinkInfo
+ https://bugs.webkit.org/show_bug.cgi?id=147243
+
+ Reviewed by Michael Saboff.
+
+ When linking, we are currently looking at data from the JS CallLinkInfo
+ to determine if we have a call or jump opcode. However, even with a
+ tail call, the slow path uses a call opcode for simplicity.
+
+ This adds the information that we are performing a tail call into the
+ CodeLocationNearCall class, which allows us to link as jump or call
+ based on the actual opcode.
+
+ This is a conceptual error that couldn't be found on X86 architecture
+ since the patching of jump and calls is identical there.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::repatchNearCall):
+ * assembler/CodeLocation.h:
+ (JSC::CodeLocationNearCall::CodeLocationNearCall):
+ (JSC::CodeLocationNearCall::isTail):
+ (JSC::CodeLocationCommon::nearCallAtOffset):
+ * assembler/LinkBuffer.h:
+ (JSC::LinkBuffer::locationOfNearCall):
+ * assembler/RepatchBuffer.h:
+ (JSC::RepatchBuffer::relink):
+ * jit/Repatch.cpp:
+ (JSC::linkSlowFor):
+ (JSC::linkFor):
+ (JSC::revertCall):
+ (JSC::linkPolymorphicCall):
+
2015-07-21 Basile Clement <[email protected]>
jsc-tailcall: Add new opcodes for tail calls
Modified: branches/jsc-tailcall/Source/_javascript_Core/assembler/AbstractMacroAssembler.h (187353 => 187354)
--- branches/jsc-tailcall/Source/_javascript_Core/assembler/AbstractMacroAssembler.h 2015-07-24 18:51:48 UTC (rev 187353)
+++ branches/jsc-tailcall/Source/_javascript_Core/assembler/AbstractMacroAssembler.h 2015-07-24 18:56:48 UTC (rev 187354)
@@ -1153,7 +1153,15 @@
static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination)
{
- AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
+ switch (nearCall.callMode()) {
+ case CallMode::Tail:
+ AssemblerType::relinkJump(nearCall.dataLocation(), destination.executableAddress());
+ return;
+ case CallMode::Regular:
+ AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
+ return;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
}
static void repatchCompact(CodeLocationDataLabelCompact dataLabelCompact, int32_t value)
Modified: branches/jsc-tailcall/Source/_javascript_Core/assembler/CodeLocation.h (187353 => 187354)
--- branches/jsc-tailcall/Source/_javascript_Core/assembler/CodeLocation.h 2015-07-24 18:51:48 UTC (rev 187353)
+++ branches/jsc-tailcall/Source/_javascript_Core/assembler/CodeLocation.h 2015-07-24 18:56:48 UTC (rev 187354)
@@ -32,6 +32,8 @@
namespace JSC {
+enum CallMode { Regular, Tail };
+
class CodeLocationInstruction;
class CodeLocationLabel;
class CodeLocationJump;
@@ -59,7 +61,7 @@
CodeLocationLabel labelAtOffset(int offset);
CodeLocationJump jumpAtOffset(int offset);
CodeLocationCall callAtOffset(int offset);
- CodeLocationNearCall nearCallAtOffset(int offset);
+ CodeLocationNearCall nearCallAtOffset(int offset, CallMode);
CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
CodeLocationDataLabelCompact dataLabelCompactAtOffset(int offset);
@@ -115,10 +117,13 @@
class CodeLocationNearCall : public CodeLocationCommon {
public:
CodeLocationNearCall() {}
- explicit CodeLocationNearCall(MacroAssemblerCodePtr location)
- : CodeLocationCommon(location) {}
- explicit CodeLocationNearCall(void* location)
- : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+ explicit CodeLocationNearCall(MacroAssemblerCodePtr location, CallMode callMode)
+ : CodeLocationCommon(location), m_callMode(callMode) {}
+ explicit CodeLocationNearCall(void* location, CallMode callMode)
+ : CodeLocationCommon(MacroAssemblerCodePtr(location)), m_callMode(callMode) {}
+ CallMode callMode() { return m_callMode; }
+private:
+ CallMode m_callMode = CallMode::Regular;
};
class CodeLocationDataLabel32 : public CodeLocationCommon {
@@ -181,10 +186,10 @@
return CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset);
}
-inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset)
+inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset, CallMode callMode)
{
ASSERT_VALID_CODE_OFFSET(offset);
- return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset);
+ return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset, callMode);
}
inline CodeLocationDataLabelPtr CodeLocationCommon::dataLabelPtrAtOffset(int offset)
Modified: branches/jsc-tailcall/Source/_javascript_Core/assembler/LinkBuffer.h (187353 => 187354)
--- branches/jsc-tailcall/Source/_javascript_Core/assembler/LinkBuffer.h 2015-07-24 18:51:48 UTC (rev 187353)
+++ branches/jsc-tailcall/Source/_javascript_Core/assembler/LinkBuffer.h 2015-07-24 18:56:48 UTC (rev 187354)
@@ -180,7 +180,8 @@
{
ASSERT(call.isFlagSet(Call::Linkable));
ASSERT(call.isFlagSet(Call::Near));
- return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)));
+ return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)),
+ call.isFlagSet(Call::Tail) ? CallMode::Tail : CallMode::Regular);
}
CodeLocationLabel locationOf(PatchableJump jump)
Modified: branches/jsc-tailcall/Source/_javascript_Core/assembler/RepatchBuffer.h (187353 => 187354)
--- branches/jsc-tailcall/Source/_javascript_Core/assembler/RepatchBuffer.h 2015-07-24 18:51:48 UTC (rev 187353)
+++ branches/jsc-tailcall/Source/_javascript_Core/assembler/RepatchBuffer.h 2015-07-24 18:56:48 UTC (rev 187354)
@@ -80,17 +80,14 @@
MacroAssembler::repatchCall(call, destination);
}
- void relink(CodeLocationNearCall nearCall, CodePtr destination, CallLinkInfo::CallType callType)
+ void relink(CodeLocationNearCall nearCall, CodePtr destination)
{
- relink(nearCall, CodeLocationLabel(destination), callType);
+ relink(nearCall, CodeLocationLabel(destination));
}
- void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination, CallLinkInfo::CallType callType)
+ void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination)
{
- if (CallLinkInfo::isTailCallType(callType))
- MacroAssembler::repatchJump(CodeLocationJump(nearCall.dataLocation()), destination);
- else
- MacroAssembler::repatchNearCall(nearCall, destination);
+ MacroAssembler::repatchNearCall(nearCall, destination);
}
void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value)
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/Repatch.cpp (187353 => 187354)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/Repatch.cpp 2015-07-24 18:51:48 UTC (rev 187353)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/Repatch.cpp 2015-07-24 18:56:48 UTC (rev 187354)
@@ -1606,8 +1606,7 @@
{
repatchBuffer.relink(
callLinkInfo.callReturnLocation(),
- virtualThunk(vm, callLinkInfo, kind, registers).code(),
- callLinkInfo.callType());
+ virtualThunk(vm, callLinkInfo, kind, registers).code());
}
void linkFor(
@@ -1628,7 +1627,7 @@
callLinkInfo.setLastSeenCallee(exec->callerFrame()->vm(), callerCodeBlock->ownerExecutable(), callee);
if (shouldShowDisassemblyFor(callerCodeBlock))
dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin(), " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n");
- repatchBuffer.relink(callLinkInfo.hotPathOther(), codePtr, callLinkInfo.callType());
+ repatchBuffer.relink(callLinkInfo.hotPathOther(), codePtr);
if (calleeCodeBlock)
calleeCodeBlock->linkIncomingCall(exec->callerFrame(), &callLinkInfo);
@@ -1636,8 +1635,7 @@
if (kind == CodeForCall) {
repatchBuffer.relink(
callLinkInfo.callReturnLocation(),
- linkPolymorphicCallThunk(vm, callLinkInfo, registers).code(),
- callLinkInfo.callType());
+ linkPolymorphicCallThunk(vm, callLinkInfo, registers).code());
return;
}
@@ -1665,7 +1663,7 @@
RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0);
repatchBuffer.relink(
- callLinkInfo.callReturnLocation(), codeRef.code(), callLinkInfo.callType());
+ callLinkInfo.callReturnLocation(), codeRef.code());
callLinkInfo.clearSeen();
callLinkInfo.clearCallee();
callLinkInfo.clearStub();
@@ -1944,8 +1942,7 @@
// taking the polymorphic path on 32 bit platforms
repatchBuffer.relink(
callLinkInfo.callReturnLocation(),
- slowPathCodePtr,
- callLinkInfo.callType());
+ slowPathCodePtr);
// If there had been a previous stub routine, that one will die as soon as the GC runs and sees
// that it's no longer on stack.