summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-10-15 16:08:57 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-15 16:08:57 +0200
commit5466563f4b5b6b86523e3f89bb7f77e5b5270c78 (patch)
tree8caccf7cd03a15207cde3ba282c88bf132482a91 /Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
parent33b26980cb24288b5a9f2590ccf32a949281bb79 (diff)
downloadqtwebkit-5466563f4b5b6b86523e3f89bb7f77e5b5270c78.tar.gz
Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)
WebKit update which introduces the QtWebKitWidgets module that contains the WK1 widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're working on completing the entire split as part of https://bugs.webkit.org/show_bug.cgi?id=99314
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp140
1 files changed, 120 insertions, 20 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 6d5f68200..dc668d93e 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -43,6 +43,76 @@
namespace JSC { namespace DFG {
+class ConstantBufferKey {
+public:
+ ConstantBufferKey()
+ : m_codeBlock(0)
+ , m_index(0)
+ {
+ }
+
+ ConstantBufferKey(WTF::HashTableDeletedValueType)
+ : m_codeBlock(0)
+ , m_index(1)
+ {
+ }
+
+ ConstantBufferKey(CodeBlock* codeBlock, unsigned index)
+ : m_codeBlock(codeBlock)
+ , m_index(index)
+ {
+ }
+
+ bool operator==(const ConstantBufferKey& other) const
+ {
+ return m_codeBlock == other.m_codeBlock
+ && m_index == other.m_index;
+ }
+
+ unsigned hash() const
+ {
+ return WTF::PtrHash<CodeBlock*>::hash(m_codeBlock) ^ m_index;
+ }
+
+ bool isHashTableDeletedValue() const
+ {
+ return !m_codeBlock && m_index;
+ }
+
+ CodeBlock* codeBlock() const { return m_codeBlock; }
+ unsigned index() const { return m_index; }
+
+private:
+ CodeBlock* m_codeBlock;
+ unsigned m_index;
+};
+
+struct ConstantBufferKeyHash {
+ static unsigned hash(const ConstantBufferKey& key) { return key.hash(); }
+ static bool equal(const ConstantBufferKey& a, const ConstantBufferKey& b)
+ {
+ return a == b;
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::DFG
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::DFG::ConstantBufferKey> {
+ typedef JSC::DFG::ConstantBufferKeyHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::DFG::ConstantBufferKey> : SimpleClassHashTraits<JSC::DFG::ConstantBufferKey> { };
+
+} // namespace WTF
+
+namespace JSC { namespace DFG {
+
// === ByteCodeParser ===
//
// This class is used to compile the dataflow graph from a CodeBlock.
@@ -142,7 +212,7 @@ private:
return getJSConstant(constant);
}
- if (operand == RegisterFile::Callee)
+ if (operand == JSStack::Callee)
return getCallee();
// Is this an argument?
@@ -227,7 +297,10 @@ private:
if (nodePtr->op() == GetLocal)
nodeIndex = nodePtr->child1().index();
- return injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
+ NodeIndex newGetLocal = injectLazyOperandSpeculation(
+ addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex));
+ m_currentBlock->variablesAtTail.local(operand) = newGetLocal;
+ return newGetLocal;
}
if (nodePtr->op() == GetLocal)
@@ -366,11 +439,11 @@ private:
InlineCallFrame* inlineCallFrame = stack->m_inlineCallFrame;
if (!inlineCallFrame)
break;
- if (operand >= static_cast<int>(inlineCallFrame->stackOffset - RegisterFile::CallFrameHeaderSize))
+ if (operand >= static_cast<int>(inlineCallFrame->stackOffset - JSStack::CallFrameHeaderSize))
continue;
if (operand == inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset())
continue;
- if (operand < static_cast<int>(inlineCallFrame->stackOffset - RegisterFile::CallFrameHeaderSize - inlineCallFrame->arguments.size()))
+ if (operand < static_cast<int>(inlineCallFrame->stackOffset - JSStack::CallFrameHeaderSize - inlineCallFrame->arguments.size()))
continue;
int argument = operandToArgument(operand - inlineCallFrame->stackOffset);
return stack->m_argumentPositions[argument];
@@ -669,9 +742,9 @@ private:
{
HashMap<JSCell*, NodeIndex>::AddResult result = m_cellConstantNodes.add(cell, NoNode);
if (result.isNewEntry)
- result.iterator->second = addToGraph(WeakJSConstant, OpInfo(cell));
+ result.iterator->value = addToGraph(WeakJSConstant, OpInfo(cell));
- return result.iterator->second;
+ return result.iterator->value;
}
CodeOrigin currentCodeOrigin()
@@ -758,8 +831,8 @@ private:
addVarArgChild(get(currentInstruction[1].u.operand));
int argCount = currentInstruction[2].u.operand;
- if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)
- m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;
+ if (JSStack::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)
+ m_parameterSlots = JSStack::CallFrameHeaderSize + argCount;
int registerOffset = currentInstruction[3].u.operand;
int dummyThisArgument = op == Call ? 0 : 1;
@@ -1049,6 +1122,8 @@ private:
Vector<PhiStackEntry, 16> m_argumentPhiStack;
Vector<PhiStackEntry, 16> m_localPhiStack;
+ HashMap<ConstantBufferKey, unsigned> m_constantBufferCache;
+
struct InlineStackEntry {
ByteCodeParser* m_byteCodeParser;
@@ -1067,6 +1142,7 @@ private:
// direct, caller).
Vector<unsigned> m_identifierRemap;
Vector<unsigned> m_constantRemap;
+ Vector<unsigned> m_constantBufferRemap;
// Blocks introduced by this code block, which need successor linking.
// May include up to one basic block that includes the continuation after
@@ -1139,7 +1215,7 @@ private:
return result;
}
- if (operand == RegisterFile::Callee)
+ if (operand == JSStack::Callee)
return m_calleeVR;
return operand + m_inlineCallFrame->stackOffset;
@@ -1361,14 +1437,14 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c
// FIXME: Don't flush constants!
- int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - RegisterFile::CallFrameHeaderSize;
+ int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - JSStack::CallFrameHeaderSize;
// Make sure that the area used by the call frame is reserved.
- for (int arg = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize + codeBlock->m_numVars; arg-- > inlineCallFrameStart;)
+ for (int arg = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numVars; arg-- > inlineCallFrameStart;)
m_preservedVars.set(arg);
// Make sure that we have enough locals.
- unsigned newNumLocals = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
+ unsigned newNumLocals = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
if (newNumLocals > m_numLocals) {
m_numLocals = newNumLocals;
for (size_t i = 0; i < m_graph.m_blocks.size(); ++i)
@@ -1571,6 +1647,8 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
case Array::ArrayWithArrayStorageToHole:
ASSERT_NOT_REACHED();
+ case Array::ArrayWithContiguous:
+ case Array::ArrayWithContiguousOutOfBounds:
case Array::ArrayWithArrayStorage:
case Array::ArrayWithArrayStorageOutOfBounds: {
NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1)));
@@ -1594,6 +1672,8 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins
case Array::ArrayWithArrayStorageToHole:
ASSERT_NOT_REACHED();
+ case Array::ArrayWithContiguous:
+ case Array::ArrayWithContiguousOutOfBounds:
case Array::ArrayWithArrayStorage:
case Array::ArrayWithArrayStorageOutOfBounds: {
NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode), OpInfo(prediction), get(registerOffset + argumentToOperand(0)));
@@ -1868,7 +1948,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
}
case op_create_this: {
- set(currentInstruction[1].u.operand, addToGraph(CreateThis, get(RegisterFile::Callee)));
+ set(currentInstruction[1].u.operand, addToGraph(CreateThis, get(JSStack::Callee)));
NEXT_OPCODE(op_create_this);
}
@@ -1889,7 +1969,7 @@ bool ByteCodeParser::parseBlock(unsigned limit)
case op_new_array_buffer: {
int startConstant = currentInstruction[2].u.operand;
int numConstants = currentInstruction[3].u.operand;
- set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(startConstant), OpInfo(numConstants)));
+ set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(m_inlineStackTop->m_constantBufferRemap[startConstant]), OpInfo(numConstants)));
NEXT_OPCODE(op_new_array_buffer);
}
@@ -2753,8 +2833,8 @@ bool ByteCodeParser::parseBlock(unsigned limit)
addToGraph(CheckArgumentsNotCreated);
unsigned argCount = m_inlineStackTop->m_inlineCallFrame->arguments.size();
- if (RegisterFile::CallFrameHeaderSize + argCount > m_parameterSlots)
- m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;
+ if (JSStack::CallFrameHeaderSize + argCount > m_parameterSlots)
+ m_parameterSlots = JSStack::CallFrameHeaderSize + argCount;
addVarArgChild(get(currentInstruction[1].u.operand)); // callee
addVarArgChild(get(currentInstruction[2].u.operand)); // this
@@ -2775,8 +2855,10 @@ bool ByteCodeParser::parseBlock(unsigned limit)
// Statically speculate for now. It makes sense to let speculate-only jneq_ptr
// support simmer for a while before making it more general, since it's
// already gnarly enough as it is.
+ ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer));
addToGraph(
- CheckFunction, OpInfo(currentInstruction[2].u.jsCell.get()),
+ CheckFunction,
+ OpInfo(actualPointerFor(m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)),
get(currentInstruction[1].u.operand));
addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr)));
LAST_OPCODE(op_jneq_ptr);
@@ -3205,7 +3287,7 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
InlineCallFrame inlineCallFrame;
inlineCallFrame.executable.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), codeBlock->ownerExecutable());
- inlineCallFrame.stackOffset = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize;
+ inlineCallFrame.stackOffset = inlineCallFrameStart + JSStack::CallFrameHeaderSize;
inlineCallFrame.callee.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), callee);
inlineCallFrame.caller = byteCodeParser->currentCodeOrigin();
inlineCallFrame.arguments.resize(argumentCountIncludingThis); // Set the number of arguments including this, but don't configure the value recoveries, yet.
@@ -3242,13 +3324,14 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
+ m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i) {
StringImpl* rep = codeBlock->identifier(i).impl();
IdentifierMap::AddResult result = byteCodeParser->m_identifierMap.add(rep, byteCodeParser->m_codeBlock->numberOfIdentifiers());
if (result.isNewEntry)
byteCodeParser->m_codeBlock->addIdentifier(Identifier(byteCodeParser->m_globalData, rep));
- m_identifierRemap[i] = result.iterator->second;
+ m_identifierRemap[i] = result.iterator->value;
}
for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) {
JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex);
@@ -3266,10 +3349,24 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
byteCodeParser->m_codeBlock->addConstant(value);
byteCodeParser->m_constants.append(ConstantRecord());
}
- m_constantRemap[i] = result.iterator->second;
+ m_constantRemap[i] = result.iterator->value;
}
for (unsigned i = 0; i < codeBlock->numberOfGlobalResolveInfos(); ++i)
byteCodeParser->m_codeBlock->addGlobalResolveInfo(std::numeric_limits<unsigned>::max());
+ for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) {
+ // If we inline the same code block multiple times, we don't want to needlessly
+ // duplicate its constant buffers.
+ HashMap<ConstantBufferKey, unsigned>::iterator iter =
+ byteCodeParser->m_constantBufferCache.find(ConstantBufferKey(codeBlock, i));
+ if (iter != byteCodeParser->m_constantBufferCache.end()) {
+ m_constantBufferRemap[i] = iter->value;
+ continue;
+ }
+ Vector<JSValue>& buffer = codeBlock->constantBufferAsVector(i);
+ unsigned newIndex = byteCodeParser->m_codeBlock->addConstantBuffer(buffer);
+ m_constantBufferRemap[i] = newIndex;
+ byteCodeParser->m_constantBufferCache.add(ConstantBufferKey(codeBlock, i), newIndex);
+ }
m_callsiteBlockHeadNeedsLinking = true;
} else {
@@ -3285,11 +3382,14 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry(
m_identifierRemap.resize(codeBlock->numberOfIdentifiers());
m_constantRemap.resize(codeBlock->numberOfConstantRegisters());
+ m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers());
for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i)
m_identifierRemap[i] = i;
for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i)
m_constantRemap[i] = i + FirstConstantRegisterIndex;
+ for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i)
+ m_constantBufferRemap[i] = i;
m_callsiteBlockHeadNeedsLinking = false;
}