blob: 5125d2f7cecf35adfc1c4af4dc6c03258b242951 [file] [log] [blame]
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "CodeBlock.h"
32
ggaren@apple.comcc0f1f12008-11-17 23:16:00 +000033#include "JIT.h"
darin@apple.com9ce79022008-06-28 15:50:49 +000034#include "JSValue.h"
ggaren@apple.com901a8a22008-11-17 20:57:18 +000035#include "Interpreter.h"
cwzwarich@webkit.orga691b5a2008-10-31 05:56:58 +000036#include "Debugger.h"
ap@webkit.org72d005d2008-05-24 12:43:02 +000037#include <stdio.h>
aroben@apple.coma2fd5702008-09-02 15:15:21 +000038#include <wtf/StringExtras.h>
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000039
weinig@apple.com3f9a9592008-12-08 21:40:15 +000040#define DUMP_CODE_BLOCK_STATISTICS 0
41
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000042namespace JSC {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000043
ggaren@apple.com47d3f052008-11-15 21:37:49 +000044#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
cwzwarich@webkit.org217b5402008-08-09 11:00:38 +000045
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000046static UString escapeQuotes(const UString& str)
47{
48 UString result = str;
49 int pos = 0;
50 while ((pos = result.find('\"', pos)) >= 0) {
51 result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);
52 pos += 4;
53 }
54 return result;
55}
56
darin@apple.com44331f82008-10-24 16:22:51 +000057static UString valueToSourceString(ExecState* exec, JSValue* val)
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000058{
ggaren@apple.comc6b3b602008-07-23 05:10:05 +000059 if (val->isString()) {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000060 UString result("\"");
ggaren@apple.comc6b3b602008-07-23 05:10:05 +000061 result += escapeQuotes(val->toString(exec)) + "\"";
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000062 return result;
63 }
64
ggaren@apple.comc6b3b602008-07-23 05:10:05 +000065 return val->toString(exec);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000066}
67
68static CString registerName(int r)
69{
weinig@apple.com3412bb42008-09-01 21:22:54 +000070 if (r == missingThisObjectMarker())
71 return "<null>";
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000072
ggaren@apple.com107bd0e2008-09-24 00:27:18 +000073 return (UString("r") + UString::from(r)).UTF8String();
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000074}
75
darin@apple.com44331f82008-10-24 16:22:51 +000076static CString constantName(ExecState* exec, int k, JSValue* value)
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +000077{
78 return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();
79}
80
81static CString idName(int id0, const Identifier& ident)
82{
83 return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
84}
85
86static UString regexpToSourceString(RegExp* regExp)
87{
88 UString pattern = UString("/") + regExp->pattern() + "/";
89 if (regExp->global())
90 pattern += "g";
91 if (regExp->ignoreCase())
92 pattern += "i";
93 if (regExp->multiline())
94 pattern += "m";
95
96 return pattern;
97}
98
99static CString regexpName(int re, RegExp* regexp)
100{
101 return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String();
102}
103
weinig@apple.com3412bb42008-09-01 21:22:54 +0000104static UString pointerToSourceString(void* p)
105{
106 char buffer[2 + 2 * sizeof(void*) + 1]; // 0x [two characters per byte] \0
107 snprintf(buffer, sizeof(buffer), "%p", p);
108 return buffer;
109}
110
ggaren@apple.comd0740c82008-05-28 20:47:13 +0000111NEVER_INLINE static const char* debugHookName(int debugHookID)
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000112{
weinig@apple.coma963b962008-06-05 05:36:55 +0000113 switch (static_cast<DebugHookID>(debugHookID)) {
114 case DidEnterCallFrame:
115 return "didEnterCallFrame";
116 case WillLeaveCallFrame:
117 return "willLeaveCallFrame";
118 case WillExecuteStatement:
119 return "willExecuteStatement";
120 case WillExecuteProgram:
121 return "willExecuteProgram";
122 case DidExecuteProgram:
123 return "didExecuteProgram";
124 case DidReachBreakpoint:
125 return "didReachBreakpoint";
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000126 }
weinig@apple.coma963b962008-06-05 05:36:55 +0000127
ggaren@apple.comd0740c82008-05-28 20:47:13 +0000128 ASSERT_NOT_REACHED();
129 return "";
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000130}
131
weinig@apple.comcb26d812008-12-06 22:01:05 +0000132static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset)
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000133{
134 return it - begin + offset;
135}
136
137static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
138{
139 int r0 = (++it)->u.operand;
140 int r1 = (++it)->u.operand;
141
aroben@apple.com82c32362008-05-27 23:25:09 +0000142 printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000143}
144
145static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op)
146{
147 int r0 = (++it)->u.operand;
148 int r1 = (++it)->u.operand;
149 int r2 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000150 printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000151}
152
153static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op)
154{
155 int r0 = (++it)->u.operand;
156 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000157 printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset));
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000158}
159
weinig@apple.comcb26d812008-12-06 22:01:05 +0000160static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
weinig@apple.com3412bb42008-09-01 21:22:54 +0000161{
162 int r0 = (++it)->u.operand;
163 int r1 = (++it)->u.operand;
164 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000165 printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
weinig@apple.com3412bb42008-09-01 21:22:54 +0000166 it += 4;
167}
168
weinig@apple.comcb26d812008-12-06 22:01:05 +0000169static void printPutByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op)
weinig@apple.com3412bb42008-09-01 21:22:54 +0000170{
171 int r0 = (++it)->u.operand;
172 int id0 = (++it)->u.operand;
173 int r1 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000174 printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
oliver@apple.come3c5d0e2008-09-14 08:18:49 +0000175 it += 4;
weinig@apple.com3412bb42008-09-01 21:22:54 +0000176}
177
darin@apple.coma9778f92008-11-16 04:40:06 +0000178void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const
weinig@apple.com3412bb42008-09-01 21:22:54 +0000179{
weinig@apple.comcb26d812008-12-06 22:01:05 +0000180 unsigned instructionOffset = vPC - m_instructions.begin();
darin@apple.coma9778f92008-11-16 04:40:06 +0000181 printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).UTF8String().c_str());
weinig@apple.com3412bb42008-09-01 21:22:54 +0000182}
183
darin@apple.coma9778f92008-11-16 04:40:06 +0000184void CodeBlock::printStructures(const Instruction* vPC) const
weinig@apple.com3412bb42008-09-01 21:22:54 +0000185{
weinig@apple.comcb26d812008-12-06 22:01:05 +0000186 Interpreter* interpreter = m_globalData->interpreter;
187 unsigned instructionOffset = vPC - m_instructions.begin();
weinig@apple.com3412bb42008-09-01 21:22:54 +0000188
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000189 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000190 printStructure("get_by_id", vPC, 4);
weinig@apple.com3412bb42008-09-01 21:22:54 +0000191 return;
192 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000193 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000194 printStructure("get_by_id_self", vPC, 4);
weinig@apple.com3412bb42008-09-01 21:22:54 +0000195 return;
196 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000197 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000198 printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str());
weinig@apple.com3412bb42008-09-01 21:22:54 +0000199 return;
200 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000201 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000202 printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_new", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().c_str());
oliver@apple.come3c5d0e2008-09-14 08:18:49 +0000203 return;
204 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000205 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000206 printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structureChain).UTF8String().c_str());
weinig@apple.com3412bb42008-09-01 21:22:54 +0000207 return;
208 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000209 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000210 printStructure("put_by_id", vPC, 4);
weinig@apple.com3412bb42008-09-01 21:22:54 +0000211 return;
212 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000213 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000214 printStructure("put_by_id_replace", vPC, 4);
weinig@apple.com3412bb42008-09-01 21:22:54 +0000215 return;
216 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000217 if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {
darin@apple.coma9778f92008-11-16 04:40:06 +0000218 printStructure("resolve_global", vPC, 4);
oliver@apple.com70579b52008-09-16 05:53:15 +0000219 return;
220 }
weinig@apple.com3412bb42008-09-01 21:22:54 +0000221
weinig@apple.comcb26d812008-12-06 22:01:05 +0000222 // These m_instructions doesn't ref Structures.
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000223 ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
weinig@apple.com3412bb42008-09-01 21:22:54 +0000224}
225
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000226void CodeBlock::dump(ExecState* exec) const
227{
weinig@apple.comcb26d812008-12-06 22:01:05 +0000228 Vector<Instruction>::const_iterator begin = m_instructions.begin();
229 Vector<Instruction>::const_iterator end = m_instructions.end();
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000230
231 size_t instructionCount = 0;
232 for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000233 if (exec->interpreter()->isOpcode(it->u.opcode))
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000234 ++instructionCount;
235
weinig@apple.comcb26d812008-12-06 22:01:05 +0000236 printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
darin@apple.com1ac13a62008-06-11 22:01:40 +0000237 static_cast<unsigned long>(instructionCount),
weinig@apple.comcb26d812008-12-06 22:01:05 +0000238 static_cast<unsigned long>(m_instructions.size() * sizeof(Instruction)),
239 this, m_numParameters, m_numCalleeRegisters);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000240
241 for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
242 dump(exec, begin, it);
243
weinig@apple.comcb26d812008-12-06 22:01:05 +0000244 if (!m_identifiers.isEmpty()) {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000245 printf("\nIdentifiers:\n");
246 size_t i = 0;
247 do {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000248 printf(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ascii());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000249 ++i;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000250 } while (i != m_identifiers.size());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000251 }
252
weinig@apple.comcb26d812008-12-06 22:01:05 +0000253 if (!m_constantRegisters.isEmpty()) {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000254 printf("\nConstants:\n");
weinig@apple.comcb26d812008-12-06 22:01:05 +0000255 unsigned registerIndex = m_numVars;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000256 size_t i = 0;
257 do {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000258 printf(" r%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue(exec)).ascii());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000259 ++i;
ggaren@apple.com6345f8b2008-10-29 00:11:21 +0000260 ++registerIndex;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000261 } while (i < m_constantRegisters.size());
cwzwarich@webkit.org300bb752008-08-06 10:37:34 +0000262 }
263
weinig@apple.com4557e842008-12-09 01:06:14 +0000264 if (m_rareData && !m_rareData->m_unexpectedConstants.isEmpty()) {
cwzwarich@webkit.org300bb752008-08-06 10:37:34 +0000265 printf("\nUnexpected Constants:\n");
266 size_t i = 0;
267 do {
weinig@apple.com4557e842008-12-09 01:06:14 +0000268 printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_rareData->m_unexpectedConstants[i]).ascii());
cwzwarich@webkit.org300bb752008-08-06 10:37:34 +0000269 ++i;
weinig@apple.com4557e842008-12-09 01:06:14 +0000270 } while (i < m_rareData->m_unexpectedConstants.size());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000271 }
272
weinig@apple.com4557e842008-12-09 01:06:14 +0000273 if (m_rareData && !m_rareData->m_regexps.isEmpty()) {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000274 printf("\nm_regexps:\n");
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000275 size_t i = 0;
276 do {
weinig@apple.com4557e842008-12-09 01:06:14 +0000277 printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).ascii());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000278 ++i;
weinig@apple.com4557e842008-12-09 01:06:14 +0000279 } while (i < m_rareData->m_regexps.size());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000280 }
281
weinig@apple.comcb26d812008-12-06 22:01:05 +0000282 if (!m_globalResolveInstructions.isEmpty() || !m_propertyAccessInstructions.isEmpty())
darin@apple.coma9778f92008-11-16 04:40:06 +0000283 printf("\nStructures:\n");
barraclough@apple.come9642652008-10-23 22:29:54 +0000284
weinig@apple.comcb26d812008-12-06 22:01:05 +0000285 if (!m_globalResolveInstructions.isEmpty()) {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000286 size_t i = 0;
287 do {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000288 printStructures(&m_instructions[m_globalResolveInstructions[i]]);
mrowe@apple.comf88a4632008-09-07 05:44:58 +0000289 ++i;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000290 } while (i < m_globalResolveInstructions.size());
barraclough@apple.come9642652008-10-23 22:29:54 +0000291 }
weinig@apple.comcb26d812008-12-06 22:01:05 +0000292 if (!m_propertyAccessInstructions.isEmpty()) {
barraclough@apple.come9642652008-10-23 22:29:54 +0000293 size_t i = 0;
294 do {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000295 printStructures(&m_instructions[m_propertyAccessInstructions[i].bytecodeIndex]);
barraclough@apple.come9642652008-10-23 22:29:54 +0000296 ++i;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000297 } while (i < m_propertyAccessInstructions.size());
weinig@apple.com3412bb42008-09-01 21:22:54 +0000298 }
mrowe@apple.comf88a4632008-09-07 05:44:58 +0000299
weinig@apple.com4557e842008-12-09 01:06:14 +0000300 if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000301 printf("\nException Handlers:\n");
302 unsigned i = 0;
303 do {
weinig@apple.com4557e842008-12-09 01:06:14 +0000304 printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000305 ++i;
weinig@apple.com4557e842008-12-09 01:06:14 +0000306 } while (i < m_rareData->m_exceptionHandlers.size());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000307 }
oliver@apple.com8007f462008-07-24 00:49:46 +0000308
weinig@apple.com4557e842008-12-09 01:06:14 +0000309 if (m_rareData && !m_rareData->m_immediateSwitchJumpTables.isEmpty()) {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000310 printf("Immediate Switch Jump Tables:\n");
oliver@apple.com8007f462008-07-24 00:49:46 +0000311 unsigned i = 0;
312 do {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000313 printf(" %1d = {\n", i);
oliver@apple.com8007f462008-07-24 00:49:46 +0000314 int entry = 0;
weinig@apple.com4557e842008-12-09 01:06:14 +0000315 Vector<int32_t>::const_iterator end = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.end();
316 for (Vector<int32_t>::const_iterator iter = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000317 if (!*iter)
318 continue;
weinig@apple.com4557e842008-12-09 01:06:14 +0000319 printf("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter);
weinig@apple.com3412bb42008-09-01 21:22:54 +0000320 }
321 printf(" }\n");
oliver@apple.com8007f462008-07-24 00:49:46 +0000322 ++i;
weinig@apple.com4557e842008-12-09 01:06:14 +0000323 } while (i < m_rareData->m_immediateSwitchJumpTables.size());
oliver@apple.com8007f462008-07-24 00:49:46 +0000324 }
325
weinig@apple.com4557e842008-12-09 01:06:14 +0000326 if (m_rareData && !m_rareData->m_characterSwitchJumpTables.isEmpty()) {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000327 printf("\nCharacter Switch Jump Tables:\n");
oliver@apple.com8007f462008-07-24 00:49:46 +0000328 unsigned i = 0;
329 do {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000330 printf(" %1d = {\n", i);
oliver@apple.com8007f462008-07-24 00:49:46 +0000331 int entry = 0;
weinig@apple.com4557e842008-12-09 01:06:14 +0000332 Vector<int32_t>::const_iterator end = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.end();
333 for (Vector<int32_t>::const_iterator iter = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000334 if (!*iter)
335 continue;
weinig@apple.com4557e842008-12-09 01:06:14 +0000336 ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF));
337 UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min);
oliver@apple.com8007f462008-07-24 00:49:46 +0000338 printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).ascii(), *iter);
mrowe@apple.comf88a4632008-09-07 05:44:58 +0000339 }
weinig@apple.com3412bb42008-09-01 21:22:54 +0000340 printf(" }\n");
oliver@apple.com8007f462008-07-24 00:49:46 +0000341 ++i;
weinig@apple.com4557e842008-12-09 01:06:14 +0000342 } while (i < m_rareData->m_characterSwitchJumpTables.size());
oliver@apple.com8007f462008-07-24 00:49:46 +0000343 }
344
weinig@apple.com4557e842008-12-09 01:06:14 +0000345 if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000346 printf("\nString Switch Jump Tables:\n");
oliver@apple.com8007f462008-07-24 00:49:46 +0000347 unsigned i = 0;
348 do {
weinig@apple.com3412bb42008-09-01 21:22:54 +0000349 printf(" %1d = {\n", i);
weinig@apple.com4557e842008-12-09 01:06:14 +0000350 StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end();
351 for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter)
mrowe@apple.comf88a4632008-09-07 05:44:58 +0000352 printf("\t\t\"%s\" => %04d\n", UString(iter->first).ascii(), iter->second.branchOffset);
weinig@apple.com3412bb42008-09-01 21:22:54 +0000353 printf(" }\n");
oliver@apple.com8007f462008-07-24 00:49:46 +0000354 ++i;
weinig@apple.com4557e842008-12-09 01:06:14 +0000355 } while (i < m_rareData->m_stringSwitchJumpTables.size());
oliver@apple.com8007f462008-07-24 00:49:46 +0000356 }
357
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000358 printf("\n");
359}
360
361void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it) const
362{
363 int location = it - begin;
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000364 switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
mjs@apple.com8b246d62008-10-04 07:15:33 +0000365 case op_enter: {
366 printf("[%4d] enter\n", location);
oliver@apple.comecfd2242008-09-20 03:00:43 +0000367 break;
368 }
mjs@apple.com8b246d62008-10-04 07:15:33 +0000369 case op_enter_with_activation: {
cwzwarich@webkit.org5f5bc9e2008-10-07 03:53:47 +0000370 int r0 = (++it)->u.operand;
371 printf("[%4d] enter_with_activation %s\n", location, registerName(r0).c_str());
ggaren@apple.coma54a8892008-09-26 22:40:26 +0000372 break;
373 }
cwzwarich@webkit.org2f316b42008-10-04 20:32:21 +0000374 case op_create_arguments: {
375 printf("[%4d] create_arguments\n", location);
cwzwarich@webkit.org9e464ca2008-09-29 03:04:08 +0000376 break;
377 }
mjs@apple.com8b246d62008-10-04 07:15:33 +0000378 case op_convert_this: {
379 int r0 = (++it)->u.operand;
380 printf("[%4d] convert_this %s\n", location, registerName(r0).c_str());
381 break;
382 }
cwzwarich@webkit.orgef627552008-08-09 03:56:46 +0000383 case op_unexpected_load: {
384 int r0 = (++it)->u.operand;
385 int k0 = (++it)->u.operand;
weinig@apple.com4557e842008-12-09 01:06:14 +0000386 printf("[%4d] unexpected_load\t %s, %s\n", location, registerName(r0).c_str(), constantName(exec, k0, unexpectedConstant(k0)).c_str());
cwzwarich@webkit.orgef627552008-08-09 03:56:46 +0000387 break;
388 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000389 case op_new_object: {
390 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000391 printf("[%4d] new_object\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000392 break;
393 }
394 case op_new_array: {
darin@apple.com9ce79022008-06-28 15:50:49 +0000395 int dst = (++it)->u.operand;
396 int argv = (++it)->u.operand;
397 int argc = (++it)->u.operand;
398 printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(dst).c_str(), registerName(argv).c_str(), argc);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000399 break;
400 }
401 case op_new_regexp: {
402 int r0 = (++it)->u.operand;
403 int re0 = (++it)->u.operand;
weinig@apple.com4557e842008-12-09 01:06:14 +0000404 printf("[%4d] new_regexp\t %s, %s\n", location, registerName(r0).c_str(), regexpName(re0, regexp(re0)).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000405 break;
406 }
407 case op_mov: {
408 int r0 = (++it)->u.operand;
409 int r1 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000410 printf("[%4d] mov\t\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000411 break;
412 }
413 case op_not: {
414 printUnaryOp(location, it, "not");
415 break;
416 }
417 case op_eq: {
418 printBinaryOp(location, it, "eq");
419 break;
420 }
ggaren@apple.comf15b18802008-09-03 02:58:14 +0000421 case op_eq_null: {
422 printUnaryOp(location, it, "eq_null");
423 break;
424 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000425 case op_neq: {
426 printBinaryOp(location, it, "neq");
427 break;
428 }
ggaren@apple.comf15b18802008-09-03 02:58:14 +0000429 case op_neq_null: {
430 printUnaryOp(location, it, "neq_null");
431 break;
432 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000433 case op_stricteq: {
434 printBinaryOp(location, it, "stricteq");
435 break;
436 }
437 case op_nstricteq: {
438 printBinaryOp(location, it, "nstricteq");
439 break;
440 }
441 case op_less: {
442 printBinaryOp(location, it, "less");
443 break;
444 }
445 case op_lesseq: {
446 printBinaryOp(location, it, "lesseq");
447 break;
448 }
449 case op_pre_inc: {
450 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000451 printf("[%4d] pre_inc\t\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000452 break;
453 }
454 case op_pre_dec: {
455 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000456 printf("[%4d] pre_dec\t\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000457 break;
458 }
459 case op_post_inc: {
460 printUnaryOp(location, it, "post_inc");
461 break;
462 }
463 case op_post_dec: {
464 printUnaryOp(location, it, "post_dec");
465 break;
466 }
467 case op_to_jsnumber: {
468 printUnaryOp(location, it, "to_jsnumber");
469 break;
470 }
471 case op_negate: {
472 printUnaryOp(location, it, "negate");
473 break;
474 }
475 case op_add: {
476 printBinaryOp(location, it, "add");
barraclough@apple.comb8b15e22008-09-27 01:44:15 +0000477 ++it;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000478 break;
479 }
480 case op_mul: {
481 printBinaryOp(location, it, "mul");
barraclough@apple.comb8b15e22008-09-27 01:44:15 +0000482 ++it;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000483 break;
484 }
485 case op_div: {
486 printBinaryOp(location, it, "div");
487 break;
488 }
489 case op_mod: {
490 printBinaryOp(location, it, "mod");
491 break;
492 }
493 case op_sub: {
494 printBinaryOp(location, it, "sub");
barraclough@apple.comb8b15e22008-09-27 01:44:15 +0000495 ++it;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000496 break;
497 }
498 case op_lshift: {
499 printBinaryOp(location, it, "lshift");
500 break;
501 }
502 case op_rshift: {
503 printBinaryOp(location, it, "rshift");
504 break;
505 }
506 case op_urshift: {
507 printBinaryOp(location, it, "urshift");
508 break;
509 }
510 case op_bitand: {
511 printBinaryOp(location, it, "bitand");
barraclough@apple.comb8b15e22008-09-27 01:44:15 +0000512 ++it;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000513 break;
514 }
515 case op_bitxor: {
516 printBinaryOp(location, it, "bitxor");
barraclough@apple.comb8b15e22008-09-27 01:44:15 +0000517 ++it;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000518 break;
519 }
520 case op_bitor: {
521 printBinaryOp(location, it, "bitor");
barraclough@apple.comb8b15e22008-09-27 01:44:15 +0000522 ++it;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000523 break;
524 }
525 case op_bitnot: {
526 printUnaryOp(location, it, "bitnot");
527 break;
528 }
529 case op_instanceof: {
mjs@apple.com988df6c2008-09-15 02:13:10 +0000530 int r0 = (++it)->u.operand;
531 int r1 = (++it)->u.operand;
532 int r2 = (++it)->u.operand;
533 int r3 = (++it)->u.operand;
534 printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000535 break;
536 }
537 case op_typeof: {
538 printUnaryOp(location, it, "typeof");
539 break;
540 }
cwzwarich@webkit.org32346622008-09-15 00:26:08 +0000541 case op_is_undefined: {
542 printUnaryOp(location, it, "is_undefined");
543 break;
544 }
545 case op_is_boolean: {
546 printUnaryOp(location, it, "is_boolean");
547 break;
548 }
549 case op_is_number: {
550 printUnaryOp(location, it, "is_number");
551 break;
552 }
553 case op_is_string: {
554 printUnaryOp(location, it, "is_string");
555 break;
556 }
557 case op_is_object: {
558 printUnaryOp(location, it, "is_object");
559 break;
560 }
561 case op_is_function: {
562 printUnaryOp(location, it, "is_function");
563 break;
564 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000565 case op_in: {
566 printBinaryOp(location, it, "in");
567 break;
568 }
569 case op_resolve: {
570 int r0 = (++it)->u.operand;
571 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000572 printf("[%4d] resolve\t\t %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000573 break;
574 }
575 case op_resolve_skip: {
576 int r0 = (++it)->u.operand;
577 int id0 = (++it)->u.operand;
578 int skipLevels = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000579 printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), skipLevels);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000580 break;
581 }
oliver@apple.com70579b52008-09-16 05:53:15 +0000582 case op_resolve_global: {
583 int r0 = (++it)->u.operand;
darin@apple.com44331f82008-10-24 16:22:51 +0000584 JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell);
oliver@apple.com70579b52008-09-16 05:53:15 +0000585 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000586 printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str());
oliver@apple.com70579b52008-09-16 05:53:15 +0000587 it += 2;
588 break;
589 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000590 case op_get_scoped_var: {
591 int r0 = (++it)->u.operand;
592 int index = (++it)->u.operand;
593 int skipLevels = (++it)->u.operand;
weinig@apple.com3412bb42008-09-01 21:22:54 +0000594 printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(r0).c_str(), index, skipLevels);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000595 break;
596 }
597 case op_put_scoped_var: {
598 int index = (++it)->u.operand;
599 int skipLevels = (++it)->u.operand;
600 int r0 = (++it)->u.operand;
weinig@apple.com3412bb42008-09-01 21:22:54 +0000601 printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000602 break;
603 }
oliver@apple.com957eefc2008-09-10 09:23:35 +0000604 case op_get_global_var: {
605 int r0 = (++it)->u.operand;
darin@apple.com44331f82008-10-24 16:22:51 +0000606 JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell);
oliver@apple.com957eefc2008-09-10 09:23:35 +0000607 int index = (++it)->u.operand;
608 printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
609 break;
610 }
611 case op_put_global_var: {
darin@apple.com44331f82008-10-24 16:22:51 +0000612 JSValue* scope = static_cast<JSValue*>((++it)->u.jsCell);
oliver@apple.com957eefc2008-09-10 09:23:35 +0000613 int index = (++it)->u.operand;
614 int r0 = (++it)->u.operand;
615 printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str());
616 break;
617 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000618 case op_resolve_base: {
619 int r0 = (++it)->u.operand;
620 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000621 printf("[%4d] resolve_base\t %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000622 break;
623 }
624 case op_resolve_with_base: {
625 int r0 = (++it)->u.operand;
626 int r1 = (++it)->u.operand;
627 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000628 printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000629 break;
630 }
631 case op_resolve_func: {
632 int r0 = (++it)->u.operand;
633 int r1 = (++it)->u.operand;
634 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000635 printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000636 break;
637 }
638 case op_get_by_id: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000639 printGetByIdOp(location, it, m_identifiers, "get_by_id");
weinig@apple.com3412bb42008-09-01 21:22:54 +0000640 break;
641 }
642 case op_get_by_id_self: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000643 printGetByIdOp(location, it, m_identifiers, "get_by_id_self");
weinig@apple.com3412bb42008-09-01 21:22:54 +0000644 break;
645 }
barraclough@apple.combc0fea62008-11-22 03:34:43 +0000646 case op_get_by_id_self_list: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000647 printGetByIdOp(location, it, m_identifiers, "get_by_id_self_list");
barraclough@apple.combc0fea62008-11-22 03:34:43 +0000648 break;
649 }
weinig@apple.com3412bb42008-09-01 21:22:54 +0000650 case op_get_by_id_proto: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000651 printGetByIdOp(location, it, m_identifiers, "get_by_id_proto");
weinig@apple.com3412bb42008-09-01 21:22:54 +0000652 break;
653 }
barraclough@apple.comf5f74822008-11-21 05:04:19 +0000654 case op_get_by_id_proto_list: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000655 printGetByIdOp(location, it, m_identifiers, "op_get_by_id_proto_list");
barraclough@apple.comf5f74822008-11-21 05:04:19 +0000656 break;
657 }
weinig@apple.com3412bb42008-09-01 21:22:54 +0000658 case op_get_by_id_chain: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000659 printGetByIdOp(location, it, m_identifiers, "get_by_id_chain");
weinig@apple.com3412bb42008-09-01 21:22:54 +0000660 break;
661 }
662 case op_get_by_id_generic: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000663 printGetByIdOp(location, it, m_identifiers, "get_by_id_generic");
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000664 break;
665 }
ggaren@apple.combc363092008-09-03 05:04:39 +0000666 case op_get_array_length: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000667 printGetByIdOp(location, it, m_identifiers, "get_array_length");
ggaren@apple.combc363092008-09-03 05:04:39 +0000668 break;
669 }
670 case op_get_string_length: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000671 printGetByIdOp(location, it, m_identifiers, "get_string_length");
ggaren@apple.combc363092008-09-03 05:04:39 +0000672 break;
673 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000674 case op_put_by_id: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000675 printPutByIdOp(location, it, m_identifiers, "put_by_id");
weinig@apple.com3412bb42008-09-01 21:22:54 +0000676 break;
677 }
678 case op_put_by_id_replace: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000679 printPutByIdOp(location, it, m_identifiers, "put_by_id_replace");
weinig@apple.com3412bb42008-09-01 21:22:54 +0000680 break;
681 }
oliver@apple.come3c5d0e2008-09-14 08:18:49 +0000682 case op_put_by_id_transition: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000683 printPutByIdOp(location, it, m_identifiers, "put_by_id_transition");
oliver@apple.come3c5d0e2008-09-14 08:18:49 +0000684 break;
685 }
weinig@apple.com3412bb42008-09-01 21:22:54 +0000686 case op_put_by_id_generic: {
weinig@apple.comcb26d812008-12-06 22:01:05 +0000687 printPutByIdOp(location, it, m_identifiers, "put_by_id_generic");
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000688 break;
689 }
690 case op_put_getter: {
691 int r0 = (++it)->u.operand;
692 int id0 = (++it)->u.operand;
693 int r1 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000694 printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000695 break;
696 }
697 case op_put_setter: {
698 int r0 = (++it)->u.operand;
699 int id0 = (++it)->u.operand;
700 int r1 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000701 printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000702 break;
703 }
704 case op_del_by_id: {
705 int r0 = (++it)->u.operand;
706 int r1 = (++it)->u.operand;
707 int id0 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000708 printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000709 break;
710 }
711 case op_get_by_val: {
712 int r0 = (++it)->u.operand;
713 int r1 = (++it)->u.operand;
714 int r2 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000715 printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000716 break;
717 }
718 case op_put_by_val: {
719 int r0 = (++it)->u.operand;
720 int r1 = (++it)->u.operand;
721 int r2 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000722 printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000723 break;
724 }
725 case op_del_by_val: {
726 int r0 = (++it)->u.operand;
727 int r1 = (++it)->u.operand;
728 int r2 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000729 printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000730 break;
731 }
732 case op_put_by_index: {
733 int r0 = (++it)->u.operand;
734 unsigned n0 = (++it)->u.operand;
735 int r1 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000736 printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(r0).c_str(), n0, registerName(r1).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000737 break;
738 }
739 case op_jmp: {
740 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000741 printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000742 break;
743 }
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000744 case op_loop: {
745 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000746 printf("[%4d] loop\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset));
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000747 break;
748 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000749 case op_jtrue: {
750 printConditionalJump(begin, it, location, "jtrue");
751 break;
752 }
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000753 case op_loop_if_true: {
754 printConditionalJump(begin, it, location, "loop_if_true");
755 break;
756 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000757 case op_jfalse: {
758 printConditionalJump(begin, it, location, "jfalse");
759 break;
760 }
cwzwarich@webkit.orgb8b30242008-10-22 21:06:30 +0000761 case op_jeq_null: {
762 printConditionalJump(begin, it, location, "jeq_null");
763 break;
764 }
765 case op_jneq_null: {
766 printConditionalJump(begin, it, location, "jneq_null");
767 break;
768 }
cwzwarich@webkit.org7b04fef2008-06-30 06:17:01 +0000769 case op_jnless: {
770 int r0 = (++it)->u.operand;
771 int r1 = (++it)->u.operand;
772 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000773 printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
cwzwarich@webkit.org7b04fef2008-06-30 06:17:01 +0000774 break;
775 }
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000776 case op_loop_if_less: {
777 int r0 = (++it)->u.operand;
778 int r1 = (++it)->u.operand;
779 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000780 printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
oliver@apple.comc8f3a752008-06-28 04:02:03 +0000781 break;
782 }
cwzwarich@webkit.org4be196a2008-09-14 23:01:03 +0000783 case op_loop_if_lesseq: {
784 int r0 = (++it)->u.operand;
785 int r1 = (++it)->u.operand;
786 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000787 printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
cwzwarich@webkit.org4be196a2008-09-14 23:01:03 +0000788 break;
789 }
oliver@apple.com8007f462008-07-24 00:49:46 +0000790 case op_switch_imm: {
791 int tableIndex = (++it)->u.operand;
792 int defaultTarget = (++it)->u.operand;
793 int scrutineeRegister = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000794 printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
oliver@apple.com8007f462008-07-24 00:49:46 +0000795 break;
796 }
797 case op_switch_char: {
798 int tableIndex = (++it)->u.operand;
799 int defaultTarget = (++it)->u.operand;
800 int scrutineeRegister = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000801 printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
oliver@apple.com8007f462008-07-24 00:49:46 +0000802 break;
803 }
804 case op_switch_string: {
805 int tableIndex = (++it)->u.operand;
806 int defaultTarget = (++it)->u.operand;
807 int scrutineeRegister = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000808 printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str());
oliver@apple.com8007f462008-07-24 00:49:46 +0000809 break;
810 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000811 case op_new_func: {
812 int r0 = (++it)->u.operand;
813 int f0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000814 printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(r0).c_str(), f0);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000815 break;
816 }
817 case op_new_func_exp: {
818 int r0 = (++it)->u.operand;
819 int f0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000820 printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(r0).c_str(), f0);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000821 break;
822 }
823 case op_call: {
ggaren@apple.com68313b02008-11-13 00:48:23 +0000824 int dst = (++it)->u.operand;
825 int func = (++it)->u.operand;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000826 int argCount = (++it)->u.operand;
ggaren@apple.com107bd0e2008-09-24 00:27:18 +0000827 int registerOffset = (++it)->u.operand;
ggaren@apple.com68313b02008-11-13 00:48:23 +0000828 printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000829 break;
830 }
831 case op_call_eval: {
ggaren@apple.com68313b02008-11-13 00:48:23 +0000832 int dst = (++it)->u.operand;
833 int func = (++it)->u.operand;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000834 int argCount = (++it)->u.operand;
ggaren@apple.com107bd0e2008-09-24 00:27:18 +0000835 int registerOffset = (++it)->u.operand;
ggaren@apple.com68313b02008-11-13 00:48:23 +0000836 printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000837 break;
838 }
cwzwarich@webkit.orga3b5f8a2008-10-06 06:00:58 +0000839 case op_tear_off_activation: {
mjs@apple.com6c3268c2008-10-06 18:31:07 +0000840 int r0 = (++it)->u.operand;
841 printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str());
cwzwarich@webkit.orga3b5f8a2008-10-06 06:00:58 +0000842 break;
843 }
844 case op_tear_off_arguments: {
cwzwarich@webkit.org5f5bc9e2008-10-07 03:53:47 +0000845 printf("[%4d] tear_off_arguments\n", location);
cwzwarich@webkit.orga3b5f8a2008-10-06 06:00:58 +0000846 break;
847 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000848 case op_ret: {
849 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000850 printf("[%4d] ret\t\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000851 break;
852 }
853 case op_construct: {
ggaren@apple.com68313b02008-11-13 00:48:23 +0000854 int dst = (++it)->u.operand;
855 int func = (++it)->u.operand;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000856 int argCount = (++it)->u.operand;
ggaren@apple.com107bd0e2008-09-24 00:27:18 +0000857 int registerOffset = (++it)->u.operand;
ggaren@apple.com68313b02008-11-13 00:48:23 +0000858 int proto = (++it)->u.operand;
859 int thisRegister = (++it)->u.operand;
860 printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset, registerName(proto).c_str(), registerName(thisRegister).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000861 break;
862 }
ggaren@apple.com743b98b2008-09-15 23:37:31 +0000863 case op_construct_verify: {
864 int r0 = (++it)->u.operand;
865 int r1 = (++it)->u.operand;
866 printf("[%4d] construct_verify\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
867 break;
868 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000869 case op_get_pnames: {
870 int r0 = (++it)->u.operand;
871 int r1 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000872 printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000873 break;
874 }
875 case op_next_pname: {
876 int dest = (++it)->u.operand;
877 int iter = (++it)->u.operand;
878 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000879 printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset));
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000880 break;
881 }
882 case op_push_scope: {
883 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000884 printf("[%4d] push_scope\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000885 break;
886 }
887 case op_pop_scope: {
aroben@apple.com82c32362008-05-27 23:25:09 +0000888 printf("[%4d] pop_scope\n", location);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000889 break;
890 }
oliver@apple.comf66dcf92008-08-03 09:58:21 +0000891 case op_push_new_scope: {
892 int r0 = (++it)->u.operand;
893 int id0 = (++it)->u.operand;
894 int r1 = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000895 printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
oliver@apple.comf66dcf92008-08-03 09:58:21 +0000896 break;
897 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000898 case op_jmp_scopes: {
899 int scopeDelta = (++it)->u.operand;
900 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000901 printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, locationForOffset(begin, it, offset));
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000902 break;
903 }
904 case op_catch: {
905 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000906 printf("[%4d] catch\t\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000907 break;
908 }
909 case op_throw: {
910 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000911 printf("[%4d] throw\t\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000912 break;
913 }
914 case op_new_error: {
915 int r0 = (++it)->u.operand;
916 int errorType = (++it)->u.operand;
917 int k0 = (++it)->u.operand;
weinig@apple.com4557e842008-12-09 01:06:14 +0000918 printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(r0).c_str(), errorType, constantName(exec, k0, unexpectedConstant(k0)).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000919 break;
920 }
921 case op_jsr: {
922 int retAddrDst = (++it)->u.operand;
923 int offset = (++it)->u.operand;
weinig@apple.comcb26d812008-12-06 22:01:05 +0000924 printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset));
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000925 break;
926 }
927 case op_sret: {
928 int retAddrSrc = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000929 printf("[%4d] sret\t\t %s\n", location, registerName(retAddrSrc).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000930 break;
931 }
932 case op_debug: {
933 int debugHookID = (++it)->u.operand;
934 int firstLine = (++it)->u.operand;
935 int lastLine = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000936 printf("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine);
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000937 break;
938 }
ggaren@apple.com4b8c0fb2008-10-20 16:48:30 +0000939 case op_profile_will_call: {
940 int function = (++it)->u.operand;
941 printf("[%4d] profile_will_call %s\n", location, registerName(function).c_str());
942 break;
943 }
944 case op_profile_did_call: {
945 int function = (++it)->u.operand;
946 printf("[%4d] profile_did_call\t %s\n", location, registerName(function).c_str());
947 break;
948 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000949 case op_end: {
950 int r0 = (++it)->u.operand;
aroben@apple.com82c32362008-05-27 23:25:09 +0000951 printf("[%4d] end\t\t %s\n", location, registerName(r0).c_str());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000952 break;
953 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +0000954 }
955}
956
ggaren@apple.com47d3f052008-11-15 21:37:49 +0000957#endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
weinig@apple.com3412bb42008-09-01 21:22:54 +0000958
weinig@apple.com3f9a9592008-12-08 21:40:15 +0000959#if DUMP_CODE_BLOCK_STATISTICS
960static HashSet<CodeBlock*> liveCodeBlockSet;
961#endif
962
weinig@apple.com67940d52008-12-09 00:14:58 +0000963#define FOR_EACH_MEMBER_VECTOR(macro) \
964 macro(instructions) \
965 macro(globalResolveInstructions) \
966 macro(propertyAccessInstructions) \
967 macro(callLinkInfos) \
968 macro(linkedCallerList) \
969 macro(identifiers) \
970 macro(functionExpressions) \
971 macro(constantRegisters) \
972 macro(expressionInfo) \
973 macro(lineInfo) \
weinig@apple.com4557e842008-12-09 01:06:14 +0000974
975#define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \
weinig@apple.com67940d52008-12-09 00:14:58 +0000976 macro(regexps) \
977 macro(functions) \
978 macro(unexpectedConstants) \
979 macro(exceptionHandlers) \
980 macro(immediateSwitchJumpTables) \
981 macro(characterSwitchJumpTables) \
982 macro(stringSwitchJumpTables)
983
weinig@apple.com3f9a9592008-12-08 21:40:15 +0000984void CodeBlock::dumpStatistics()
985{
986#if DUMP_CODE_BLOCK_STATISTICS
weinig@apple.com67940d52008-12-09 00:14:58 +0000987
988 #define DEFINE_VARS(name) size_t name##IsNotEmpty = 0;
989 FOR_EACH_MEMBER_VECTOR(DEFINE_VARS)
weinig@apple.com15d40092008-12-09 05:27:10 +0000990 FOR_EACH_MEMBER_VECTOR_RARE_DATA(DEFINE_VARS)
weinig@apple.com67940d52008-12-09 00:14:58 +0000991 #undef DEFINE_VARS
992
993 // Non-vector data members
994 size_t jitReturnAddressVPCMapIsNotEmpty = 0;
995 size_t evalCodeCacheIsNotEmpty = 0;
996
weinig@apple.com4557e842008-12-09 01:06:14 +0000997 size_t hasRareData = 0;
998
weinig@apple.com67940d52008-12-09 00:14:58 +0000999 HashSet<CodeBlock*>::const_iterator end = liveCodeBlockSet.end();
1000 for (HashSet<CodeBlock*>::const_iterator it = liveCodeBlockSet.begin(); it != end; ++it) {
1001 CodeBlock* codeBlock = *it;
1002
1003 #define GET_STATS(name) if (!codeBlock->m_##name.isEmpty()) { name##IsNotEmpty++; }
1004 FOR_EACH_MEMBER_VECTOR(GET_STATS)
1005 #undef GET_STATS
1006
1007 if (!codeBlock->m_jitReturnAddressVPCMap.isEmpty())
1008 jitReturnAddressVPCMapIsNotEmpty++;
weinig@apple.com4557e842008-12-09 01:06:14 +00001009
1010 if (codeBlock->m_rareData) {
1011 hasRareData++;
1012 #define GET_STATS(name) if (!codeBlock->m_rareData->m_##name.isEmpty()) { name##IsNotEmpty++; }
1013 FOR_EACH_MEMBER_VECTOR_RARE_DATA(GET_STATS)
1014 #undef GET_STATS
1015
1016 if (!codeBlock->m_rareData->m_evalCodeCache.isEmpty())
1017 evalCodeCacheIsNotEmpty++;
1018 }
weinig@apple.com67940d52008-12-09 00:14:58 +00001019 }
1020
weinig@apple.com3f9a9592008-12-08 21:40:15 +00001021 printf("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size());
1022 printf("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock));
weinig@apple.com67940d52008-12-09 00:14:58 +00001023
weinig@apple.com4557e842008-12-09 01:06:14 +00001024 printf("Number of CodeBlocks with rare data: %zu\n", hasRareData);
1025
weinig@apple.com67940d52008-12-09 00:14:58 +00001026 #define PRINT_STATS(name) printf("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty);
1027 FOR_EACH_MEMBER_VECTOR(PRINT_STATS)
weinig@apple.com4557e842008-12-09 01:06:14 +00001028 FOR_EACH_MEMBER_VECTOR_RARE_DATA(PRINT_STATS)
weinig@apple.com67940d52008-12-09 00:14:58 +00001029 #undef PRINT_STATS
weinig@apple.com4557e842008-12-09 01:06:14 +00001030
weinig@apple.com67940d52008-12-09 00:14:58 +00001031 printf("Number of CodeBlocks with jitReturnAddressVPCMap: %zu\n", jitReturnAddressVPCMapIsNotEmpty);
1032 printf("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty);
weinig@apple.com3f9a9592008-12-08 21:40:15 +00001033#else
1034 printf("Dumping CodeBlock statistics is not enabled.\n");
1035#endif
1036}
1037
1038
weinig@apple.com0e9a7ee2008-12-06 22:31:14 +00001039CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
1040 : m_numCalleeRegisters(0)
1041 , m_numConstants(0)
1042 , m_numVars(0)
1043 , m_numParameters(0)
1044 , m_ownerNode(ownerNode)
1045 , m_globalData(0)
1046#if ENABLE(JIT)
1047 , m_jitCode(0)
1048#endif
1049 , m_needsFullScopeChain(ownerNode->needsActivation())
1050 , m_usesEval(ownerNode->usesEval())
1051 , m_codeType(codeType)
1052 , m_source(sourceProvider)
1053 , m_sourceOffset(sourceOffset)
1054{
1055 ASSERT(m_source);
weinig@apple.com3f9a9592008-12-08 21:40:15 +00001056
1057#if DUMP_CODE_BLOCK_STATISTICS
1058 liveCodeBlockSet.add(this);
1059#endif
weinig@apple.com0e9a7ee2008-12-06 22:31:14 +00001060}
1061
weinig@apple.com3412bb42008-09-01 21:22:54 +00001062CodeBlock::~CodeBlock()
1063{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001064 for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
1065 derefStructures(&m_instructions[m_globalResolveInstructions[i]]);
1066
1067 for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
1068 derefStructures(&m_instructions[m_propertyAccessInstructions[i].bytecodeIndex]);
barraclough@apple.come9642652008-10-23 22:29:54 +00001069 }
1070
weinig@apple.comcb26d812008-12-06 22:01:05 +00001071 for (size_t size = m_callLinkInfos.size(), i = 0; i < size; ++i) {
1072 CallLinkInfo* callLinkInfo = &m_callLinkInfos[i];
barraclough@apple.come9642652008-10-23 22:29:54 +00001073 if (callLinkInfo->isLinked())
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001074 callLinkInfo->callee->removeCaller(callLinkInfo);
barraclough@apple.com71500d52008-09-15 02:18:13 +00001075 }
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001076
ggaren@apple.comf272d2d2008-11-17 04:25:37 +00001077#if ENABLE(JIT)
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001078 unlinkCallers();
mrowe@apple.comf88a4632008-09-07 05:44:58 +00001079#endif
weinig@apple.com3f9a9592008-12-08 21:40:15 +00001080
1081#if DUMP_CODE_BLOCK_STATISTICS
1082 liveCodeBlockSet.remove(this);
1083#endif
weinig@apple.com3412bb42008-09-01 21:22:54 +00001084}
1085
ggaren@apple.comf272d2d2008-11-17 04:25:37 +00001086#if ENABLE(JIT)
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001087void CodeBlock::unlinkCallers()
1088{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001089 size_t size = m_linkedCallerList.size();
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001090 for (size_t i = 0; i < size; ++i) {
weinig@apple.comcb26d812008-12-06 22:01:05 +00001091 CallLinkInfo* currentCaller = m_linkedCallerList[i];
ggaren@apple.com4f7d7a92008-11-17 03:34:05 +00001092 JIT::unlinkCall(currentCaller);
barraclough@apple.come9642652008-10-23 22:29:54 +00001093 currentCaller->setUnlinked();
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001094 }
weinig@apple.comcb26d812008-12-06 22:01:05 +00001095 m_linkedCallerList.clear();
barraclough@apple.com3a4eb9b2008-10-18 02:51:52 +00001096}
1097#endif
1098
darin@apple.coma9778f92008-11-16 04:40:06 +00001099void CodeBlock::derefStructures(Instruction* vPC) const
weinig@apple.com3412bb42008-09-01 21:22:54 +00001100{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001101 Interpreter* interpreter = m_globalData->interpreter;
weinig@apple.com3412bb42008-09-01 21:22:54 +00001102
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001103 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001104 vPC[4].u.structure->deref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001105 return;
1106 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001107 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001108 vPC[4].u.structure->deref();
1109 vPC[5].u.structure->deref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001110 return;
1111 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001112 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001113 vPC[4].u.structure->deref();
1114 vPC[5].u.structureChain->deref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001115 return;
1116 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001117 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001118 vPC[4].u.structure->deref();
1119 vPC[5].u.structure->deref();
1120 vPC[6].u.structureChain->deref();
oliver@apple.come3c5d0e2008-09-14 08:18:49 +00001121 return;
1122 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001123 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001124 vPC[4].u.structure->deref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001125 return;
1126 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001127 if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001128 if(vPC[4].u.structure)
1129 vPC[4].u.structure->deref();
oliver@apple.com70579b52008-09-16 05:53:15 +00001130 return;
1131 }
barraclough@apple.combc0fea62008-11-22 03:34:43 +00001132 if ((vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list))
1133 || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self_list))) {
1134 PolymorphicAccessStructureList* polymorphicStructures = vPC[4].u.polymorphicStructures;
1135 polymorphicStructures->derefStructures(vPC[5].u.operand);
1136 delete polymorphicStructures;
barraclough@apple.comf5f74822008-11-21 05:04:19 +00001137 return;
1138 }
1139
darin@apple.coma9778f92008-11-16 04:40:06 +00001140 // These instructions don't ref their Structures.
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001141 ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_get_array_length) || vPC[0].u.opcode == interpreter->getOpcode(op_get_string_length));
weinig@apple.com3412bb42008-09-01 21:22:54 +00001142}
1143
darin@apple.coma9778f92008-11-16 04:40:06 +00001144void CodeBlock::refStructures(Instruction* vPC) const
weinig@apple.com3412bb42008-09-01 21:22:54 +00001145{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001146 Interpreter* interpreter = m_globalData->interpreter;
weinig@apple.com3412bb42008-09-01 21:22:54 +00001147
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001148 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001149 vPC[4].u.structure->ref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001150 return;
1151 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001152 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001153 vPC[4].u.structure->ref();
1154 vPC[5].u.structure->ref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001155 return;
1156 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001157 if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001158 vPC[4].u.structure->ref();
1159 vPC[5].u.structureChain->ref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001160 return;
1161 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001162 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001163 vPC[4].u.structure->ref();
1164 vPC[5].u.structure->ref();
1165 vPC[6].u.structureChain->ref();
oliver@apple.come3c5d0e2008-09-14 08:18:49 +00001166 return;
1167 }
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001168 if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
darin@apple.coma9778f92008-11-16 04:40:06 +00001169 vPC[4].u.structure->ref();
weinig@apple.com3412bb42008-09-01 21:22:54 +00001170 return;
1171 }
1172
darin@apple.coma9778f92008-11-16 04:40:06 +00001173 // These instructions don't ref their Structures.
ggaren@apple.com47d3f052008-11-15 21:37:49 +00001174 ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic));
weinig@apple.com3412bb42008-09-01 21:22:54 +00001175}
cwzwarich@webkit.org217b5402008-08-09 11:00:38 +00001176
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001177void CodeBlock::mark()
1178{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001179 for (size_t i = 0; i < m_constantRegisters.size(); ++i)
1180 if (!m_constantRegisters[i].marked())
1181 m_constantRegisters[i].mark();
cwzwarich@webkit.org300bb752008-08-06 10:37:34 +00001182
weinig@apple.comcb26d812008-12-06 22:01:05 +00001183 for (size_t i = 0; i < m_functionExpressions.size(); ++i)
1184 m_functionExpressions[i]->body()->mark();
weinig@apple.com4557e842008-12-09 01:06:14 +00001185
1186 if (m_rareData) {
1187 for (size_t i = 0; i < m_rareData->m_functions.size(); ++i)
1188 m_rareData->m_functions[i]->body()->mark();
1189
1190 for (size_t i = 0; i < m_rareData->m_unexpectedConstants.size(); ++i) {
1191 if (!m_rareData->m_unexpectedConstants[i]->marked())
1192 m_rareData->m_unexpectedConstants[i]->mark();
1193 }
1194 }
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001195}
1196
1197bool CodeBlock::getHandlerForVPC(const Instruction* vPC, Instruction*& target, int& scopeDepth)
1198{
weinig@apple.com4557e842008-12-09 01:06:14 +00001199 if (!m_rareData)
1200 return false;
1201
1202 Vector<HandlerInfo>::iterator ptr = m_rareData->m_exceptionHandlers.begin();
1203 Vector<HandlerInfo>::iterator end = m_rareData->m_exceptionHandlers.end();
weinig@apple.comcb26d812008-12-06 22:01:05 +00001204 unsigned addressOffset = vPC - m_instructions.begin();
1205 ASSERT(addressOffset < m_instructions.size());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001206
1207 for (; ptr != end; ++ptr) {
1208 // Handlers are ordered innermost first, so the first handler we encounter
1209 // that contains the source address is the correct handler to use.
1210 if (ptr->start <= addressOffset && ptr->end >= addressOffset) {
1211 scopeDepth = ptr->scopeDepth;
weinig@apple.comcb26d812008-12-06 22:01:05 +00001212 target = m_instructions.begin() + ptr->target;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001213 return true;
1214 }
1215 }
1216 return false;
1217}
1218
mrowe@apple.comf88a4632008-09-07 05:44:58 +00001219void* CodeBlock::nativeExceptionCodeForHandlerVPC(const Instruction* handlerVPC)
1220{
weinig@apple.com4557e842008-12-09 01:06:14 +00001221 if (!m_rareData)
1222 return 0;
1223
1224 Vector<HandlerInfo>::iterator ptr = m_rareData->m_exceptionHandlers.begin();
1225 Vector<HandlerInfo>::iterator end = m_rareData->m_exceptionHandlers.end();
mrowe@apple.comf88a4632008-09-07 05:44:58 +00001226
1227 for (; ptr != end; ++ptr) {
weinig@apple.comcb26d812008-12-06 22:01:05 +00001228 Instruction*target = m_instructions.begin() + ptr->target;
mrowe@apple.comf88a4632008-09-07 05:44:58 +00001229 if (handlerVPC == target)
1230 return ptr->nativeCode;
1231 }
1232
1233 return 0;
1234}
1235
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001236int CodeBlock::lineNumberForVPC(const Instruction* vPC)
1237{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001238 unsigned instructionOffset = vPC - m_instructions.begin();
1239 ASSERT(instructionOffset < m_instructions.size());
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001240
weinig@apple.comcb26d812008-12-06 22:01:05 +00001241 if (!m_lineInfo.size())
1242 return m_ownerNode->source().firstLine(); // Empty function
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001243
1244 int low = 0;
weinig@apple.comcb26d812008-12-06 22:01:05 +00001245 int high = m_lineInfo.size();
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001246 while (low < high) {
1247 int mid = low + (high - low) / 2;
weinig@apple.comcb26d812008-12-06 22:01:05 +00001248 if (m_lineInfo[mid].instructionOffset <= instructionOffset)
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001249 low = mid + 1;
1250 else
1251 high = mid;
1252 }
ggaren@apple.combe95ccf2008-10-25 19:59:47 +00001253
1254 if (!low)
weinig@apple.comcb26d812008-12-06 22:01:05 +00001255 return m_ownerNode->source().firstLine();
1256 return m_lineInfo[low - 1].lineNumber;
mrowe@apple.com2f6dfdf2008-05-22 01:20:45 +00001257}
1258
oliver@apple.com90b88ae2008-07-19 01:44:24 +00001259int CodeBlock::expressionRangeForVPC(const Instruction* vPC, int& divot, int& startOffset, int& endOffset)
1260{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001261 unsigned instructionOffset = vPC - m_instructions.begin();
1262 ASSERT(instructionOffset < m_instructions.size());
oliver@apple.com90b88ae2008-07-19 01:44:24 +00001263
weinig@apple.comcb26d812008-12-06 22:01:05 +00001264 if (!m_expressionInfo.size()) {
oliver@apple.com90b88ae2008-07-19 01:44:24 +00001265 // We didn't think anything could throw. Apparently we were wrong.
1266 startOffset = 0;
1267 endOffset = 0;
1268 divot = 0;
1269 return lineNumberForVPC(vPC);
1270 }
1271
1272 int low = 0;
weinig@apple.comcb26d812008-12-06 22:01:05 +00001273 int high = m_expressionInfo.size();
oliver@apple.com90b88ae2008-07-19 01:44:24 +00001274 while (low < high) {
1275 int mid = low + (high - low) / 2;
weinig@apple.comcb26d812008-12-06 22:01:05 +00001276 if (m_expressionInfo[mid].instructionOffset <= instructionOffset)
oliver@apple.com90b88ae2008-07-19 01:44:24 +00001277 low = mid + 1;
1278 else
1279 high = mid;
1280 }
1281
1282 ASSERT(low);
1283 if (!low) {
1284 startOffset = 0;
1285 endOffset = 0;
1286 divot = 0;
1287 return lineNumberForVPC(vPC);
1288 }
1289
weinig@apple.comcb26d812008-12-06 22:01:05 +00001290 startOffset = m_expressionInfo[low - 1].startOffset;
1291 endOffset = m_expressionInfo[low - 1].endOffset;
1292 divot = m_expressionInfo[low - 1].divotPoint + m_sourceOffset;
oliver@apple.com90b88ae2008-07-19 01:44:24 +00001293 return lineNumberForVPC(vPC);
1294}
1295
weinig@apple.com9d9d25d2008-12-05 20:27:58 +00001296void CodeBlock::shrinkToFit()
1297{
weinig@apple.comcb26d812008-12-06 22:01:05 +00001298 m_instructions.shrinkToFit();
1299
1300 m_globalResolveInstructions.shrinkToFit();
1301 m_propertyAccessInstructions.shrinkToFit();
1302 m_callLinkInfos.shrinkToFit();
1303 m_linkedCallerList.shrinkToFit();
weinig@apple.comcb26d812008-12-06 22:01:05 +00001304 m_expressionInfo.shrinkToFit();
1305 m_lineInfo.shrinkToFit();
weinig@apple.comcb26d812008-12-06 22:01:05 +00001306 m_identifiers.shrinkToFit();
weinig@apple.comcb26d812008-12-06 22:01:05 +00001307 m_functionExpressions.shrinkToFit();
1308 m_constantRegisters.shrinkToFit();
weinig@apple.comcb26d812008-12-06 22:01:05 +00001309
weinig@apple.com4557e842008-12-09 01:06:14 +00001310 if (m_rareData) {
1311 m_rareData->m_exceptionHandlers.shrinkToFit();
1312 m_rareData->m_functions.shrinkToFit();
1313 m_rareData->m_unexpectedConstants.shrinkToFit();
1314 m_rareData->m_regexps.shrinkToFit();
1315 m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
1316 m_rareData->m_characterSwitchJumpTables.shrinkToFit();
1317 m_rareData->m_stringSwitchJumpTables.shrinkToFit();
1318 }
weinig@apple.com9d9d25d2008-12-05 20:27:58 +00001319}
1320
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +00001321} // namespace JSC