diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGGraph.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGGraph.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp new file mode 100644 index 0000000..84e2d4d --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DFGGraph.h" + +#include "CodeBlock.h" + +#if ENABLE(DFG_JIT) + +namespace JSC { namespace DFG { + +#ifndef NDEBUG + +// Creates an array of stringized names. +static const char* dfgOpNames[] = { +#define STRINGIZE_DFG_OP_ENUM(opcode, flags) #opcode , + FOR_EACH_DFG_OP(STRINGIZE_DFG_OP_ENUM) +#undef STRINGIZE_DFG_OP_ENUM +}; + +void Graph::dump(NodeIndex nodeIndex, CodeBlock* codeBlock) +{ + Node& node = at(nodeIndex); + NodeType op = node.op; + + unsigned refCount = node.refCount; + if (!refCount) + return; + bool mustGenerate = node.mustGenerate(); + if (mustGenerate) + --refCount; + + // Example/explanation of dataflow dump output + // + // 14: <!2:7> GetByVal(@3, @13) + // ^1 ^2 ^3 ^4 ^5 + // + // (1) The nodeIndex of this operation. + // (2) The reference count. The number printed is the 'real' count, + // not including the 'mustGenerate' ref. If the node is + // 'mustGenerate' then the count it prefixed with '!'. + // (3) The virtual register slot assigned to this node. + // (4) The name of the operation. + // (5) The arguments to the operation. The may be of the form: + // @# - a NodeIndex referencing a prior node in the graph. + // arg# - an argument number. + // $# - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }. + // id# - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }. + // var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations. + printf("% 4d:\t<%c%u:%u>\t%s(", (int)nodeIndex, mustGenerate ? '!' : ' ', refCount, node.virtualRegister, dfgOpNames[op & NodeIdMask]); + if (node.child1 != NoNode) + printf("@%u", node.child1); + if (node.child2 != NoNode) + printf(", @%u", node.child2); + if (node.child3 != NoNode) + printf(", @%u", node.child3); + bool hasPrinted = node.child1 != NoNode; + + if (node.hasVarNumber()) { + printf("%svar%u", hasPrinted ? ", " : "", node.varNumber()); + hasPrinted = true; + } + if (node.hasIdentifier()) { + if (codeBlock) + printf("%sid%u{%s}", hasPrinted ? ", " : "", node.identifierNumber(), codeBlock->identifier(node.identifierNumber()).ustring().utf8().data()); + else + printf("%sid%u", hasPrinted ? ", " : "", node.identifierNumber()); + hasPrinted = true; + } + if (node.hasLocal()) { + int local = node.local(); + if (local < 0) + printf("%sarg%u", hasPrinted ? ", " : "", local - codeBlock->thisRegister()); + else + printf("%sr%u", hasPrinted ? ", " : "", local); + hasPrinted = true; + } + if (op == Int32Constant) { + printf("%s$%u{%d|0x%08x}", hasPrinted ? ", " : "", node.constantNumber(), node.int32Constant(), node.int32Constant()); + hasPrinted = true; + } + if (op == DoubleConstant) { + printf("%s$%u{%f})", hasPrinted ? ", " : "", node.constantNumber(), node.numericConstant()); + hasPrinted = true; + } + if (op == JSConstant) { + printf("%s$%u", hasPrinted ? ", " : "", node.constantNumber()); + hasPrinted = true; + } + if (node.isBranch() || node.isJump()) { + printf("%sT:#%u", hasPrinted ? ", " : "", blockIndexForBytecodeOffset(node.takenBytecodeOffset())); + hasPrinted = true; + } + if (node.isBranch()) { + printf("%sF:#%u", hasPrinted ? ", " : "", blockIndexForBytecodeOffset(node.notTakenBytecodeOffset())); + hasPrinted = true; + } + + printf(")\n"); +} + +void Graph::dump(CodeBlock* codeBlock) +{ + for (size_t b = 0; b < m_blocks.size(); ++b) { + printf("Block #%u:\n", (int)b); + BasicBlock& block = m_blocks[b]; + for (size_t i = block.begin; i < block.end; ++i) + dump(i, codeBlock); + } +} + +#endif + +// FIXME: Convert these methods to be iterative, not recursive. +void Graph::refChildren(NodeIndex op) +{ + Node& node = at(op); + + if (node.child1 == NoNode) { + ASSERT(node.child2 == NoNode && node.child3 == NoNode); + return; + } + ref(node.child1); + + if (node.child2 == NoNode) { + ASSERT(node.child3 == NoNode); + return; + } + ref(node.child2); + + if (node.child3 == NoNode) + return; + ref(node.child3); +} +void Graph::derefChildren(NodeIndex op) +{ + Node& node = at(op); + + if (node.child1 == NoNode) { + ASSERT(node.child2 == NoNode && node.child3 == NoNode); + return; + } + deref(node.child1); + + if (node.child2 == NoNode) { + ASSERT(node.child3 == NoNode); + return; + } + deref(node.child2); + + if (node.child3 == NoNode) + return; + deref(node.child3); +} + +} } // namespace JSC::DFG + +#endif |