Modified: trunk/Source/WebCore/ChangeLog (169952 => 169953)
--- trunk/Source/WebCore/ChangeLog 2014-06-13 22:24:17 UTC (rev 169952)
+++ trunk/Source/WebCore/ChangeLog 2014-06-13 22:26:52 UTC (rev 169953)
@@ -1,3 +1,31 @@
+2014-06-13 Alex Christensen <[email protected]>
+
+ Make css jit allocator smarter.
+ https://bugs.webkit.org/show_bug.cgi?id=133834
+
+ Reviewed by Benjamin Poulain.
+
+ * cssjit/RegisterAllocator.h:
+ (WebCore::RegisterAllocator::allocateRegister):
+ (WebCore::RegisterAllocator::deallocateRegister):
+ (WebCore::RegisterAllocator::reserveCalleeSavedRegisters):
+ (WebCore::LocalRegister::LocalRegister):
+ (WebCore::RegisterAllocator::RegisterAllocator):
+ Use a Deque for the registers. Allocate from the front and deallocate to the back to cycle the register usage.
+ (WebCore::RegisterAllocator::allocateRegisterWithPreference):
+ (WebCore::LocalRegisterWithPreference::LocalRegisterWithPreference):
+ Added the ability to specify that we prefer a certain register if it is available while allocating.
+ These functions always return a register. It is just a different register than preferred if the preferred register is not available.
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeValueExactMatching):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsActive):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsHovered):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+ Whenever we are allocating a register for the second argument, we should specify that we
+ prefer to have argumentGPR1 to reduce register swapping when preparing for a function call.
+ This cannot be done for argumentGPR0 because elementAddressRegister is argumentGPR0 and it is always allocated.
+
2014-06-13 Jeremy Jones <[email protected]>
set setUsesExternalPlaybackWhileExternalScreenIsActive based on fullscreen mode
Modified: trunk/Source/WebCore/cssjit/RegisterAllocator.h (169952 => 169953)
--- trunk/Source/WebCore/cssjit/RegisterAllocator.h 2014-06-13 22:24:17 UTC (rev 169952)
+++ trunk/Source/WebCore/cssjit/RegisterAllocator.h 2014-06-13 22:26:52 UTC (rev 169953)
@@ -29,7 +29,7 @@
#if ENABLE(CSS_SELECTOR_JIT)
#include <_javascript_Core/MacroAssembler.h>
-#include <wtf/HashSet.h>
+#include <wtf/Deque.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -102,9 +102,9 @@
JSC::MacroAssembler::RegisterID allocateRegister()
{
- auto first = m_registers.begin();
- JSC::MacroAssembler::RegisterID registerID = static_cast<JSC::MacroAssembler::RegisterID>(*first);
- RELEASE_ASSERT(m_registers.remove(first));
+ RELEASE_ASSERT(m_registers.size());
+ JSC::MacroAssembler::RegisterID registerID = m_registers.first();
+ m_registers.removeFirst();
ASSERT(!m_allocatedRegisters.contains(registerID));
m_allocatedRegisters.append(registerID);
return registerID;
@@ -112,10 +112,29 @@
void allocateRegister(JSC::MacroAssembler::RegisterID registerID)
{
- RELEASE_ASSERT(m_registers.remove(registerID));
- ASSERT(!m_allocatedRegisters.contains(registerID));
- m_allocatedRegisters.append(registerID);
+ for (auto it = m_registers.begin(); it != m_registers.end(); ++it) {
+ if (*it == registerID) {
+ m_registers.remove(it);
+ ASSERT(!m_allocatedRegisters.contains(registerID));
+ m_allocatedRegisters.append(registerID);
+ return;
+ }
+ }
+ RELEASE_ASSERT_NOT_REACHED();
}
+
+ JSC::MacroAssembler::RegisterID allocateRegisterWithPreference(JSC::MacroAssembler::RegisterID preferredRegister)
+ {
+ for (auto it = m_registers.begin(); it != m_registers.end(); ++it) {
+ if (*it == preferredRegister) {
+ m_registers.remove(it);
+ ASSERT(!m_allocatedRegisters.contains(preferredRegister));
+ m_allocatedRegisters.append(preferredRegister);
+ return preferredRegister;
+ }
+ }
+ return allocateRegister();
+ }
void deallocateRegister(JSC::MacroAssembler::RegisterID registerID)
{
@@ -123,7 +142,9 @@
// Most allocation/deallocation happen in stack-like order. In the common case, this
// just removes the last item.
m_allocatedRegisters.remove(m_allocatedRegisters.reverseFind(registerID));
- RELEASE_ASSERT(m_registers.add(registerID).isNewEntry);
+ for (auto unallocatedRegister : m_registers)
+ RELEASE_ASSERT(unallocatedRegister != registerID);
+ m_registers.append(registerID);
}
const Vector<JSC::MacroAssembler::RegisterID, calleeSavedRegisterCount>& reserveCalleeSavedRegisters(unsigned count)
@@ -133,7 +154,7 @@
for (unsigned i = 0; i < count; ++i) {
JSC::MacroAssembler::RegisterID registerId = calleeSavedRegisters[i];
m_reservedCalleeSavedRegisters.append(registerId);
- m_registers.add(registerId);
+ m_registers.append(registerId);
}
return m_reservedCalleeSavedRegisters;
}
@@ -161,7 +182,7 @@
}
private:
- HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> m_registers;
+ Deque<JSC::MacroAssembler::RegisterID> m_registers;
Vector<JSC::MacroAssembler::RegisterID, registerCount> m_allocatedRegisters;
Vector<JSC::MacroAssembler::RegisterID, calleeSavedRegisterCount> m_reservedCalleeSavedRegisters;
};
@@ -184,15 +205,28 @@
return m_register;
}
-private:
+protected:
+ explicit LocalRegister(RegisterAllocator& allocator, JSC::MacroAssembler::RegisterID registerID)
+ : m_allocator(allocator)
+ , m_register(registerID)
+ {
+ }
RegisterAllocator& m_allocator;
JSC::MacroAssembler::RegisterID m_register;
};
+class LocalRegisterWithPreference : public LocalRegister {
+public:
+ explicit LocalRegisterWithPreference(RegisterAllocator& allocator, JSC::MacroAssembler::RegisterID preferredRegister)
+ : LocalRegister(allocator, allocator.allocateRegisterWithPreference(preferredRegister))
+ {
+ }
+};
+
inline RegisterAllocator::RegisterAllocator()
{
for (unsigned i = 0; i < WTF_ARRAY_LENGTH(callerSavedRegisters); ++i)
- m_registers.add(callerSavedRegisters[i]);
+ m_registers.append(callerSavedRegisters[i]);
}
inline RegisterAllocator::~RegisterAllocator()
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (169952 => 169953)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2014-06-13 22:24:17 UTC (rev 169952)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2014-06-13 22:26:52 UTC (rev 169953)
@@ -2064,7 +2064,7 @@
void SelectorCodeGenerator::generateElementAttributeValueExactMatching(Assembler::JumpList& failureCases, Assembler::RegisterID currentAttributeAddress, const AtomicString& expectedValue, bool canDefaultToCaseSensitiveValueMatch)
{
- LocalRegister expectedValueRegister(m_registerAllocator);
+ LocalRegisterWithPreference expectedValueRegister(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
m_assembler.move(Assembler::TrustedImmPtr(expectedValue.impl()), expectedValueRegister);
if (canDefaultToCaseSensitiveValueMatch)
@@ -2088,7 +2088,7 @@
FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
functionCall.setFunctionAddress(WTF::equalIgnoringCaseNonNull);
- functionCall.setTwoArguments(expectedValueRegister, valueStringImpl);
+ functionCall.setTwoArguments(valueStringImpl, expectedValueRegister);
failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
skipCaseInsensitiveComparison.link(&m_assembler);
@@ -2097,7 +2097,7 @@
void SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching(Assembler::JumpList& failureCases, Assembler::RegisterID currentAttributeAddress, const AtomicString& expectedValue, bool canDefaultToCaseSensitiveValueMatch, JSC::FunctionPtr caseSensitiveTest, JSC::FunctionPtr caseInsensitiveTest)
{
- LocalRegister expectedValueRegister(m_registerAllocator);
+ LocalRegisterWithPreference expectedValueRegister(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
m_assembler.move(Assembler::TrustedImmPtr(expectedValue.impl()), expectedValueRegister);
if (canDefaultToCaseSensitiveValueMatch) {
@@ -2186,7 +2186,7 @@
failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
} else {
unsigned offsetToCheckingContext = m_stackAllocator.offsetToStackReference(m_checkingContextStackReference);
- Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegister();
+ Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1);
m_assembler.loadPtr(Assembler::Address(Assembler::stackPointerRegister, offsetToCheckingContext), checkingContext);
m_registerAllocator.deallocateRegister(checkingContext);
@@ -2271,7 +2271,7 @@
failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
} else {
if (fragment.relationToRightFragment == FragmentRelation::Rightmost) {
- LocalRegister checkingContext(m_registerAllocator);
+ LocalRegisterWithPreference checkingContext(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
Assembler::Jump notResolvingStyle = jumpIfNotResolvingStyle(checkingContext);
addFlagsToElementStyleFromContext(checkingContext, RenderStyle::NonInheritedFlags::flagIsaffectedByHover());
notResolvingStyle.link(&m_assembler);
@@ -2282,7 +2282,7 @@
failureCases.append(functionCall.callAndBranchOnBooleanReturnValue(Assembler::Zero));
} else {
unsigned offsetToCheckingContext = m_stackAllocator.offsetToStackReference(m_checkingContextStackReference);
- Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegister();
+ Assembler::RegisterID checkingContext = m_registerAllocator.allocateRegisterWithPreference(JSC::GPRInfo::argumentGPR1);
m_assembler.loadPtr(Assembler::Address(Assembler::stackPointerRegister, offsetToCheckingContext), checkingContext);
m_registerAllocator.deallocateRegister(checkingContext);
@@ -2542,7 +2542,7 @@
m_registerAllocator.deallocateRegister(parentElement);
// Setup the counter at 1.
- LocalRegister elementCounter(m_registerAllocator);
+ LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
m_assembler.move(Assembler::TrustedImm32(1), elementCounter);
// Loop over the previous adjacent elements and increment the counter.