summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp171
1 files changed, 43 insertions, 128 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
index a3f2ac6ff..6392f14a9 100644
--- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,8 +29,10 @@
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
+#include "DFGJITCode.h"
#include "DFGValueSource.h"
-#include "Operations.h"
+#include "InlineCallFrame.h"
+#include "JSCInlines.h"
#include <wtf/DataLog.h>
#include <wtf/HashMap.h>
@@ -47,11 +49,14 @@ namespace {
struct MinifiedGenerationInfo {
bool filled; // true -> in gpr/fpr/pair, false -> spilled
+ bool alive;
VariableRepresentation u;
DataFormat format;
MinifiedGenerationInfo()
- : format(DataFormatNone)
+ : filled(false)
+ , alive(false)
+ , format(DataFormatNone)
{
}
@@ -61,13 +66,19 @@ struct MinifiedGenerationInfo {
case BirthToFill:
case Fill:
filled = true;
+ alive = true;
break;
case BirthToSpill:
case Spill:
filled = false;
+ alive = true;
break;
+ case Birth:
+ alive = true;
+ return;
case Death:
format = DataFormatNone;
+ alive = false;
return;
default:
return;
@@ -80,25 +91,23 @@ struct MinifiedGenerationInfo {
} // namespace
-bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, CodeBlock* codeBlock, MinifiedNode* node) const
+bool VariableEventStream::tryToSetConstantRecovery(ValueRecovery& recovery, MinifiedNode* node) const
{
if (!node)
return false;
- if (node->hasConstantNumber()) {
- recovery = ValueRecovery::constant(
- codeBlock->constantRegister(
- FirstConstantRegisterIndex + node->constantNumber()).get());
+ if (node->hasConstant()) {
+ recovery = ValueRecovery::constant(node->constant());
return true;
}
- if (node->hasWeakConstant()) {
- recovery = ValueRecovery::constant(node->weakConstant());
+ if (node->op() == PhantomDirectArguments) {
+ recovery = ValueRecovery::directArgumentsThatWereNotCreated(node->id());
return true;
}
- if (node->op() == PhantomArguments) {
- recovery = ValueRecovery::argumentsThatWereNotCreated();
+ if (node->op() == PhantomClonedArguments) {
+ recovery = ValueRecovery::outOfBandArgumentsThatWereNotCreated(node->id());
return true;
}
@@ -109,22 +118,24 @@ void VariableEventStream::reconstruct(
CodeBlock* codeBlock, CodeOrigin codeOrigin, MinifiedGraph& graph,
unsigned index, Operands<ValueRecovery>& valueRecoveries) const
{
- ASSERT(codeBlock->getJITType() == JITCode::DFGJIT);
+ ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
CodeBlock* baselineCodeBlock = codeBlock->baselineVersion();
unsigned numVariables;
if (codeOrigin.inlineCallFrame)
- numVariables = baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame)->m_numCalleeRegisters + codeOrigin.inlineCallFrame->stackOffset;
+ numVariables = baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame)->m_numCalleeLocals + VirtualRegister(codeOrigin.inlineCallFrame->stackOffset).toLocal() + 1;
else
- numVariables = baselineCodeBlock->m_numCalleeRegisters;
+ numVariables = baselineCodeBlock->m_numCalleeLocals;
// Crazy special case: if we're at index == 0 then this must be an argument check
// failure, in which case all variables are already set up. The recoveries should
// reflect this.
if (!index) {
valueRecoveries = Operands<ValueRecovery>(codeBlock->numParameters(), numVariables);
- for (size_t i = 0; i < valueRecoveries.size(); ++i)
- valueRecoveries[i] = ValueRecovery::alreadyInJSStack();
+ for (size_t i = 0; i < valueRecoveries.size(); ++i) {
+ valueRecoveries[i] = ValueRecovery::displacedInJSStack(
+ VirtualRegister(valueRecoveries.operandForIndex(i)), DataFormatJS);
+ }
return;
}
@@ -133,12 +144,10 @@ void VariableEventStream::reconstruct(
while (at(startIndex).kind() != Reset)
startIndex--;
-#if DFG_ENABLE(DEBUG_VERBOSE)
- dataLogF("Computing OSR exit recoveries starting at seq#%u.\n", startIndex);
-#endif
-
// Step 2: Create a mock-up of the DFG's state and execute the events.
Operands<ValueSource> operandSources(codeBlock->numParameters(), numVariables);
+ for (unsigned i = operandSources.size(); i--;)
+ operandSources[i] = ValueSource(SourceIsDead);
HashMap<MinifiedID, MinifiedGenerationInfo> generationInfos;
for (unsigned i = startIndex; i < index; ++i) {
const VariableEvent& event = at(i);
@@ -147,7 +156,8 @@ void VariableEventStream::reconstruct(
// nothing to do.
break;
case BirthToFill:
- case BirthToSpill: {
+ case BirthToSpill:
+ case Birth: {
MinifiedGenerationInfo info;
info.update(event);
generationInfos.add(event.id(), info);
@@ -162,12 +172,12 @@ void VariableEventStream::reconstruct(
break;
}
case MovHintEvent:
- if (operandSources.hasOperand(event.operand()))
- operandSources.setOperand(event.operand(), ValueSource(event.id()));
+ if (operandSources.hasOperand(event.bytecodeRegister()))
+ operandSources.setOperand(event.bytecodeRegister(), ValueSource(event.id()));
break;
case SetLocalEvent:
- if (operandSources.hasOperand(event.operand()))
- operandSources.setOperand(event.operand(), ValueSource::forDataFormat(event.dataFormat()));
+ if (operandSources.hasOperand(event.bytecodeRegister()))
+ operandSources.setOperand(event.bytecodeRegister(), ValueSource::forDataFormat(event.machineRegister(), event.dataFormat()));
break;
default:
RELEASE_ASSERT_NOT_REACHED();
@@ -186,108 +196,20 @@ void VariableEventStream::reconstruct(
ASSERT(source.kind() == HaveNode);
MinifiedNode* node = graph.at(source.id());
- if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, node))
- continue;
-
MinifiedGenerationInfo info = generationInfos.get(source.id());
- if (info.format == DataFormatNone) {
- // Try to see if there is an alternate node that would contain the value we want.
- // There are four possibilities:
- //
- // Int32ToDouble: We can use this in place of the original node, but
- // we'd rather not; so we use it only if it is the only remaining
- // live version.
- //
- // ValueToInt32: If the only remaining live version of the value is
- // ValueToInt32, then we can use it.
- //
- // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
- // then the only remaining uses are ones that want a properly formed number
- // rather than a UInt32 intermediate.
- //
- // DoubleAsInt32: Same as UInt32ToNumber.
- //
- // The reverse of the above: This node could be a UInt32ToNumber, but its
- // alternative is still alive. This means that the only remaining uses of
- // the number would be fine with a UInt32 intermediate.
-
- bool found = false;
-
- if (node && node->op() == UInt32ToNumber) {
- MinifiedID id = node->child1();
- if (tryToSetConstantRecovery(valueRecoveries[i], codeBlock, graph.at(id)))
- continue;
- info = generationInfos.get(id);
- if (info.format != DataFormatNone)
- found = true;
- }
-
- if (!found) {
- MinifiedID int32ToDoubleID;
- MinifiedID valueToInt32ID;
- MinifiedID uint32ToNumberID;
- MinifiedID doubleAsInt32ID;
-
- HashMap<MinifiedID, MinifiedGenerationInfo>::iterator iter = generationInfos.begin();
- HashMap<MinifiedID, MinifiedGenerationInfo>::iterator end = generationInfos.end();
- for (; iter != end; ++iter) {
- MinifiedID id = iter->key;
- node = graph.at(id);
- if (!node)
- continue;
- if (!node->hasChild1())
- continue;
- if (node->child1() != source.id())
- continue;
- if (iter->value.format == DataFormatNone)
- continue;
- switch (node->op()) {
- case Int32ToDouble:
- case ForwardInt32ToDouble:
- int32ToDoubleID = id;
- break;
- case ValueToInt32:
- valueToInt32ID = id;
- break;
- case UInt32ToNumber:
- uint32ToNumberID = id;
- break;
- case DoubleAsInt32:
- doubleAsInt32ID = id;
- break;
- default:
- break;
- }
- }
-
- MinifiedID idToUse;
- if (!!doubleAsInt32ID)
- idToUse = doubleAsInt32ID;
- else if (!!int32ToDoubleID)
- idToUse = int32ToDoubleID;
- else if (!!valueToInt32ID)
- idToUse = valueToInt32ID;
- else if (!!uint32ToNumberID)
- idToUse = uint32ToNumberID;
-
- if (!!idToUse) {
- info = generationInfos.get(idToUse);
- ASSERT(info.format != DataFormatNone);
- found = true;
- }
- }
-
- if (!found) {
- valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
- continue;
- }
+ if (!info.alive) {
+ valueRecoveries[i] = ValueRecovery::constant(jsUndefined());
+ continue;
}
+
+ if (tryToSetConstantRecovery(valueRecoveries[i], node))
+ continue;
ASSERT(info.format != DataFormatNone);
if (info.filled) {
if (info.format == DataFormatDouble) {
- valueRecoveries[i] = ValueRecovery::inFPR(info.u.fpr);
+ valueRecoveries[i] = ValueRecovery::inFPR(info.u.fpr, DataFormatDouble);
continue;
}
#if USE(JSVALUE32_64)
@@ -303,13 +225,6 @@ void VariableEventStream::reconstruct(
valueRecoveries[i] =
ValueRecovery::displacedInJSStack(static_cast<VirtualRegister>(info.u.virtualReg), info.format);
}
-
- // Step 4: Make sure that for locals that coincide with true call frame headers, the exit compiler knows
- // that those values don't have to be recovered. Signal this by using ValueRecovery::alreadyInJSStack()
- for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->caller.inlineCallFrame) {
- for (unsigned i = JSStack::CallFrameHeaderSize; i--;)
- valueRecoveries.setLocal(inlineCallFrame->stackOffset - i - 1, ValueRecovery::alreadyInJSStack());
- }
}
} } // namespace JSC::DFG