Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (194125 => 194126)
--- trunk/Source/_javascript_Core/ChangeLog 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-12-16 01:05:00 UTC (rev 194126)
@@ -1,5 +1,43 @@
2015-12-15 Mark Lam <[email protected]>
+ Introducing ScratchRegisterAllocator::PreservedState.
+ https://bugs.webkit.org/show_bug.cgi?id=152315
+
+ Reviewed by Geoffrey Garen.
+
+ restoreReusedRegistersByPopping() should always be called with 2 values that
+ matches the expectation of preserveReusedRegistersByPushing(). Those 2 values
+ are the number of bytes preserved and the ExtraStackSpace requirement. By
+ encapsulating them in a ScratchRegisterAllocator::PreservedState, we can make
+ it less error prone when calling restoreReusedRegistersByPopping(). Now, we only
+ need to pass it the appropriate PreservedState that its matching
+ preserveReusedRegistersByPushing() returned.
+
+ * bytecode/PolymorphicAccess.cpp:
+ (JSC::AccessGenerationState::restoreScratch):
+ (JSC::AccessCase::generate):
+ (JSC::PolymorphicAccess::regenerate):
+ * bytecode/PolymorphicAccess.h:
+ (JSC::AccessGenerationState::AccessGenerationState):
+ * ftl/FTLCompileBinaryOp.cpp:
+ (JSC::FTL::generateBinaryBitOpFastPath):
+ (JSC::FTL::generateRightShiftFastPath):
+ (JSC::FTL::generateBinaryArithOpFastPath):
+ * ftl/FTLLazySlowPath.cpp:
+ (JSC::FTL::LazySlowPath::generate):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::DFG::LowerDFGToLLVM::emitStoreBarrier):
+ * jit/ScratchRegisterAllocator.cpp:
+ (JSC::ScratchRegisterAllocator::allocateScratchGPR):
+ (JSC::ScratchRegisterAllocator::allocateScratchFPR):
+ (JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
+ (JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):
+ * jit/ScratchRegisterAllocator.h:
+ (JSC::ScratchRegisterAllocator::usedRegisters):
+ (JSC::ScratchRegisterAllocator::PreservedState::PreservedState):
+
+2015-12-15 Mark Lam <[email protected]>
+
Polymorphic operand types for DFG and FTL bit operators.
https://bugs.webkit.org/show_bug.cgi?id=152191
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (194125 => 194126)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-12-16 01:05:00 UTC (rev 194126)
@@ -158,7 +158,7 @@
0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54817EE274900ABB217 /* TempRegisterSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E54917EE274900ABB217 /* Repatch.cpp */; };
0F24E55117EE274900ABB217 /* Repatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54A17EE274900ABB217 /* Repatch.h */; };
- 0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; };
+ 0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E54B17EE274900ABB217 /* ScratchRegisterAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F24E55517F0B71C00ABB217 /* InlineCallFrameSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55317F0B71C00ABB217 /* InlineCallFrameSet.cpp */; };
0F24E55617F0B71C00ABB217 /* InlineCallFrameSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F24E55417F0B71C00ABB217 /* InlineCallFrameSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F24E55817F74EDB00ABB217 /* ValueRecovery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F24E55717F74EDB00ABB217 /* ValueRecovery.cpp */; };
Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp (194125 => 194126)
--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp 2015-12-16 01:05:00 UTC (rev 194126)
@@ -54,7 +54,7 @@
void AccessGenerationState::restoreScratch()
{
- allocator->restoreReusedRegistersByPopping(*jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator->restoreReusedRegistersByPopping(*jit, preservedReusedRegisterState);
}
void AccessGenerationState::succeed()
@@ -727,7 +727,7 @@
done.link(&jit);
- jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()->stackPointerOffset() * sizeof(Register)) - state.numberOfBytesUsedToPreserveReusedRegisters - state.numberOfStackBytesUsedForRegisterPreservation()),
+ jit.addPtr(CCallHelpers::TrustedImm32((jit.codeBlock()->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - state.numberOfStackBytesUsedForRegisterPreservation()),
GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
state.restoreLiveRegistersFromStackForCall(isGetter());
@@ -886,12 +886,13 @@
else
scratchGPR3 = InvalidGPRReg;
- size_t numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+ ScratchRegisterAllocator::PreservedState preservedState =
+ allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
ASSERT(structure()->transitionWatchpointSetHasBeenInvalidated());
bool scratchGPRHasStorage = false;
- bool needsToMakeRoomOnStackForCCall = !numberOfBytesUsedToPreserveReusedRegisters && codeBlock->jitType() == JITCode::FTLJIT;
+ bool needsToMakeRoomOnStackForCCall = !preservedState.numberOfBytesPreserved && codeBlock->jitType() == JITCode::FTLJIT;
if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()) {
size_t newSize = newStructure()->outOfLineCapacity() * sizeof(JSValue);
@@ -1016,12 +1017,12 @@
});
}
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
state.succeed();
if (newStructure()->outOfLineCapacity() != structure()->outOfLineCapacity()) {
slowPath.link(&jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
allocator.preserveUsedRegistersToScratchBufferForCall(jit, scratchBuffer, scratchGPR);
if (needsToMakeRoomOnStackForCCall)
jit.makeSpaceOnStackForCCall();
@@ -1245,7 +1246,8 @@
CCallHelpers jit(&vm, codeBlock);
state.jit = &jit;
- state.numberOfBytesUsedToPreserveReusedRegisters = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ state.preservedReusedRegisterState =
+ allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
bool allGuardedByStructureCheck = true;
bool hasJSGetterSetterCall = false;
@@ -1315,7 +1317,7 @@
MacroAssembler::Label makeshiftCatchHandler = jit.label();
int stackPointerOffset = codeBlock->stackPointerOffset() * sizeof(EncodedJSValue);
- stackPointerOffset -= state.numberOfBytesUsedToPreserveReusedRegisters;
+ stackPointerOffset -= state.preservedReusedRegisterState.numberOfBytesPreserved;
stackPointerOffset -= state.numberOfStackBytesUsedForRegisterPreservation();
jit.loadPtr(vm.addressOfCallFrameForCatch(), GPRInfo::callFrameRegister);
Modified: trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h (194125 => 194126)
--- trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/bytecode/PolymorphicAccess.h 2015-12-16 01:05:00 UTC (rev 194126)
@@ -33,6 +33,7 @@
#include "MacroAssembler.h"
#include "ObjectPropertyConditionSet.h"
#include "Opcode.h"
+#include "ScratchRegisterAllocator.h"
#include "Structure.h"
#include <wtf/Vector.h>
@@ -349,7 +350,7 @@
}
CCallHelpers* jit { nullptr };
ScratchRegisterAllocator* allocator;
- unsigned numberOfBytesUsedToPreserveReusedRegisters { 0 };
+ ScratchRegisterAllocator::PreservedState preservedReusedRegisterState;
PolymorphicAccess* access { nullptr };
StructureStubInfo* stubInfo { nullptr };
MacroAssembler::JumpList success;
Modified: trunk/Source/_javascript_Core/ftl/FTLCompileBinaryOp.cpp (194125 => 194126)
--- trunk/Source/_javascript_Core/ftl/FTLCompileBinaryOp.cpp 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/ftl/FTLCompileBinaryOp.cpp 2015-12-16 01:05:00 UTC (rev 194126)
@@ -178,7 +178,7 @@
SnippetGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
JSValueRegs(left), JSValueRegs(right), scratchGPR);
- unsigned numberOfBytesUsedToPreserveReusedRegisters =
+ ScratchRegisterAllocator::PreservedState preservedState =
allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
context.initializeRegisters(jit);
@@ -188,14 +188,12 @@
gen.endJumpList().link(&jit);
context.restoreRegisters(jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
- ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
done = jit.jump();
gen.slowPathJumpList().link(&jit);
context.restoreRegisters(jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
- ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
slowPathStart = jit.jump();
}
@@ -214,7 +212,7 @@
JITRightShiftGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
JSValueRegs(left), JSValueRegs(right), leftFPR, scratchGPR, InvalidFPRReg, shiftType);
- unsigned numberOfBytesUsedToPreserveReusedRegisters =
+ ScratchRegisterAllocator::PreservedState preservedState =
allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
context.initializeRegisters(jit);
@@ -223,14 +221,12 @@
ASSERT(gen.didEmitFastPath());
gen.endJumpList().link(&jit);
context.restoreRegisters(jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
- ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
done = jit.jump();
gen.slowPathJumpList().link(&jit);
context.restoreRegisters(jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
- ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
slowPathStart = jit.jump();
}
@@ -253,7 +249,7 @@
BinaryArithOpGenerator gen(ic.leftOperand(), ic.rightOperand(), JSValueRegs(result),
JSValueRegs(left), JSValueRegs(right), leftFPR, rightFPR, scratchGPR, scratchFPR);
- unsigned numberOfBytesUsedToPreserveReusedRegisters =
+ ScratchRegisterAllocator::PreservedState preservedState =
allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
context.initializeRegisters(jit);
@@ -262,14 +258,12 @@
ASSERT(gen.didEmitFastPath());
gen.endJumpList().link(&jit);
context.restoreRegisters(jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
- ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
done = jit.jump();
gen.slowPathJumpList().link(&jit);
context.restoreRegisters(jit);
- allocator.restoreReusedRegistersByPopping(jit, numberOfBytesUsedToPreserveReusedRegisters,
- ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ allocator.restoreReusedRegistersByPopping(jit, preservedState);
slowPathStart = jit.jump();
}
Modified: trunk/Source/_javascript_Core/ftl/FTLLazySlowPath.cpp (194125 => 194126)
--- trunk/Source/_javascript_Core/ftl/FTLLazySlowPath.cpp 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/ftl/FTLLazySlowPath.cpp 2015-12-16 01:05:00 UTC (rev 194126)
@@ -79,7 +79,8 @@
params.lazySlowPath = this;
#if !FTL_USES_B3
- unsigned bytesSaved = m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ ScratchRegisterAllocator::PreservedState preservedState =
+ m_scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
// This is needed because LLVM may create a stackmap location that is the register SP.
// But on arm64, SP is also the same register number as ZR, so LLVM is telling us that it has
// proven something is zero. Our MASM isn't universally compatible with arm64's context dependent
@@ -94,9 +95,9 @@
#if !FTL_USES_B3
CCallHelpers::Label doneLabel;
CCallHelpers::Jump jumpToEndOfPatchpoint;
- if (bytesSaved) {
+ if (preservedState.numberOfBytesPreserved) {
doneLabel = jit.label();
- m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesSaved, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+ m_scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
jumpToEndOfPatchpoint = jit.jump();
}
#endif // !FTL_USES_B3
@@ -105,7 +106,7 @@
#if FTL_USES_B3
linkBuffer.link(params.doneJumps, m_done);
#else // FTL_USES_B3
- if (bytesSaved) {
+ if (preservedState.numberOfBytesPreserved) {
linkBuffer.link(params.doneJumps, linkBuffer.locationOf(doneLabel));
linkBuffer.link(jumpToEndOfPatchpoint, m_patchpoint.labelAtOffset(MacroAssembler::maxJumpReplacementSize()));
} else
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (194125 => 194126)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-12-16 01:05:00 UTC (rev 194126)
@@ -9342,7 +9342,7 @@
GPRReg scratch1 = scratchRegisterAllocator.allocateScratchGPR();
GPRReg scratch2 = scratchRegisterAllocator.allocateScratchGPR();
- unsigned bytesPushed =
+ ScratchRegisterAllocator::PreservedState preservedState =
scratchRegisterAllocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
// We've already saved these, so when we make a slow path call, we don't have
@@ -9365,7 +9365,7 @@
scratch1, scratch2, CCallHelpers::ScalePtr,
static_cast<int32_t>(-sizeof(void*))));
- scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+ scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
params.doneJumps.append(jit.jump());
@@ -9374,7 +9374,7 @@
usedRegisters, jit, params.lazySlowPath->callSiteIndex(),
params.exceptionJumps, operationFlushWriteBarrierBuffer, InvalidGPRReg,
baseGPR);
- scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, bytesPushed, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
+ scratchRegisterAllocator.restoreReusedRegistersByPopping(jit, preservedState);
params.doneJumps.append(jit.jump());
});
},
Modified: trunk/Source/_javascript_Core/jit/ScratchRegisterAllocator.cpp (194125 => 194126)
--- trunk/Source/_javascript_Core/jit/ScratchRegisterAllocator.cpp 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/jit/ScratchRegisterAllocator.cpp 2015-12-16 01:05:00 UTC (rev 194126)
@@ -102,10 +102,10 @@
GPRReg ScratchRegisterAllocator::allocateScratchGPR() { return allocateScratch<GPRInfo>(); }
FPRReg ScratchRegisterAllocator::allocateScratchFPR() { return allocateScratch<FPRInfo>(); }
-unsigned ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace extraStackSpace)
+ScratchRegisterAllocator::PreservedState ScratchRegisterAllocator::preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace extraStackSpace)
{
if (!didReuseRegisters())
- return 0;
+ return PreservedState(0, extraStackSpace);
RegisterSet registersToSpill;
for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
@@ -122,10 +122,10 @@
unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
unsigned stackAdjustmentSize = ScratchRegisterAllocator::preserveRegistersToStackForCall(jit, registersToSpill, extraStackBytesAtTopOfStack);
- return stackAdjustmentSize;
+ return PreservedState(stackAdjustmentSize, extraStackSpace);
}
-void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace extraStackSpace)
+void ScratchRegisterAllocator::restoreReusedRegistersByPopping(MacroAssembler& jit, const ScratchRegisterAllocator::PreservedState preservedState)
{
if (!didReuseRegisters())
return;
@@ -142,9 +142,11 @@
registersToFill.set(reg);
}
- unsigned extraStackBytesAtTopOfStack = extraStackSpace == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
+ unsigned extraStackBytesAtTopOfStack =
+ preservedState.extraStackSpaceRequirement == ExtraStackSpace::SpaceForCCall ? maxFrameExtentForSlowPathCall : 0;
RegisterSet dontRestore; // Empty set. We want to restore everything.
- ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore, numberOfBytesUsedToPreserveReusedRegisters, extraStackBytesAtTopOfStack);
+ ScratchRegisterAllocator::restoreRegistersFromStackForCall(jit, registersToFill, dontRestore,
+ preservedState.numberOfBytesPreserved, extraStackBytesAtTopOfStack);
}
RegisterSet ScratchRegisterAllocator::usedRegistersForCall() const
Modified: trunk/Source/_javascript_Core/jit/ScratchRegisterAllocator.h (194125 => 194126)
--- trunk/Source/_javascript_Core/jit/ScratchRegisterAllocator.h 2015-12-16 00:55:49 UTC (rev 194125)
+++ trunk/Source/_javascript_Core/jit/ScratchRegisterAllocator.h 2015-12-16 01:05:00 UTC (rev 194126)
@@ -67,8 +67,23 @@
RegisterSet usedRegisters() const { return m_usedRegisters; }
enum class ExtraStackSpace { SpaceForCCall, NoExtraSpace };
- unsigned preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace);
- void restoreReusedRegistersByPopping(MacroAssembler& jit, unsigned numberOfBytesUsedToPreserveReusedRegisters, ExtraStackSpace);
+
+ struct PreservedState {
+ PreservedState()
+ : PreservedState(0)
+ { }
+
+ PreservedState(unsigned numberOfBytes, ExtraStackSpace extraStackSpace = ExtraStackSpace::NoExtraSpace)
+ : numberOfBytesPreserved(numberOfBytes)
+ , extraStackSpaceRequirement(extraStackSpace)
+ { }
+
+ unsigned numberOfBytesPreserved;
+ ExtraStackSpace extraStackSpaceRequirement;
+ };
+
+ PreservedState preserveReusedRegistersByPushing(MacroAssembler& jit, ExtraStackSpace);
+ void restoreReusedRegistersByPopping(MacroAssembler& jit, PreservedState);
RegisterSet usedRegistersForCall() const;