summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
commitcfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch)
tree24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
parent69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff)
downloadqtwebkit-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.cpp141
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");