Diff
Modified: branches/jsc-tailcall/Source/_javascript_Core/ChangeLog (187636 => 187637)
--- branches/jsc-tailcall/Source/_javascript_Core/ChangeLog 2015-07-31 02:07:03 UTC (rev 187636)
+++ branches/jsc-tailcall/Source/_javascript_Core/ChangeLog 2015-07-31 03:40:56 UTC (rev 187637)
@@ -1,3 +1,27 @@
+2015-07-30 Michael Saboff <msab...@apple.com>
+
+ jsc-tailcall: Eliminate rdi from temp register list for X86-64 Windows
+ https://bugs.webkit.org/show_bug.cgi?id=147461
+
+ Reviewed by Basile Clement.
+
+ Eliminated rdi from the list of temporary registers for X86-64 Windows as it
+ is a callee saves register. This reduced the number of temporary registers
+ for X86-64 Windows. Since the LLInt needs 6 available registers in a couple
+ of places, added a register alias called extraTempReg which is t0 on X86-64
+ Windows and t5 on all other platforms.
+
+ As a result of this change, I changed the "PC" register in the LLInt from t5
+ to t4.
+
+ * jit/GPRInfo.h:
+ (JSC::GPRInfo::toRegister):
+ (JSC::GPRInfo::toIndex):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * offlineasm/x86.rb:
+
2015-07-30 Basile Clement <basile_clem...@apple.com>
jsc-tailcall: Add enums for type-safety
Modified: branches/jsc-tailcall/Source/_javascript_Core/jit/GPRInfo.h (187636 => 187637)
--- branches/jsc-tailcall/Source/_javascript_Core/jit/GPRInfo.h 2015-07-31 02:07:03 UTC (rev 187636)
+++ branches/jsc-tailcall/Source/_javascript_Core/jit/GPRInfo.h 2015-07-31 03:40:56 UTC (rev 187637)
@@ -396,9 +396,8 @@
static const GPRReg regT1 = X86Registers::edx;
static const GPRReg regT2 = X86Registers::r8;
static const GPRReg regT3 = X86Registers::r9;
- static const GPRReg regT4 = X86Registers::edi; // This one is actually callee-save
- static const GPRReg regT5 = X86Registers::r10;
- static const GPRReg regT6 = X86Registers::ecx;
+ static const GPRReg regT4 = X86Registers::r10;
+ static const GPRReg regT5 = X86Registers::ecx;
#endif
static const GPRReg regCS0 = X86Registers::ebx;
@@ -410,31 +409,31 @@
static const GPRReg regCS4 = X86Registers::r15;
#else
static const GPRReg regCS3 = X86Registers::esi;
- static const GPRReg regCS4 = X86Registers::edi; // regT4
+ static const GPRReg regCS4 = X86Registers::edi;
static const GPRReg regCS5 = X86Registers::r14;
static const GPRReg regCS6 = X86Registers::r15;
#endif
// These constants provide the names for the general purpose argument & return value registers.
-#if OS(WINDOWS)
- static const GPRReg argumentGPR0 = X86Registers::ecx; // regT6
- static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
- static const GPRReg argumentGPR2 = X86Registers::r8; // regT2
- static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
-#else
+#if !OS(WINDOWS)
static const GPRReg argumentGPR0 = X86Registers::edi; // regT6
static const GPRReg argumentGPR1 = X86Registers::esi; // regT1
static const GPRReg argumentGPR2 = X86Registers::edx; // regT2
static const GPRReg argumentGPR3 = X86Registers::ecx; // regT3
static const GPRReg argumentGPR4 = X86Registers::r8; // regT4
static const GPRReg argumentGPR5 = X86Registers::r9; // regT7
+#else
+ static const GPRReg argumentGPR0 = X86Registers::ecx; // regT5
+ static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
+ static const GPRReg argumentGPR2 = X86Registers::r8; // regT2
+ static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
#endif
- static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5
- static const GPRReg nonArgGPR1 = X86Registers::ebx;
+ static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows)
+ static const GPRReg nonArgGPR1 = X86Registers::ebx; // Callee save
static const GPRReg returnValueGPR = X86Registers::eax; // regT0
static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2
- static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5
- static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5
+ static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
+ static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
static GPRReg toRegister(unsigned index)
@@ -443,7 +442,7 @@
#if !OS(WINDOWS)
static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regCS0, regCS1, regCS2 };
#else
- static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regCS0, regCS1, regCS2, regCS3 };
+ static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regCS0, regCS1, regCS2, regCS3, regCS4 };
#endif
return registerForIndex[index];
}
@@ -466,7 +465,7 @@
#if !OS(WINDOWS)
static const unsigned indexForRegister[16] = { 0, 3, 2, 8, InvalidIndex, InvalidIndex, 1, 6, 4, 7, 5, InvalidIndex, 9, 10, InvalidIndex, InvalidIndex };
#else
- static const unsigned indexForRegister[16] = { 0, 6, 1, 7, InvalidIndex, InvalidIndex, 10, 4, 2, 3, 5, InvalidIndex, 8, 9, InvalidIndex, InvalidIndex };
+ static const unsigned indexForRegister[16] = { 0, 5, 1, 6, InvalidIndex, InvalidIndex, 9, 10, 2, 3, 4, InvalidIndex, 7, 8, InvalidIndex, InvalidIndex };
#endif
return indexForRegister[reg];
}
Modified: branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter.asm (187636 => 187637)
--- branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2015-07-31 02:07:03 UTC (rev 187636)
+++ branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2015-07-31 03:40:56 UTC (rev 187637)
@@ -77,8 +77,8 @@
# - pc holds the (native) program counter on 32-bits ARM architectures (ARM,
# ARMv7, ARMv7_TRADITIONAL)
#
-# - t0, t1, t2, t3, t4 and t5 are temporary registers that can get trashed on
-# calls, and are pairwise distinct registers. t5 holds the JS program counter, so use
+# - t0, t1, t2, t3, t4 and optionally t5 are temporary registers that can get trashed on
+# calls, and are pairwise distinct registers. t4 holds the JS program counter, so use
# with caution in opcodes (actually, don't use it in opcodes at all, except as PC).
#
# - r0 and r1 are the platform's customary return registers, and thus are
@@ -126,9 +126,6 @@
# a2 is r0 on X86 (because we have so few registers) and r1 on X86_64 (because
# the ABI enforces it).
#
-# - On X86_64_WIN, t4 is actually callee-save (because we have so few
-# caller-save registers).
-#
# The following floating-point registers are available:
#
# - ft0-ft5 are temporary floating-point registers that get trashed on calls,
@@ -232,7 +229,7 @@
# - The PC base (or PB for short) must be stored in a callee-save register.
# - C calls are still given the Instruction* rather than the PC index.
# This requires an add before the call, and a sub after.
- const PC = t5
+ const PC = t4
const PB = csr0
const tagTypeNumber = csr1
const tagMask = csr2
@@ -250,7 +247,7 @@
end
else
- const PC = t5
+ const PC = t4
macro loadisFromInstruction(offset, dest)
loadis offset * 4[PC], dest
end
@@ -260,6 +257,12 @@
end
end
+if X86_64_WIN
+ const extraTempReg = t0
+else
+ const extraTempReg = t5
+end
+
# Constants for reasoning about value representation.
if BIG_ENDIAN
const TagOffset = 0
@@ -580,12 +583,12 @@
macro restoreStackPointerAfterCall()
loadp CodeBlock[cfr], t2
- getFrameRegisterSizeForCodeBlock(t2, t4)
+ getFrameRegisterSizeForCodeBlock(t2, t2)
if ARMv7
- subp cfr, t4, t4
- move t4, sp
+ subp cfr, t2, t2
+ move t2, sp
else
- subp cfr, t4, sp
+ subp cfr, t2, sp
end
end
@@ -646,7 +649,7 @@
macro (callee, calleeFramePtr)
btpz calleeFramePtr, .dontUpdateSP
move calleeFramePtr, sp
- prepareCall(callee, t3, t4)
+ prepareCall(callee, t3, extraTempReg)
.dontUpdateSP:
callTargetFunction(callee)
end)
Modified: branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (187636 => 187637)
--- branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2015-07-31 02:07:03 UTC (rev 187636)
+++ branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2015-07-31 03:40:56 UTC (rev 187637)
@@ -670,14 +670,14 @@
traceExecution()
loadi 8[PC], t0
loadp PayloadOffset[cfr, t0, 8], t0
- loadp JSFunction::m_rareData[t0], t4
- btpz t4, .opCreateThisSlow
- loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t4], t1
- loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t4], t2
+ loadp JSFunction::m_rareData[t0], t5
+ btpz t5, .opCreateThisSlow
+ loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t5], t1
+ loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t5], t2
btpz t1, .opCreateThisSlow
- loadpFromInstruction(4, t4)
- bpeq t4, 1, .hasSeenMultipleCallee
- bpneq t4, t0, .opCreateThisSlow
+ loadpFromInstruction(4, t5)
+ bpeq t5, 1, .hasSeenMultipleCallee
+ bpneq t5, t0, .opCreateThisSlow
.hasSeenMultipleCallee:
allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
loadi 4[PC], t1
@@ -2166,9 +2166,9 @@
macro putLocalClosureVar()
loadisFromInstruction(3, t1)
loadConstantOrVariable(t1, t2, t3)
- loadpFromInstruction(5, t4)
- btpz t4, .noVariableWatchpointSet
- notifyWrite(t4, .pDynamic)
+ loadpFromInstruction(5, t5)
+ btpz t5, .noVariableWatchpointSet
+ notifyWrite(t5, .pDynamic)
.noVariableWatchpointSet:
loadisFromInstruction(6, t1)
storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
@@ -2269,22 +2269,22 @@
# t1 is holding the pointer to the typeProfilerLog.
loadp VM::m_typeProfilerLog[t1], t1
- # t0 is holding the payload, t4 is holding the tag.
+ # t0 is holding the payload, t5 is holding the tag.
loadisFromInstruction(1, t2)
- loadConstantOrVariable(t2, t4, t0)
+ loadConstantOrVariable(t2, t5, t0)
# t2 is holding the pointer to the current log entry.
loadp TypeProfilerLog::m_currentLogEntryPtr[t1], t2
# Store the JSValue onto the log entry.
- storei t4, TypeProfilerLog::LogEntry::value + TagOffset[t2]
+ storei t5, TypeProfilerLog::LogEntry::value + TagOffset[t2]
storei t0, TypeProfilerLog::LogEntry::value + PayloadOffset[t2]
# Store the TypeLocation onto the log entry.
loadpFromInstruction(2, t3)
storep t3, TypeProfilerLog::LogEntry::location[t2]
- bieq t4, CellTag, .opProfileTypeIsCell
+ bieq t5, CellTag, .opProfileTypeIsCell
storei 0, TypeProfilerLog::LogEntry::structureID[t2]
jmp .opProfileTypeSkipIsCell
.opProfileTypeIsCell:
Modified: branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (187636 => 187637)
--- branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2015-07-31 02:07:03 UTC (rev 187636)
+++ branches/jsc-tailcall/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2015-07-31 03:40:56 UTC (rev 187637)
@@ -163,10 +163,10 @@
vmEntryRecord(cfr, t4)
loadp VMEntryRecord::m_vm[t4], vm
- loadp VMEntryRecord::m_prevTopCallFrame[t4], t5
- storep t5, VM::topCallFrame[vm]
- loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], t5
- storep t5, VM::topVMEntryFrame[vm]
+ loadp VMEntryRecord::m_prevTopCallFrame[t4], extraTempReg
+ storep extraTempReg, VM::topCallFrame[vm]
+ loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], extraTempReg
+ storep extraTempReg, VM::topVMEntryFrame[vm]
subp cfr, CalleeRegisterSaveSize, sp
@@ -180,21 +180,21 @@
.copyHeaderLoop:
subi 1, t3
- loadq [protoCallFrame, t3, 8], t5
- storeq t5, CodeBlock[sp, t3, 8]
+ loadq [protoCallFrame, t3, 8], extraTempReg
+ storeq extraTempReg, CodeBlock[sp, t3, 8]
btinz t3, .copyHeaderLoop
loadi PayloadOffset + ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], t4
subi 1, t4
- loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t5
- subi 1, t5
+ loadi ProtoCallFrame::paddedArgCount[protoCallFrame], extraTempReg
+ subi 1, extraTempReg
- bieq t4, t5, .copyArgs
+ bieq t4, extraTempReg, .copyArgs
move ValueUndefined, t3
.fillExtraArgsLoop:
- subi 1, t5
- storeq t3, ThisArgumentOffset + 8[sp, t5, 8]
- bineq t4, t5, .fillExtraArgsLoop
+ subi 1, extraTempReg
+ storeq t3, ThisArgumentOffset + 8[sp, extraTempReg, 8]
+ bineq t4, extraTempReg, .fillExtraArgsLoop
.copyArgs:
loadp ProtoCallFrame::args[protoCallFrame], t3
@@ -202,8 +202,8 @@
.copyArgsLoop:
btiz t4, .copyArgsDone
subi 1, t4
- loadq [t3, t4, 8], t5
- storeq t5, ThisArgumentOffset + 8[sp, t4, 8]
+ loadq [t3, t4, 8], extraTempReg
+ storeq extraTempReg, ThisArgumentOffset + 8[sp, t4, 8]
jmp .copyArgsLoop
.copyArgsDone:
@@ -218,22 +218,22 @@
move TagTypeNumber, tagTypeNumber
addp TagBitTypeOther, tagTypeNumber, tagMask
- checkStackPointerAlignment(t5, 0xbad0dc02)
+ checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
makeCall(entry, t3)
# We may have just made a call into a JS function, so we can't rely on sp
# for anything but the fact that our own locals (ie the VMEntryRecord) are
# not below it. It also still has to be aligned, though.
- checkStackPointerAlignment(t5, 0xbad0dc03)
+ checkStackPointerAlignment(extraTempReg, 0xbad0dc03)
vmEntryRecord(cfr, t4)
loadp VMEntryRecord::m_vm[t4], vm
- loadp VMEntryRecord::m_prevTopCallFrame[t4], t5
- storep t5, VM::topCallFrame[vm]
- loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], t5
- storep t5, VM::topVMEntryFrame[vm]
+ loadp VMEntryRecord::m_prevTopCallFrame[t4], extraTempReg
+ storep extraTempReg, VM::topCallFrame[vm]
+ loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], extraTempReg
+ storep extraTempReg, VM::topVMEntryFrame[vm]
subp cfr, CalleeRegisterSaveSize, sp
@@ -283,10 +283,10 @@
vmEntryRecord(cfr, t2)
loadp VMEntryRecord::m_vm[t2], t3
- loadp VMEntryRecord::m_prevTopCallFrame[t2], t5
- storep t5, VM::topCallFrame[t3]
- loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], t5
- storep t5, VM::topVMEntryFrame[t3]
+ loadp VMEntryRecord::m_prevTopCallFrame[t2], extraTempReg
+ storep extraTempReg, VM::topCallFrame[t3]
+ loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], extraTempReg
+ storep extraTempReg, VM::topVMEntryFrame[t3]
subp cfr, CalleeRegisterSaveSize, sp
@@ -589,14 +589,14 @@
traceExecution()
loadisFromInstruction(2, t0)
loadp [cfr, t0, 8], t0
- loadp JSFunction::m_rareData[t0], t4
- btpz t4, .opCreateThisSlow
- loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t4], t1
- loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t4], t2
+ loadp JSFunction::m_rareData[t0], t3
+ btpz t3, .opCreateThisSlow
+ loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t3], t1
+ loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t3], t2
btpz t1, .opCreateThisSlow
- loadpFromInstruction(4, t4)
- bpeq t4, 1, .hasSeenMultipleCallee
- bpneq t4, t0, .opCreateThisSlow
+ loadpFromInstruction(4, t3)
+ bpeq t3, 1, .hasSeenMultipleCallee
+ bpneq t3, t0, .opCreateThisSlow
.hasSeenMultipleCallee:
allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
loadisFromInstruction(1, t1)
Modified: branches/jsc-tailcall/Source/_javascript_Core/offlineasm/x86.rb (187636 => 187637)
--- branches/jsc-tailcall/Source/_javascript_Core/offlineasm/x86.rb 2015-07-31 02:07:03 UTC (rev 187636)
+++ branches/jsc-tailcall/Source/_javascript_Core/offlineasm/x86.rb 2015-07-31 03:40:56 UTC (rev 187637)
@@ -68,10 +68,10 @@
# rdx => t1, a1, r1
# r8 => t2, a2
# r9 => t3, a3
-# rdi => t4, (callee-save)
-# r10 => t5
+# r10 => t4
# rsi => (callee-save)
# rbx => csr0 (callee-save, PB, unused in baseline)
+# rdi => (callee-save)
# r12 => (callee-save)
# r13 => (callee-save)
# r14 => csr1 (callee-save, tagTypeNumber)
@@ -283,8 +283,9 @@
when "t3", "a3"
isWin ? "r9" : "ecx"
when "t4"
- isWin ? "edi" : "r8"
+ isWin ? "r10" : "r8"
when "t5"
+ raise "cannot use register #{name} on X86-64 Windows" unless not isWin
"r10"
when "csr0"
"ebx"