Commit 1a5f13c8 authored by msaboff@apple.com's avatar msaboff@apple.com

Add local to/from operand helpers similar to argument to/from operand2

https://bugs.webkit.org/show_bug.cgi?id=121056

Reviewed by Geoffrey Garen.

Added localToOperand(), operandToLocal() and operandIsLocal() to Operands.h, very similar to
argumentToOperand(), et al.  Used the new helpers everywhere where an index into a data
structure is intended instead of the actual virtual register offset.  When the stack is
changed to grow down, local register offsets can be negative.  Also added the helper
DFG::SpeculativeJIT::generationInfoFromVirtualRegister() for the common case accessing 
m_generationInfo[operandToLocal(val)].

* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* bytecode/Operands.h:
(JSC::localToOperand):
(JSC::operandIsLocal):
(JSC::operandToLocal):
* bytecompiler/BytecodeGenerator.h:
* dfg/DFGAbstractInterpreterInlines.h:
* dfg/DFGByteCodeParser.cpp:
* dfg/DFGCFGSimplificationPhase.cpp:
* dfg/DFGCPSRethreadingPhase.cpp:
* dfg/DFGOSREntry.cpp:
* dfg/DFGOSRExitCompiler32_64.cpp:
* dfg/DFGOSRExitCompiler64.cpp:
* dfg/DFGScoreBoard.h:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::generationInfoFromVirtualRegister):
* dfg/DFGSpeculativeJIT32_64.cpp:
* dfg/DFGSpeculativeJIT64.cpp:
* dfg/DFGValidate.cpp:
* dfg/DFGVariableEventStream.cpp:
* dfg/DFGVirtualRegisterAllocationPhase.cpp:
* jit/JITInlines.h:
* jit/JITOpcodes.cpp:
* jit/JITOpcodes32_64.cpp:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@155415 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a34e5223
2013-09-09 Michael Saboff <msaboff@apple.com>
Add local to/from operand helpers similar to argument to/from operand2
https://bugs.webkit.org/show_bug.cgi?id=121056
Reviewed by Geoffrey Garen.
Added localToOperand(), operandToLocal() and operandIsLocal() to Operands.h, very similar to
argumentToOperand(), et al. Used the new helpers everywhere where an index into a data
structure is intended instead of the actual virtual register offset. When the stack is
changed to grow down, local register offsets can be negative. Also added the helper
DFG::SpeculativeJIT::generationInfoFromVirtualRegister() for the common case accessing
m_generationInfo[operandToLocal(val)].
* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
* bytecode/Operands.h:
(JSC::localToOperand):
(JSC::operandIsLocal):
(JSC::operandToLocal):
* bytecompiler/BytecodeGenerator.h:
* dfg/DFGAbstractInterpreterInlines.h:
* dfg/DFGByteCodeParser.cpp:
* dfg/DFGCFGSimplificationPhase.cpp:
* dfg/DFGCPSRethreadingPhase.cpp:
* dfg/DFGOSREntry.cpp:
* dfg/DFGOSRExitCompiler32_64.cpp:
* dfg/DFGOSRExitCompiler64.cpp:
* dfg/DFGScoreBoard.h:
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::generationInfoFromVirtualRegister):
* dfg/DFGSpeculativeJIT32_64.cpp:
* dfg/DFGSpeculativeJIT64.cpp:
* dfg/DFGValidate.cpp:
* dfg/DFGVariableEventStream.cpp:
* dfg/DFGVirtualRegisterAllocationPhase.cpp:
* jit/JITInlines.h:
* jit/JITOpcodes.cpp:
* jit/JITOpcodes32_64.cpp:
2013-09-09 Filip Pizlo <fpizlo@apple.com>
Unreviewed, disable GC logging.
......
......@@ -171,7 +171,7 @@ CString CodeBlock::registerName(int r) const
return toCString("arg", operandToArgument(r));
}
return toCString("loc", r);
return toCString("loc", operandToLocal(r));
}
static CString regexpToSourceString(RegExp* regExp)
......
......@@ -367,7 +367,7 @@ public:
return operandToArgument(operand) && usesArguments();
if (inlineCallFrame)
return inlineCallFrame->capturedVars.get(operand);
return inlineCallFrame->capturedVars.get(operandToLocal(operand));
// The activation object isn't in the captured region, but it's "captured"
// in the sense that stores to its location can be observed indirectly.
......
......@@ -28,11 +28,16 @@
#include "CallFrame.h"
#include "JSObject.h"
#include "VirtualRegister.h"
#include <wtf/PrintStream.h>
#include <wtf/Vector.h>
namespace JSC {
inline VirtualRegister localToOperand(int local) { return (VirtualRegister)local; }
inline bool operandIsLocal(int operand) { return operand >= 0; }
inline int operandToLocal(int operand) { return operand; }
// argument 0 is 'this'.
inline bool operandIsArgument(int operand) { return operand < 0; }
inline int operandToArgument(int operand) { return -operand + CallFrame::thisArgumentOffset(); }
......@@ -143,7 +148,7 @@ public:
return m_arguments[argument];
}
return m_locals[operand];
return m_locals[operandToLocal(operand)];
}
const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
......@@ -152,7 +157,7 @@ public:
{
if (operandIsArgument(operand))
return true;
return static_cast<size_t>(operand) < numberOfLocals();
return static_cast<size_t>(operandToLocal(operand)) < numberOfLocals();
}
void setOperand(int operand, const T& value)
......@@ -163,7 +168,7 @@ public:
return;
}
setLocal(operand, value);
setLocal(operandToLocal(operand), value);
}
size_t size() const { return numberOfArguments() + numberOfLocals(); }
......@@ -196,7 +201,7 @@ public:
{
if (index < numberOfArguments())
return argumentToOperand(index);
return index - numberOfArguments();
return localToOperand(index - numberOfArguments());
}
void setOperandFirstTime(int operand, const T& value)
......@@ -206,7 +211,7 @@ public:
return;
}
setLocalFirstTime(operand, value);
setLocalFirstTime(operandToLocal(operand), value);
}
void fill(T value)
......
......@@ -498,14 +498,14 @@ namespace JSC {
RegisterID& registerFor(int index)
{
if (index >= 0)
return m_calleeRegisters[index];
if (operandIsLocal(index))
return m_calleeRegisters[operandToLocal(index)];
if (index == JSStack::Callee)
return m_calleeRegister;
ASSERT(m_parameters.size());
return m_parameters[index + m_parameters.size() + JSStack::CallFrameHeaderSize];
return m_parameters[operandToArgument(index)];
}
unsigned addConstant(const Identifier&);
......
......@@ -154,7 +154,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
case ExtractOSREntryLocal: {
forNode(node).makeTop();
if (!operandIsArgument(node->unlinkedLocal())
&& m_graph.m_lazyVars.get(node->unlinkedLocal())) {
&& m_graph.m_lazyVars.get(operandToLocal(node->unlinkedLocal()))) {
// This is kind of pessimistic - we could know in some cases that the
// DFG code at the point of the OSR had already initialized the lazy
// variable. But maybe this is fine, since we're inserting OSR
......@@ -1598,7 +1598,7 @@ void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigi
}
} else {
for (size_t i = m_codeBlock->m_numVars; i--;) {
if (m_codeBlock->isCaptured(i))
if (m_codeBlock->isCaptured(localToOperand(i)))
m_state.variables().local(i).makeTop();
}
}
......
......@@ -261,7 +261,8 @@ private:
// Used in implementing get/set, above, where the operand is a local variable.
Node* getLocal(unsigned operand)
{
Node* node = m_currentBlock->variablesAtTail.local(operand);
unsigned local = operandToLocal(operand);
Node* node = m_currentBlock->variablesAtTail.local(local);
bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
// This has two goals: 1) link together variable access datas, and 2)
......@@ -287,16 +288,17 @@ private:
}
}
} else {
m_preservedVars.set(operand);
m_preservedVars.set(local);
variable = newVariableAccessData(operand, isCaptured);
}
node = injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(variable)));
m_currentBlock->variablesAtTail.local(operand) = node;
m_currentBlock->variablesAtTail.local(local) = node;
return node;
}
void setLocal(unsigned operand, Node* value, SetMode setMode = NormalSet)
{
unsigned local = operandToLocal(operand);
bool isCaptured = m_codeBlock->isCaptured(operand, inlineCallFrame());
if (setMode == NormalSet) {
......@@ -311,7 +313,7 @@ private:
variableAccessData->mergeCheckArrayHoistingFailed(
m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType));
Node* node = addToGraph(SetLocal, OpInfo(variableAccessData), value);
m_currentBlock->variablesAtTail.local(operand) = node;
m_currentBlock->variablesAtTail.local(local) = node;
}
// Used in implementing get/set, above, where the operand is an argument.
......@@ -431,7 +433,7 @@ private:
ASSERT(operand < FirstConstantRegisterIndex);
if (!operandIsArgument(operand))
m_preservedVars.set(operand);
m_preservedVars.set(operandToLocal(operand));
Node* node = m_currentBlock->variablesAtTail.operand(operand);
......@@ -459,9 +461,9 @@ private:
for (unsigned argument = numArguments; argument-- > 1;)
flushDirect(inlineStackEntry->remapOperand(argumentToOperand(argument)));
for (int local = 0; local < inlineStackEntry->m_codeBlock->m_numVars; ++local) {
if (!inlineStackEntry->m_codeBlock->isCaptured(local))
if (!inlineStackEntry->m_codeBlock->isCaptured(localToOperand(local)))
continue;
flushDirect(inlineStackEntry->remapOperand(local));
flushDirect(inlineStackEntry->remapOperand(localToOperand(local)));
}
}
......@@ -1280,11 +1282,11 @@ bool ByteCodeParser::handleInlining(Node* callTargetNode, int resultOperand, con
int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - JSStack::CallFrameHeaderSize;
// Make sure that the area used by the call frame is reserved.
for (int arg = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numVars; arg-- > inlineCallFrameStart;)
for (int arg = operandToLocal(inlineCallFrameStart) + JSStack::CallFrameHeaderSize + codeBlock->m_numVars; arg-- > operandToLocal(inlineCallFrameStart);)
m_preservedVars.set(arg);
// Make sure that we have enough locals.
unsigned newNumLocals = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
unsigned newNumLocals = operandToLocal(inlineCallFrameStart) + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
if (newNumLocals > m_numLocals) {
m_numLocals = newNumLocals;
for (size_t i = 0; i < m_graph.numBlocks(); ++i)
......@@ -1884,7 +1886,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_enter:
// Initialize all locals to undefined.
for (int i = 0; i < m_inlineStackTop->m_codeBlock->m_numVars; ++i)
set(i, constantUndefined(), SetOnEntry);
set(localToOperand(i), constantUndefined(), SetOnEntry);
NEXT_OPCODE(op_enter);
case op_to_this: {
......@@ -3151,8 +3153,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_init_lazy_reg: {
set(currentInstruction[1].u.operand, getJSConstantForValue(JSValue()));
ASSERT(currentInstruction[1].u.operand >= 0);
m_graph.m_lazyVars.set(currentInstruction[1].u.operand);
ASSERT(operandIsLocal(currentInstruction[1].u.operand));
m_graph.m_lazyVars.set(operandToLocal(currentInstruction[1].u.operand));
NEXT_OPCODE(op_init_lazy_reg);
}
......@@ -3381,18 +3383,19 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
inlineCallFrame.capturedVars = inlineCallFrame.caller.inlineCallFrame->capturedVars;
else {
for (int i = byteCodeParser->m_codeBlock->m_numVars; i--;) {
if (byteCodeParser->m_codeBlock->isCaptured(i))
if (byteCodeParser->m_codeBlock->isCaptured(localToOperand(i)))
inlineCallFrame.capturedVars.set(i);
}
}
for (int i = argumentCountIncludingThis; i--;) {
if (codeBlock->isCaptured(argumentToOperand(i)))
inlineCallFrame.capturedVars.set(argumentToOperand(i) + inlineCallFrame.stackOffset);
inlineCallFrame.capturedVars.set(operandToLocal(argumentToOperand(i) + inlineCallFrame.stackOffset));
}
for (size_t i = codeBlock->m_numVars; i--;) {
if (codeBlock->isCaptured(i))
inlineCallFrame.capturedVars.set(i + inlineCallFrame.stackOffset);
int localOperand = localToOperand(i);
if (codeBlock->isCaptured(localOperand))
inlineCallFrame.capturedVars.set(operandToLocal(localOperand + inlineCallFrame.stackOffset));
}
#if DFG_ENABLE(DEBUG_VERBOSE)
......
......@@ -328,7 +328,7 @@ private:
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i)
keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, argumentToOperand(i));
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i)
keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, i);
keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, localToOperand(i));
fixJettisonedPredecessors(block, jettisonedBlock);
}
......@@ -382,7 +382,7 @@ private:
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i)
keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, argumentToOperand(i));
for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i)
keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, i);
keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, localToOperand(i));
}
for (size_t i = 0; i < secondBlock->phis.size(); ++i)
......
......@@ -220,7 +220,7 @@ private:
if (operandIsArgument(variable->local()))
canonicalizeGetLocalFor<ArgumentOperand>(node, variable, operandToArgument(variable->local()));
else
canonicalizeGetLocalFor<LocalOperand>(node, variable, variable->local());
canonicalizeGetLocalFor<LocalOperand>(node, variable, operandToLocal(variable->local()));
}
void canonicalizeSetLocal(Node* node)
......@@ -288,7 +288,7 @@ private:
if (operandIsArgument(variable->local()))
canonicalizeFlushOrPhantomLocalFor<nodeType, ArgumentOperand>(node, variable, operandToArgument(variable->local()));
else
canonicalizeFlushOrPhantomLocalFor<nodeType, LocalOperand>(node, variable, variable->local());
canonicalizeFlushOrPhantomLocalFor<nodeType, LocalOperand>(node, variable, operandToLocal(variable->local()));
}
void canonicalizeSetArgument(Node* node)
......
......@@ -139,21 +139,21 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
for (size_t local = 0; local < entry->m_expectedValues.numberOfLocals(); ++local) {
if (entry->m_localsForcedDouble.get(local)) {
if (!exec->registers()[local].jsValue().isNumber()) {
if (!exec->registers()[localToOperand(local)].jsValue().isNumber()) {
if (Options::verboseOSR()) {
dataLog(
" OSR failed because variable ", local, " is ",
exec->registers()[local].jsValue(), ", expected number.\n");
" OSR failed because variable ", localToOperand(local), " is ",
exec->registers()[localToOperand(local)].jsValue(), ", expected number.\n");
}
return 0;
}
continue;
}
if (!entry->m_expectedValues.local(local).validate(exec->registers()[local].jsValue())) {
if (!entry->m_expectedValues.local(local).validate(exec->registers()[localToOperand(local)].jsValue())) {
if (Options::verboseOSR()) {
dataLog(
" OSR failed because variable ", local, " is ",
exec->registers()[local].jsValue(), ", expected ",
" OSR failed because variable ", localToOperand(local), " is ",
exec->registers()[localToOperand(local)].jsValue(), ", expected ",
entry->m_expectedValues.local(local), ".\n");
}
return 0;
......@@ -179,7 +179,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
// 3) Perform data format conversions.
for (size_t local = 0; local < entry->m_expectedValues.numberOfLocals(); ++local) {
if (entry->m_localsForcedDouble.get(local))
*bitwise_cast<double*>(exec->registers() + local) = exec->registers()[local].jsValue().asNumber();
*bitwise_cast<double*>(exec->registers() + localToOperand(local)) = exec->registers()[localToOperand(local)].jsValue().asNumber();
}
// 4) Fix the call frame.
......
......@@ -199,9 +199,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
case DisplacedInJSStack:
case Int32DisplacedInJSStack:
case CellDisplacedInJSStack:
case BooleanDisplacedInJSStack:
case BooleanDisplacedInJSStack: {
numberOfDisplacedVirtualRegisters++;
ASSERT((int)recovery.virtualRegister() >= 0);
ASSERT(operandIsLocal(recovery.virtualRegister()));
// See if we might like to store to this virtual register before doing
// virtual register shuffling. If so, we say that the virtual register
......@@ -210,16 +210,17 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
// to ensure this happens efficiently. Note that we expect this case
// to be rare, so the handling of it is optimized for the cases in
// which it does not happen.
if (recovery.virtualRegister() < (int)operands.numberOfLocals()) {
switch (operands.local(recovery.virtualRegister()).technique()) {
int local = operandToLocal(recovery.virtualRegister());
if (local < (int)operands.numberOfLocals()) {
switch (operands.local(local).technique()) {
case InGPR:
case UnboxedInt32InGPR:
case UnboxedBooleanInGPR:
case UInt32InGPR:
case InPair:
case InFPR:
if (!poisonedVirtualRegisters[recovery.virtualRegister()]) {
poisonedVirtualRegisters[recovery.virtualRegister()] = true;
if (!poisonedVirtualRegisters[local]) {
poisonedVirtualRegisters[local] = true;
numberOfPoisonedVirtualRegisters++;
}
break;
......@@ -228,7 +229,8 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
}
}
break;
}
case UInt32InGPR:
haveUInt32s = true;
break;
......@@ -543,7 +545,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
case UnboxedInt32InGPR:
case UnboxedBooleanInGPR: {
m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + poisonIndex(virtualRegister)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), GPRInfo::regT0);
m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor((VirtualRegister)virtualRegister));
m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(localToOperand(virtualRegister)));
uint32_t tag = JSValue::EmptyValueTag;
if (recovery.technique() == InGPR)
tag = JSValue::CellTag;
......@@ -551,7 +553,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
tag = JSValue::Int32Tag;
else
tag = JSValue::BooleanTag;
m_jit.store32(AssemblyHelpers::TrustedImm32(tag), AssemblyHelpers::tagFor((VirtualRegister)virtualRegister));
m_jit.store32(AssemblyHelpers::TrustedImm32(tag), AssemblyHelpers::tagFor(localToOperand(virtualRegister)));
break;
}
......@@ -560,8 +562,8 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
case UInt32InGPR:
m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + poisonIndex(virtualRegister)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), GPRInfo::regT0);
m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + poisonIndex(virtualRegister)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag), GPRInfo::regT1);
m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor((VirtualRegister)virtualRegister));
m_jit.store32(GPRInfo::regT1, AssemblyHelpers::tagFor((VirtualRegister)virtualRegister));
m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(localToOperand(virtualRegister)));
m_jit.store32(GPRInfo::regT1, AssemblyHelpers::tagFor(localToOperand(virtualRegister)));
break;
default:
......
......@@ -180,9 +180,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
switch (recovery.technique()) {
case Int32DisplacedInJSStack:
case DoubleDisplacedInJSStack:
case DisplacedInJSStack:
case DisplacedInJSStack: {
numberOfDisplacedVirtualRegisters++;
ASSERT((int)recovery.virtualRegister() >= 0);
ASSERT(operandIsLocal(recovery.virtualRegister()));
// See if we might like to store to this virtual register before doing
// virtual register shuffling. If so, we say that the virtual register
......@@ -191,14 +191,15 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
// to ensure this happens efficiently. Note that we expect this case
// to be rare, so the handling of it is optimized for the cases in
// which it does not happen.
if (recovery.virtualRegister() < (int)operands.numberOfLocals()) {
switch (operands.local(recovery.virtualRegister()).technique()) {
int local = operandToLocal(recovery.virtualRegister());
if (local < (int)operands.numberOfLocals()) {
switch (operands.local(local).technique()) {
case InGPR:
case UnboxedInt32InGPR:
case UInt32InGPR:
case InFPR:
if (!poisonedVirtualRegisters[recovery.virtualRegister()]) {
poisonedVirtualRegisters[recovery.virtualRegister()] = true;
if (!poisonedVirtualRegisters[local]) {
poisonedVirtualRegisters[local] = true;
numberOfPoisonedVirtualRegisters++;
}
break;
......@@ -207,7 +208,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
}
}
break;
}
case UnboxedInt32InGPR:
case AlreadyInJSStackAsUnboxedInt32:
haveUnboxedInt32s = true;
......@@ -530,7 +531,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov
case UInt32InGPR:
case InFPR:
m_jit.load64(scratchDataBuffer + poisonIndex(virtualRegister), GPRInfo::regT0);
m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor((VirtualRegister)virtualRegister));
m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(localToOperand(virtualRegister)));
break;
default:
......
......@@ -89,25 +89,25 @@ public:
// Use count must have hit zero for it to have been added to the free list!
ASSERT(!m_used[index]);
m_highWatermark = std::max(m_highWatermark, static_cast<unsigned>(index) + 1);
return (VirtualRegister)index;
return localToOperand(index);
}
// Allocate a new VirtualRegister, and add a corresponding entry to m_used.
size_t next = m_used.size();
m_used.append(0);
m_highWatermark = std::max(m_highWatermark, static_cast<unsigned>(next) + 1);
return (VirtualRegister)next;
return localToOperand(next);
}
// Increment the usecount for the VirtualRegsiter associated with 'child',
// if it reaches the node's refcount, free the VirtualRegsiter.
// Increment the usecount for the VirtualRegister associated with 'child',
// if it reaches the node's refcount, free the VirtualRegister.
void use(Node* child)
{
if (!child)
return;
// Find the virtual register number for this child, increment its use count.
uint32_t index = child->virtualRegister();
uint32_t index = operandToLocal(child->virtualRegister());
ASSERT(m_used[index] != max());
if (child->refCount() == ++m_used[index]) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
......
......@@ -317,7 +317,7 @@ void SpeculativeJIT::clearGenerationInfo()
SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source)
{
GenerationInfo& info = m_generationInfo[spillMe];
GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
Node* node = info.node();
DataFormat registerFormat = info.registerFormat();
ASSERT(registerFormat != DataFormatNone);
......@@ -436,7 +436,7 @@ SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForGPR(VirtualRegister spil
SilentRegisterSavePlan SpeculativeJIT::silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source)
{
GenerationInfo& info = m_generationInfo[spillMe];
GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
Node* node = info.node();
ASSERT(info.registerFormat() == DataFormatDouble);
......@@ -777,7 +777,7 @@ void SpeculativeJIT::arrayify(Node* node)
GPRReg SpeculativeJIT::fillStorage(Edge edge)
{
VirtualRegister virtualRegister = edge->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
switch (info.registerFormat()) {
case DataFormatNone: {
......@@ -1076,7 +1076,7 @@ void SpeculativeJIT::checkConsistency()
for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
VirtualRegister virtualRegister = (VirtualRegister)i;
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
if (!info.alive())
continue;
switch (info.registerFormat()) {
......@@ -1124,7 +1124,7 @@ void SpeculativeJIT::checkConsistency()
if (virtualRegister == InvalidVirtualRegister)
continue;
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
#if USE(JSVALUE64)
if (iter.regID() != info.gpr()) {
dataLogF("DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
......@@ -1150,7 +1150,7 @@ void SpeculativeJIT::checkConsistency()
if (virtualRegister == InvalidVirtualRegister)
continue;
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
if (iter.regID() != info.fpr()) {
dataLogF("DFG_CONSISTENCY_CHECK failed: name mismatch for fpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
failed = true;
......@@ -1548,7 +1548,7 @@ void SpeculativeJIT::noticeOSRBirth(Node* node)
return;
VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
info.noticeOSRBirth(*m_stream, node, virtualRegister);
}
......@@ -1681,7 +1681,7 @@ void SpeculativeJIT::compileCurrentBlock()
valueSource = ValueSource::forSpeculation(node->variableAccessData()->argumentAwarePrediction());
m_variables[i] = valueSource;
// FIXME: Don't emit SetLocal(Dead). https://bugs.webkit.org/show_bug.cgi?id=108019
m_stream->appendAndLog(VariableEvent::setLocal(i, valueSource.dataFormat()));
m_stream->appendAndLog(VariableEvent::setLocal(localToOperand(i), valueSource.dataFormat()));
}
m_lastSetOperand = std::numeric_limits<int>::max();
......@@ -2176,7 +2176,7 @@ GeneratedOperandType SpeculativeJIT::checkGeneratedTypeForToInt32(Node* node)
dataLogF("checkGeneratedTypeForToInt32@%d ", node->index());
#endif
VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
switch (info.registerFormat()) {
case DataFormatStorage:
......@@ -2290,7 +2290,7 @@ void SpeculativeJIT::compileValueToInt32(Node* node)
#else
Node* childNode = node->child1().node();
VirtualRegister virtualRegister = childNode->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
......
......@@ -161,7 +161,7 @@ public:
bool canReuse(Node* node)
{
VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
return info.canReuse();
}
bool canReuse(Edge nodeUse)
......@@ -189,7 +189,7 @@ public:
GPRReg gpr = m_gprs.allocate(spillMe);
if (spillMe != InvalidVirtualRegister) {
#if USE(JSVALUE32_64)
GenerationInfo& info = m_generationInfo[spillMe];
GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
if ((info.registerFormat() & DataFormatJS))
m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
......@@ -206,7 +206,7 @@ public:
VirtualRegister spillMe = m_gprs.allocateSpecific(specific);
if (spillMe != InvalidVirtualRegister) {
#if USE(JSVALUE32_64)
GenerationInfo& info = m_generationInfo[spillMe];
GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
if ((info.registerFormat() & DataFormatJS))
m_gprs.release(info.tagGPR() == specific ? info.payloadGPR() : info.tagGPR());
......@@ -239,13 +239,13 @@ public:
bool isFilled(Node* node)
{
VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
return info.registerFormat() != DataFormatNone;
}
bool isFilledDouble(Node* node)
{
VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
return info.registerFormat() == DataFormatDouble;
}
......@@ -255,7 +255,7 @@ public:
if (!node->hasResult())
return;
VirtualRegister virtualRegister = node->virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);