diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-07 11:22:47 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-07 11:22:47 +0100 |
commit | cfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch) | |
tree | 24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp | |
parent | 69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff) | |
download | qtwebkit-cfd86b747d32ac22246a1aa908eaa720c63a88c1.tar.gz |
Imported WebKit commit 20271caf2e2c016d5cef40184cddeefeac4f1876 (http://svn.webkit.org/repository/webkit/trunk@133733)
New snapshot that contains all previous fixes as well as build fix for latest QtMultimedia API changes.
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp | 141 |
1 files changed, 55 insertions, 86 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp index 36d18d7b3..70aa2b637 100644 --- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp +++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp @@ -35,7 +35,6 @@ #include "DFGByteCodeCache.h" #include "DFGCapabilities.h" #include "GetByIdStatus.h" -#include "MethodCallLinkStatus.h" #include "PutByIdStatus.h" #include "ResolveGlobalStatus.h" #include <wtf/HashMap.h> @@ -906,15 +905,15 @@ private: return getPrediction(m_graph.size(), m_currentProfilingIndex); } - Array::Mode getArrayMode(ArrayProfile* profile) + ArrayMode getArrayMode(ArrayProfile* profile) { - profile->computeUpdatedPrediction(); - return fromObserved(profile, Array::Read, false); + profile->computeUpdatedPrediction(m_inlineStackTop->m_codeBlock); + return ArrayMode::fromObserved(profile, Array::Read, false); } - Array::Mode getArrayModeAndEmitChecks(ArrayProfile* profile, Array::Action action, NodeIndex base) + ArrayMode getArrayModeAndEmitChecks(ArrayProfile* profile, Array::Action action, NodeIndex base) { - profile->computeUpdatedPrediction(); + profile->computeUpdatedPrediction(m_inlineStackTop->m_codeBlock); #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) if (m_inlineStackTop->m_profiledBlock->numberOfRareCaseProfiles()) @@ -926,9 +925,9 @@ private: m_inlineStackTop->m_profiledBlock->couldTakeSlowCase(m_currentIndex) || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, OutOfBounds); - Array::Mode result = fromObserved(profile, action, makeSafe); + ArrayMode result = ArrayMode::fromObserved(profile, action, makeSafe); - if (profile->hasDefiniteStructure() && benefitsFromStructureCheck(result)) + if (profile->hasDefiniteStructure() && result.benefitsFromStructureCheck()) addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(profile->expectedStructure())), base); return result; @@ -1649,16 +1648,11 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins if (argumentCountIncludingThis != 2) return false; - Array::Mode arrayMode = getArrayMode(m_currentInstruction[5].u.arrayProfile); - switch (arrayMode) { - 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))); + ArrayMode arrayMode = getArrayMode(m_currentInstruction[5].u.arrayProfile); + switch (arrayMode.type()) { + case Array::Contiguous: + case Array::ArrayStorage: { + NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1))); if (usesResult) set(resultOperand, arrayPush); @@ -1674,16 +1668,11 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins if (argumentCountIncludingThis != 1) return false; - Array::Mode arrayMode = getArrayMode(m_currentInstruction[5].u.arrayProfile); - switch (arrayMode) { - 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))); + ArrayMode arrayMode = getArrayMode(m_currentInstruction[5].u.arrayProfile); + switch (arrayMode.type()) { + case Array::Contiguous: + case Array::ArrayStorage: { + NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode.asWord()), OpInfo(prediction), get(registerOffset + argumentToOperand(0))); if (usesResult) set(resultOperand, arrayPop); return true; @@ -1699,9 +1688,6 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins return false; int thisOperand = registerOffset + argumentToOperand(0); - if (!(m_graph[get(thisOperand)].prediction() & SpecString)) - return false; - int indexOperand = registerOffset + argumentToOperand(1); NodeIndex charCode = addToGraph(StringCharCodeAt, OpInfo(Array::String), get(thisOperand), getToInt32(indexOperand)); @@ -1715,9 +1701,6 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins return false; int thisOperand = registerOffset + argumentToOperand(0); - if (!(m_graph[get(thisOperand)].prediction() & SpecString)) - return false; - int indexOperand = registerOffset + argumentToOperand(1); NodeIndex charCode = addToGraph(StringCharAt, OpInfo(Array::String), get(thisOperand), getToInt32(indexOperand)); @@ -1793,6 +1776,10 @@ NodeIndex ByteCodeParser::handleGetByOffset(SpeculatedType prediction, NodeIndex propertyStorage = base; else propertyStorage = addToGraph(GetButterfly, base); + // FIXME: It would be far more efficient for load elimination (and safer from + // an OSR standpoint) if GetByOffset also referenced the object we were loading + // from, and if we could load eliminate a GetByOffset even if the butterfly + // had changed. That would be a great success. NodeIndex getByOffset = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), propertyStorage); StorageAccessData storageAccessData; @@ -1888,12 +1875,12 @@ bool ByteCodeParser::parseResolveOperations(SpeculatedType prediction, unsigned while (resolvingBase) { switch (pc->m_operation) { case ResolveOperation::ReturnGlobalObjectAsBase: - *base = get(m_codeBlock->globalObjectConstant()); + *base = cellConstant(globalObject); ASSERT(!value); return true; case ResolveOperation::SetBaseToGlobal: - *base = get(m_codeBlock->globalObjectConstant()); + *base = cellConstant(globalObject); setBase = true; resolvingBase = false; ++pc; @@ -2150,7 +2137,11 @@ 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(m_inlineStackTop->m_constantBufferRemap[startConstant]), OpInfo(numConstants))); + NewArrayBufferData data; + data.startConstant = m_inlineStackTop->m_constantBufferRemap[startConstant]; + data.numConstants = numConstants; + m_graph.m_newArrayBufferData.append(data); + set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(&m_graph.m_newArrayBufferData.last()))); NEXT_OPCODE(op_new_array_buffer); } @@ -2472,9 +2463,9 @@ bool ByteCodeParser::parseBlock(unsigned limit) SpeculatedType prediction = getPrediction(); NodeIndex base = get(currentInstruction[2].u.operand); - Array::Mode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Read, base); + ArrayMode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Read, base); NodeIndex property = get(currentInstruction[3].u.operand); - NodeIndex getByVal = addToGraph(GetByVal, OpInfo(arrayMode), OpInfo(prediction), base, property); + NodeIndex getByVal = addToGraph(GetByVal, OpInfo(arrayMode.asWord()), OpInfo(prediction), base, property); set(currentInstruction[1].u.operand, getByVal); NEXT_OPCODE(op_get_by_val); @@ -2483,7 +2474,7 @@ bool ByteCodeParser::parseBlock(unsigned limit) case op_put_by_val: { NodeIndex base = get(currentInstruction[1].u.operand); - Array::Mode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Write, base); + ArrayMode arrayMode = getArrayModeAndEmitChecks(currentInstruction[4].u.arrayProfile, Array::Write, base); NodeIndex property = get(currentInstruction[2].u.operand); NodeIndex value = get(currentInstruction[3].u.operand); @@ -2492,53 +2483,11 @@ bool ByteCodeParser::parseBlock(unsigned limit) addVarArgChild(property); addVarArgChild(value); addVarArgChild(NoNode); // Leave room for property storage. - addToGraph(Node::VarArg, PutByVal, OpInfo(arrayMode), OpInfo(0)); + addToGraph(Node::VarArg, PutByVal, OpInfo(arrayMode.asWord()), OpInfo(0)); NEXT_OPCODE(op_put_by_val); } - case op_method_check: { - m_currentProfilingIndex += OPCODE_LENGTH(op_method_check); - Instruction* getInstruction = currentInstruction + OPCODE_LENGTH(op_method_check); - - SpeculatedType prediction = getPrediction(); - - ASSERT(interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id - || interpreter->getOpcodeID(getInstruction->u.opcode) == op_get_by_id_out_of_line); - - NodeIndex base = get(getInstruction[2].u.operand); - unsigned identifier = m_inlineStackTop->m_identifierRemap[getInstruction[3].u.operand]; - - // Check if the method_check was monomorphic. If so, emit a CheckXYZMethod - // node, which is a lot more efficient. - GetByIdStatus getByIdStatus = GetByIdStatus::computeFor( - m_inlineStackTop->m_profiledBlock, - m_currentIndex, - m_codeBlock->identifier(identifier)); - MethodCallLinkStatus methodCallStatus = MethodCallLinkStatus::computeFor( - m_inlineStackTop->m_profiledBlock, m_currentIndex); - - if (methodCallStatus.isSet() - && !getByIdStatus.wasSeenInJIT() - && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) { - // It's monomorphic as far as we can tell, since the method_check was linked - // but the slow path (i.e. the normal get_by_id) never fired. - - addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(methodCallStatus.structure())), base); - if (methodCallStatus.needsPrototypeCheck()) { - addStructureTransitionCheck( - methodCallStatus.prototype(), methodCallStatus.prototypeStructure()); - addToGraph(Phantom, base); - } - set(getInstruction[1].u.operand, cellConstant(methodCallStatus.function())); - } else { - handleGetById( - getInstruction[1].u.operand, prediction, base, identifier, getByIdStatus); - } - - m_currentIndex += OPCODE_LENGTH(op_method_check) + OPCODE_LENGTH(op_get_by_id); - continue; - } case op_get_by_id: case op_get_by_id_out_of_line: case op_get_array_length: { @@ -2665,6 +2614,10 @@ bool ByteCodeParser::parseBlock(unsigned limit) NEXT_OPCODE(op_put_by_id); } + case op_init_global_const_nop: { + NEXT_OPCODE(op_init_global_const_nop); + } + case op_init_global_const: { NodeIndex value = get(currentInstruction[2].u.operand); addToGraph( @@ -2902,10 +2855,10 @@ bool ByteCodeParser::parseBlock(unsigned limit) addToGraph(Throw, get(currentInstruction[1].u.operand)); LAST_OPCODE(op_throw); - case op_throw_reference_error: + case op_throw_static_error: flushArgumentsAndCapturedVariables(); addToGraph(ThrowReferenceError); - LAST_OPCODE(op_throw_reference_error); + LAST_OPCODE(op_throw_static_error); case op_call: handleCall(interpreter, currentInstruction, Call, CodeForCall); @@ -3104,6 +3057,14 @@ bool ByteCodeParser::parseBlock(unsigned limit) NodeIndex base = 0; NodeIndex value = 0; if (parseResolveOperations(prediction, identifier, operations, putToBaseOperation, &base, &value)) { + // First create OSR hints only. + set(baseDst, base); + set(valueDst, value); + + // If we try to hoist structure checks into here, then we're guaranteed that they will occur + // *after* we have already set up the values for OSR. + + // Then do the real SetLocals. set(baseDst, base); set(valueDst, value); } else { @@ -3124,6 +3085,14 @@ bool ByteCodeParser::parseBlock(unsigned limit) NodeIndex base = 0; NodeIndex value = 0; if (parseResolveOperations(prediction, identifier, operations, 0, &base, &value)) { + // First create OSR hints only. + set(baseDst, base); + set(valueDst, value); + + // If we try to hoist structure checks into here, then we're guaranteed that they will occur + // *after* we have already set up the values for OSR. + + // Then do the real SetLocals. set(baseDst, base); set(valueDst, value); } else { @@ -3632,7 +3601,7 @@ void ByteCodeParser::parseCodeBlock() dataLog("Parsing code block %p. codeType = %s, captureCount = %u, needsFullScopeChain = %s, needsActivation = %s, isStrictMode = %s\n", codeBlock, codeTypeToString(codeBlock->codeType()), - codeBlock->symbolTable()->captureCount(), + codeBlock->symbolTable() ? codeBlock->symbolTable()->captureCount() : 0, codeBlock->needsFullScopeChain()?"true":"false", codeBlock->ownerExecutable()->needsActivation()?"true":"false", codeBlock->ownerExecutable()->isStrictMode()?"true":"false"); |