]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGGraph.cpp
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / dfg / DFGGraph.cpp
CommitLineData
14957cd0
A
1/*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "DFGGraph.h"
28
29#include "CodeBlock.h"
30
31#if ENABLE(DFG_JIT)
32
33namespace JSC { namespace DFG {
34
35#ifndef NDEBUG
36
37// Creates an array of stringized names.
38static const char* dfgOpNames[] = {
39#define STRINGIZE_DFG_OP_ENUM(opcode, flags) #opcode ,
40 FOR_EACH_DFG_OP(STRINGIZE_DFG_OP_ENUM)
41#undef STRINGIZE_DFG_OP_ENUM
42};
43
44void Graph::dump(NodeIndex nodeIndex, CodeBlock* codeBlock)
45{
46 Node& node = at(nodeIndex);
47 NodeType op = node.op;
48
49 unsigned refCount = node.refCount();
50 if (!refCount)
51 return;
52 bool mustGenerate = node.mustGenerate();
53 if (mustGenerate)
54 --refCount;
55
56 // Example/explanation of dataflow dump output
57 //
58 // 14: <!2:7> GetByVal(@3, @13)
59 // ^1 ^2 ^3 ^4 ^5
60 //
61 // (1) The nodeIndex of this operation.
62 // (2) The reference count. The number printed is the 'real' count,
63 // not including the 'mustGenerate' ref. If the node is
64 // 'mustGenerate' then the count it prefixed with '!'.
65 // (3) The virtual register slot assigned to this node.
66 // (4) The name of the operation.
67 // (5) The arguments to the operation. The may be of the form:
68 // @# - a NodeIndex referencing a prior node in the graph.
69 // arg# - an argument number.
70 // $# - the index in the CodeBlock of a constant { for numeric constants the value is displayed | for integers, in both decimal and hex }.
71 // id# - the index in the CodeBlock of an identifier { if codeBlock is passed to dump(), the string representation is displayed }.
72 // var# - the index of a var on the global object, used by GetGlobalVar/PutGlobalVar operations.
73 printf("% 4d:\t<%c%u:", (int)nodeIndex, mustGenerate ? '!' : ' ', refCount);
74 if (node.hasResult())
75 printf("%u", node.virtualRegister());
76 else
77 printf("-");
78 printf(">\t%s(", dfgOpNames[op & NodeIdMask]);
79 if (node.child1 != NoNode)
80 printf("@%u", node.child1);
81 if (node.child2 != NoNode)
82 printf(", @%u", node.child2);
83 if (node.child3 != NoNode)
84 printf(", @%u", node.child3);
85 bool hasPrinted = node.child1 != NoNode;
86
87 if (node.hasVarNumber()) {
88 printf("%svar%u", hasPrinted ? ", " : "", node.varNumber());
89 hasPrinted = true;
90 }
91 if (node.hasIdentifier()) {
92 if (codeBlock)
93 printf("%sid%u{%s}", hasPrinted ? ", " : "", node.identifierNumber(), codeBlock->identifier(node.identifierNumber()).ustring().utf8().data());
94 else
95 printf("%sid%u", hasPrinted ? ", " : "", node.identifierNumber());
96 hasPrinted = true;
97 }
98 if (node.hasLocal()) {
99 int local = node.local();
100 if (operandIsArgument(local))
101 printf("%sarg%u", hasPrinted ? ", " : "", local - codeBlock->thisRegister());
102 else
103 printf("%sr%u", hasPrinted ? ", " : "", local);
104 hasPrinted = true;
105 }
106 if (op == Int32Constant) {
107 printf("%s$%u{%d|0x%08x}", hasPrinted ? ", " : "", node.constantNumber(), node.int32Constant(), node.int32Constant());
108 hasPrinted = true;
109 }
110 if (op == DoubleConstant) {
111 printf("%s$%u{%f})", hasPrinted ? ", " : "", node.constantNumber(), node.numericConstant());
112 hasPrinted = true;
113 }
114 if (op == JSConstant) {
115 printf("%s$%u", hasPrinted ? ", " : "", node.constantNumber());
116 hasPrinted = true;
117 }
118 if (node.isBranch() || node.isJump()) {
119 printf("%sT:#%u", hasPrinted ? ", " : "", blockIndexForBytecodeOffset(node.takenBytecodeOffset()));
120 hasPrinted = true;
121 }
122 if (node.isBranch()) {
123 printf("%sF:#%u", hasPrinted ? ", " : "", blockIndexForBytecodeOffset(node.notTakenBytecodeOffset()));
124 hasPrinted = true;
125 }
126
127 printf(")\n");
128}
129
130void Graph::dump(CodeBlock* codeBlock)
131{
132 for (size_t b = 0; b < m_blocks.size(); ++b) {
133 printf("Block #%u:\n", (int)b);
134 for (size_t i = m_blocks[b]->begin; i < m_blocks[b]->end; ++i)
135 dump(i, codeBlock);
136 }
137 printf("Phi Nodes:\n");
138 for (size_t i = m_blocks.last()->end; i < size(); ++i)
139 dump(i, codeBlock);
140}
141
142#endif
143
144// FIXME: Convert this method to be iterative, not recursive.
145void Graph::refChildren(NodeIndex op)
146{
147 Node& node = at(op);
148
149 if (node.child1 == NoNode) {
150 ASSERT(node.child2 == NoNode && node.child3 == NoNode);
151 return;
152 }
153 ref(node.child1);
154
155 if (node.child2 == NoNode) {
156 ASSERT(node.child3 == NoNode);
157 return;
158 }
159 ref(node.child2);
160
161 if (node.child3 == NoNode)
162 return;
163 ref(node.child3);
164}
165
166} } // namespace JSC::DFG
167
168#endif