diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-25 19:20:41 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2017-02-02 12:30:55 +0000 |
commit | 6882a04fb36642862b11efe514251d32070c3d65 (patch) | |
tree | b7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp | |
parent | ab6df191029eeeb0b0f16f127d553265659f739e (diff) | |
download | qtwebkit-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.cpp | 171 |
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 |