blob: f40fd3e6be717df28e5df7ddc16ad57582467995 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "disassembler.h"
31#include "disasm.h"
32#include "macro-assembler.h"
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000033#include "jsregexp.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034
35namespace v8 { namespace internal {
36
37#ifdef DEBUG
38
39static const char* TypeToString(InstanceType type);
40
41
42void Object::Print() {
43 if (IsSmi()) {
44 Smi::cast(this)->SmiPrint();
45 } else if (IsFailure()) {
46 Failure::cast(this)->FailurePrint();
47 } else {
48 HeapObject::cast(this)->HeapObjectPrint();
49 }
50 Flush();
51}
52
53
54void Object::PrintLn() {
55 Print();
56 PrintF("\n");
57}
58
59
60void Object::Verify() {
61 if (IsSmi()) {
62 Smi::cast(this)->SmiVerify();
63 } else if (IsFailure()) {
64 Failure::cast(this)->FailureVerify();
65 } else {
66 HeapObject::cast(this)->HeapObjectVerify();
67 }
68}
69
70
71void Object::VerifyPointer(Object* p) {
72 if (p->IsHeapObject()) {
73 HeapObject::VerifyHeapPointer(p);
74 } else {
75 ASSERT(p->IsSmi());
76 }
77}
78
79
80void Smi::SmiVerify() {
81 ASSERT(IsSmi());
82}
83
84
85void Failure::FailureVerify() {
86 ASSERT(IsFailure());
87}
88
89
90void HeapObject::PrintHeader(const char* id) {
91 PrintF("%p: [%s]\n", this, id);
92}
93
94
95void HeapObject::HeapObjectPrint() {
96 InstanceType instance_type = map()->instance_type();
97
98 HandleScope scope;
99 if (instance_type < FIRST_NONSTRING_TYPE) {
100 String::cast(this)->StringPrint();
101 return;
102 }
103
104 switch (instance_type) {
105 case MAP_TYPE:
106 Map::cast(this)->MapPrint();
107 break;
108 case HEAP_NUMBER_TYPE:
109 HeapNumber::cast(this)->HeapNumberPrint();
110 break;
111 case FIXED_ARRAY_TYPE:
112 FixedArray::cast(this)->FixedArrayPrint();
113 break;
114 case BYTE_ARRAY_TYPE:
115 ByteArray::cast(this)->ByteArrayPrint();
116 break;
117 case FILLER_TYPE:
118 PrintF("filler");
119 break;
120 case JS_OBJECT_TYPE: // fall through
ager@chromium.org32912102009-01-16 10:38:43 +0000121 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000122 case JS_ARRAY_TYPE:
ager@chromium.org236ad962008-09-25 09:45:57 +0000123 case JS_REGEXP_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000124 JSObject::cast(this)->JSObjectPrint();
125 break;
126 case ODDBALL_TYPE:
127 Oddball::cast(this)->to_string()->Print();
128 break;
129 case JS_FUNCTION_TYPE:
130 JSFunction::cast(this)->JSFunctionPrint();
131 break;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000132 case JS_GLOBAL_PROXY_TYPE:
133 JSGlobalProxy::cast(this)->JSGlobalProxyPrint();
134 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135 case JS_GLOBAL_OBJECT_TYPE:
136 JSGlobalObject::cast(this)->JSGlobalObjectPrint();
137 break;
138 case JS_BUILTINS_OBJECT_TYPE:
139 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
140 break;
141 case JS_VALUE_TYPE:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000142 PrintF("Value wrapper around:");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000143 JSValue::cast(this)->value()->Print();
144 break;
145 case CODE_TYPE:
146 Code::cast(this)->CodePrint();
147 break;
148 case PROXY_TYPE:
149 Proxy::cast(this)->ProxyPrint();
150 break;
151 case SHARED_FUNCTION_INFO_TYPE:
152 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint();
153 break;
154
155#define MAKE_STRUCT_CASE(NAME, Name, name) \
156 case NAME##_TYPE: \
157 Name::cast(this)->Name##Print(); \
158 break;
159 STRUCT_LIST(MAKE_STRUCT_CASE)
160#undef MAKE_STRUCT_CASE
161
162 default:
163 PrintF("UNKNOWN TYPE %d", map()->instance_type());
164 UNREACHABLE();
165 break;
166 }
167}
168
169
170void HeapObject::HeapObjectVerify() {
171 InstanceType instance_type = map()->instance_type();
172
173 if (instance_type < FIRST_NONSTRING_TYPE) {
174 String::cast(this)->StringVerify();
175 return;
176 }
177
178 switch (instance_type) {
179 case MAP_TYPE:
180 Map::cast(this)->MapVerify();
181 break;
182 case HEAP_NUMBER_TYPE:
183 HeapNumber::cast(this)->HeapNumberVerify();
184 break;
185 case FIXED_ARRAY_TYPE:
186 FixedArray::cast(this)->FixedArrayVerify();
187 break;
188 case BYTE_ARRAY_TYPE:
189 ByteArray::cast(this)->ByteArrayVerify();
190 break;
191 case CODE_TYPE:
192 Code::cast(this)->CodeVerify();
193 break;
194 case ODDBALL_TYPE:
195 Oddball::cast(this)->OddballVerify();
196 break;
197 case JS_OBJECT_TYPE:
ager@chromium.org32912102009-01-16 10:38:43 +0000198 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199 JSObject::cast(this)->JSObjectVerify();
200 break;
201 case JS_VALUE_TYPE:
202 JSValue::cast(this)->JSValueVerify();
203 break;
204 case JS_FUNCTION_TYPE:
205 JSFunction::cast(this)->JSFunctionVerify();
206 break;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000207 case JS_GLOBAL_PROXY_TYPE:
208 JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
209 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210 case JS_GLOBAL_OBJECT_TYPE:
211 JSGlobalObject::cast(this)->JSGlobalObjectVerify();
212 break;
213 case JS_BUILTINS_OBJECT_TYPE:
214 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
215 break;
216 case JS_ARRAY_TYPE:
217 JSArray::cast(this)->JSArrayVerify();
218 break;
ager@chromium.org236ad962008-09-25 09:45:57 +0000219 case JS_REGEXP_TYPE:
220 JSRegExp::cast(this)->JSRegExpVerify();
221 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222 case FILLER_TYPE:
223 break;
224 case PROXY_TYPE:
225 Proxy::cast(this)->ProxyVerify();
226 break;
227 case SHARED_FUNCTION_INFO_TYPE:
228 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
229 break;
230
231#define MAKE_STRUCT_CASE(NAME, Name, name) \
232 case NAME##_TYPE: \
233 Name::cast(this)->Name##Verify(); \
234 break;
235 STRUCT_LIST(MAKE_STRUCT_CASE)
236#undef MAKE_STRUCT_CASE
237
238 default:
239 UNREACHABLE();
240 break;
241 }
242}
243
244
245void HeapObject::VerifyHeapPointer(Object* p) {
246 ASSERT(p->IsHeapObject());
247 ASSERT(Heap::Contains(HeapObject::cast(p)));
248}
249
250
251void HeapNumber::HeapNumberVerify() {
252 ASSERT(IsHeapNumber());
253}
254
255
256void ByteArray::ByteArrayPrint() {
257 PrintF("byte array, data starts at %p", GetDataStartAddress());
258}
259
260
261void ByteArray::ByteArrayVerify() {
262 ASSERT(IsByteArray());
263}
264
265
266void JSObject::PrintProperties() {
267 if (HasFastProperties()) {
268 for (DescriptorReader r(map()->instance_descriptors());
269 !r.eos();
270 r.advance()) {
271 PrintF(" ");
272 r.GetKey()->StringPrint();
273 PrintF(": ");
274 if (r.type() == FIELD) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000275 FastPropertyAt(r.GetFieldIndex())->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000276 PrintF(" (field at offset %d)\n", r.GetFieldIndex());
277 } else if (r.type() == CONSTANT_FUNCTION) {
278 r.GetConstantFunction()->ShortPrint();
279 PrintF(" (constant function)\n");
280 } else if (r.type() == CALLBACKS) {
281 r.GetCallbacksObject()->ShortPrint();
282 PrintF(" (callback)\n");
283 } else if (r.type() == MAP_TRANSITION) {
284 PrintF(" (map transition)\n");
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000285 } else if (r.type() == CONSTANT_TRANSITION) {
286 PrintF(" (constant transition)\n");
287 } else if (r.type() == NULL_DESCRIPTOR) {
288 PrintF(" (null descriptor)\n");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000289 } else {
290 UNREACHABLE();
291 }
292 }
293 } else {
294 property_dictionary()->Print();
295 }
296}
297
298
299void JSObject::PrintElements() {
300 if (HasFastElements()) {
301 FixedArray* p = FixedArray::cast(elements());
302 for (int i = 0; i < p->length(); i++) {
303 PrintF(" %d: ", i);
304 p->get(i)->ShortPrint();
305 PrintF("\n");
306 }
307 } else {
308 elements()->Print();
309 }
310}
311
312
313void JSObject::JSObjectPrint() {
314 PrintF("%p: [JSObject]\n", this);
315 PrintF(" - map = %p\n", map());
316 PrintF(" - prototype = %p\n", GetPrototype());
317 PrintF(" {\n");
318 PrintProperties();
319 PrintElements();
320 PrintF(" }\n");
321}
322
323
324void JSObject::JSObjectVerify() {
325 VerifyHeapPointer(properties());
326 VerifyHeapPointer(elements());
327 if (HasFastProperties()) {
328 CHECK(map()->unused_property_fields() ==
ager@chromium.org7c537e22008-10-16 08:43:32 +0000329 (map()->inobject_properties() + properties()->length() -
330 map()->NextFreePropertyIndex()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000331 }
332}
333
334
335static const char* TypeToString(InstanceType type) {
336 switch (type) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000337 case INVALID_TYPE: return "INVALID";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000338 case MAP_TYPE: return "MAP";
339 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
340 case SHORT_SYMBOL_TYPE:
341 case MEDIUM_SYMBOL_TYPE:
342 case LONG_SYMBOL_TYPE: return "SYMBOL";
343 case SHORT_ASCII_SYMBOL_TYPE:
344 case MEDIUM_ASCII_SYMBOL_TYPE:
345 case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
346 case SHORT_SLICED_SYMBOL_TYPE:
347 case MEDIUM_SLICED_SYMBOL_TYPE:
348 case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL";
349 case SHORT_SLICED_ASCII_SYMBOL_TYPE:
350 case MEDIUM_SLICED_ASCII_SYMBOL_TYPE:
351 case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL";
352 case SHORT_CONS_SYMBOL_TYPE:
353 case MEDIUM_CONS_SYMBOL_TYPE:
354 case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
355 case SHORT_CONS_ASCII_SYMBOL_TYPE:
356 case MEDIUM_CONS_ASCII_SYMBOL_TYPE:
357 case LONG_CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
358 case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
359 case MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE:
360 case LONG_EXTERNAL_ASCII_SYMBOL_TYPE:
361 case SHORT_EXTERNAL_SYMBOL_TYPE:
362 case MEDIUM_EXTERNAL_SYMBOL_TYPE:
363 case LONG_EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
364 case SHORT_ASCII_STRING_TYPE:
365 case MEDIUM_ASCII_STRING_TYPE:
366 case LONG_ASCII_STRING_TYPE: return "ASCII_STRING";
367 case SHORT_STRING_TYPE:
368 case MEDIUM_STRING_TYPE:
369 case LONG_STRING_TYPE: return "TWO_BYTE_STRING";
370 case SHORT_CONS_STRING_TYPE:
371 case MEDIUM_CONS_STRING_TYPE:
372 case LONG_CONS_STRING_TYPE:
373 case SHORT_CONS_ASCII_STRING_TYPE:
374 case MEDIUM_CONS_ASCII_STRING_TYPE:
375 case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING";
376 case SHORT_SLICED_STRING_TYPE:
377 case MEDIUM_SLICED_STRING_TYPE:
378 case LONG_SLICED_STRING_TYPE:
379 case SHORT_SLICED_ASCII_STRING_TYPE:
380 case MEDIUM_SLICED_ASCII_STRING_TYPE:
381 case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING";
382 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
383 case MEDIUM_EXTERNAL_ASCII_STRING_TYPE:
384 case LONG_EXTERNAL_ASCII_STRING_TYPE:
385 case SHORT_EXTERNAL_STRING_TYPE:
386 case MEDIUM_EXTERNAL_STRING_TYPE:
387 case LONG_EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
388 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
389 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
390 case FILLER_TYPE: return "FILLER";
391 case JS_OBJECT_TYPE: return "JS_OBJECT";
ager@chromium.org32912102009-01-16 10:38:43 +0000392 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000393 case ODDBALL_TYPE: return "ODDBALL";
394 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
395 case JS_FUNCTION_TYPE: return "JS_FUNCTION";
396 case CODE_TYPE: return "CODE";
397 case JS_ARRAY_TYPE: return "JS_ARRAY";
ager@chromium.org236ad962008-09-25 09:45:57 +0000398 case JS_REGEXP_TYPE: return "JS_REGEXP";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000399 case JS_VALUE_TYPE: return "JS_VALUE";
400 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
401 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000402 case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000403 case PROXY_TYPE: return "PROXY";
404 case SMI_TYPE: return "SMI";
405#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
406 STRUCT_LIST(MAKE_STRUCT_CASE)
407#undef MAKE_STRUCT_CASE
408 }
409 return "UNKNOWN";
410}
411
412
413void Map::MapPrint() {
414 HeapObject::PrintHeader("Map");
415 PrintF(" - type: %s\n", TypeToString(instance_type()));
416 PrintF(" - instance size: %d\n", instance_size());
417 PrintF(" - unused property fields: %d\n", unused_property_fields());
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000418 if (is_hidden_prototype()) {
419 PrintF(" - hidden_prototype\n");
420 }
421 if (has_named_interceptor()) {
422 PrintF(" - named_interceptor\n");
423 }
424 if (has_indexed_interceptor()) {
425 PrintF(" - indexed_interceptor\n");
426 }
427 if (is_undetectable()) {
428 PrintF(" - undetectable\n");
429 }
430 if (has_instance_call_handler()) {
431 PrintF(" - instance_call_handler\n");
432 }
433 if (is_access_check_needed()) {
434 PrintF(" - access_check_needed\n");
435 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000436 PrintF(" - instance descriptors: ");
437 instance_descriptors()->ShortPrint();
438 PrintF("\n - prototype: ");
439 prototype()->ShortPrint();
440 PrintF("\n - constructor: ");
441 constructor()->ShortPrint();
442 PrintF("\n");
443}
444
445
446void Map::MapVerify() {
447 ASSERT(!Heap::InNewSpace(this));
448 ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
449 ASSERT(kPointerSize <= instance_size()
450 && instance_size() < Heap::Capacity());
451 VerifyHeapPointer(prototype());
452 VerifyHeapPointer(instance_descriptors());
453}
454
455
456void FixedArray::FixedArrayPrint() {
457 HeapObject::PrintHeader("FixedArray");
458 PrintF(" - length: %d", length());
459 for (int i = 0; i < length(); i++) {
460 PrintF("\n [%d]: ", i);
461 get(i)->ShortPrint();
462 }
463 PrintF("\n");
464}
465
466
467void FixedArray::FixedArrayVerify() {
468 for (int i = 0; i < length(); i++) {
469 Object* e = get(i);
470 if (e->IsHeapObject()) {
471 VerifyHeapPointer(e);
472 } else {
473 e->Verify();
474 }
475 }
476}
477
478
479void JSValue::JSValuePrint() {
480 HeapObject::PrintHeader("ValueObject");
481 value()->Print();
482}
483
484
485void JSValue::JSValueVerify() {
486 Object* v = value();
487 if (v->IsHeapObject()) {
488 VerifyHeapPointer(v);
489 }
490}
491
492
493void String::StringPrint() {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000494 if (StringShape(this).IsSymbol()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000495 PrintF("#");
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000496 } else if (StringShape(this).IsCons()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000497 PrintF("c\"");
498 } else {
499 PrintF("\"");
500 }
501
502 for (int i = 0; i < length(); i++) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000503 PrintF("%c", Get(i));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504 }
505
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000506 if (!StringShape(this).IsSymbol()) PrintF("\"");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000507}
508
509
510void String::StringVerify() {
511 CHECK(IsString());
512 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
513 if (IsSymbol()) {
514 CHECK(!Heap::InNewSpace(this));
515 }
516}
517
518
519void JSFunction::JSFunctionPrint() {
520 HeapObject::PrintHeader("Function");
521 PrintF(" - map = 0x%p\n", map());
522 PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no");
523 PrintF(" - initial_map = ");
524 if (has_initial_map()) {
525 initial_map()->ShortPrint();
526 }
527 PrintF("\n - shared_info = ");
528 shared()->ShortPrint();
529 PrintF("\n - name = ");
530 shared()->name()->Print();
531 PrintF("\n - context = ");
532 unchecked_context()->ShortPrint();
533 PrintF("\n - code = ");
534 code()->ShortPrint();
535 PrintF("\n");
536
537 PrintProperties();
538 PrintElements();
539
540 PrintF("\n");
541}
542
543
544void JSFunction::JSFunctionVerify() {
545 CHECK(IsJSFunction());
546 VerifyObjectField(kPrototypeOrInitialMapOffset);
547}
548
549
550void SharedFunctionInfo::SharedFunctionInfoPrint() {
551 HeapObject::PrintHeader("SharedFunctionInfo");
552 PrintF(" - name: ");
553 name()->ShortPrint();
554 PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
ager@chromium.org381abbb2009-02-25 13:23:22 +0000555 PrintF("\n - instance class name = ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000556 instance_class_name()->Print();
ager@chromium.org381abbb2009-02-25 13:23:22 +0000557 PrintF("\n - code = ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558 code()->ShortPrint();
ager@chromium.org381abbb2009-02-25 13:23:22 +0000559 PrintF("\n - source code = ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000560 GetSourceCode()->ShortPrint();
561 PrintF("\n - lazy load: %s",
562 lazy_load_data() == Heap::undefined_value() ? "no" : "yes");
563 // Script files are often large, hard to read.
564 // PrintF("\n - script =");
565 // script()->Print();
566 PrintF("\n - function token position = %d", function_token_position());
567 PrintF("\n - start position = %d", start_position());
568 PrintF("\n - end position = %d", end_position());
569 PrintF("\n - is expression = %d", is_expression());
570 PrintF("\n - debug info = ");
ager@chromium.org381abbb2009-02-25 13:23:22 +0000571 debug_info()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000572 PrintF("\n - length = %d", length());
573 PrintF("\n");
574}
575
576void SharedFunctionInfo::SharedFunctionInfoVerify() {
577 CHECK(IsSharedFunctionInfo());
578 VerifyObjectField(kNameOffset);
579 VerifyObjectField(kCodeOffset);
580 VerifyObjectField(kInstanceClassNameOffset);
581 VerifyObjectField(kExternalReferenceDataOffset);
582 VerifyObjectField(kLazyLoadDataOffset);
583 VerifyObjectField(kScriptOffset);
584 VerifyObjectField(kDebugInfoOffset);
585}
586
587
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000588void JSGlobalProxy::JSGlobalProxyPrint() {
589 PrintF("global_proxy");
590 JSObjectPrint();
591 PrintF("context : ");
592 context()->ShortPrint();
593 PrintF("\n");
594}
595
596
597void JSGlobalProxy::JSGlobalProxyVerify() {
598 CHECK(IsJSGlobalProxy());
599 JSObjectVerify();
600 VerifyObjectField(JSGlobalProxy::kContextOffset);
601 // Make sure that this object has no properties, elements.
602 CHECK_EQ(0, properties()->length());
603 CHECK_EQ(0, elements()->length());
604}
605
606
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607void JSGlobalObject::JSGlobalObjectPrint() {
608 PrintF("global ");
609 JSObjectPrint();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000610 PrintF("global context : ");
611 global_context()->ShortPrint();
612 PrintF("\n");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000613}
614
615
616void JSGlobalObject::JSGlobalObjectVerify() {
617 CHECK(IsJSGlobalObject());
618 JSObjectVerify();
619 for (int i = GlobalObject::kBuiltinsOffset;
620 i < JSGlobalObject::kSize;
621 i += kPointerSize) {
622 VerifyObjectField(i);
623 }
624}
625
626
627void JSBuiltinsObject::JSBuiltinsObjectPrint() {
628 PrintF("builtins ");
629 JSObjectPrint();
630}
631
632
633void JSBuiltinsObject::JSBuiltinsObjectVerify() {
634 CHECK(IsJSBuiltinsObject());
635 JSObjectVerify();
636 for (int i = GlobalObject::kBuiltinsOffset;
637 i < JSBuiltinsObject::kSize;
638 i += kPointerSize) {
639 VerifyObjectField(i);
640 }
641}
642
643
644void Oddball::OddballVerify() {
645 CHECK(IsOddball());
646 VerifyHeapPointer(to_string());
647 Object* number = to_number();
648 if (number->IsHeapObject()) {
649 ASSERT(number == Heap::nan_value());
650 } else {
651 ASSERT(number->IsSmi());
652 int value = Smi::cast(number)->value();
653 ASSERT(value == 0 || value == 1 || value == -1);
654 }
655}
656
657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000658void Code::CodePrint() {
659 HeapObject::PrintHeader("Code");
mads.s.ager31e71382008-08-13 09:32:07 +0000660#ifdef ENABLE_DISASSEMBLER
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000661 Disassemble(NULL);
mads.s.ager31e71382008-08-13 09:32:07 +0000662#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
666void Code::CodeVerify() {
kasper.lund7276f142008-07-30 08:49:36 +0000667 CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000668 CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
669 static_cast<intptr_t>(kCodeAlignment)));
kasper.lund7276f142008-07-30 08:49:36 +0000670 Address last_gc_pc = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000671 for (RelocIterator it(this); !it.done(); it.next()) {
672 it.rinfo()->Verify();
kasper.lund7276f142008-07-30 08:49:36 +0000673 // Ensure that GC will not iterate twice over the same pointer.
ager@chromium.org236ad962008-09-25 09:45:57 +0000674 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
kasper.lund7276f142008-07-30 08:49:36 +0000675 CHECK(it.rinfo()->pc() != last_gc_pc);
676 last_gc_pc = it.rinfo()->pc();
677 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678 }
679}
680
681
682void JSArray::JSArrayVerify() {
683 JSObjectVerify();
684 ASSERT(length()->IsNumber() || length()->IsUndefined());
685 ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
686}
687
688
ager@chromium.org236ad962008-09-25 09:45:57 +0000689void JSRegExp::JSRegExpVerify() {
690 JSObjectVerify();
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000691 ASSERT(data()->IsUndefined() || data()->IsFixedArray());
692 switch (TypeTag()) {
693 case JSRegExp::ATOM: {
694 FixedArray* arr = FixedArray::cast(data());
695 ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
696 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000697 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000698 case JSRegExp::IRREGEXP: {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000699 bool is_native = RegExpImpl::UseNativeRegexp();
700
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000701 FixedArray* arr = FixedArray::cast(data());
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000702 Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
703 ASSERT(ascii_data->IsTheHole()
704 || (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
705 Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
706 ASSERT(uc16_data->IsTheHole()
707 || (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
708 ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
709 ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000710 break;
711 }
712 default:
713 ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
714 ASSERT(data()->IsUndefined());
715 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000716 }
ager@chromium.org236ad962008-09-25 09:45:57 +0000717}
718
719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720void Proxy::ProxyPrint() {
721 PrintF("proxy to %p", proxy());
722}
723
724
725void Proxy::ProxyVerify() {
726 ASSERT(IsProxy());
727}
728
729
730void Dictionary::Print() {
731 int capacity = Capacity();
732 for (int i = 0; i < capacity; i++) {
733 Object* k = KeyAt(i);
734 if (IsKey(k)) {
735 PrintF(" ");
736 if (k->IsString()) {
737 String::cast(k)->StringPrint();
738 } else {
739 k->ShortPrint();
740 }
741 PrintF(": ");
742 ValueAt(i)->ShortPrint();
743 PrintF("\n");
744 }
745 }
746}
747
748
749void AccessorInfo::AccessorInfoVerify() {
750 CHECK(IsAccessorInfo());
751 VerifyPointer(getter());
752 VerifyPointer(setter());
753 VerifyPointer(name());
754 VerifyPointer(data());
755 VerifyPointer(flag());
756}
757
758void AccessorInfo::AccessorInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000759 HeapObject::PrintHeader("AccessorInfo");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760 PrintF("\n - getter: ");
761 getter()->ShortPrint();
762 PrintF("\n - setter: ");
763 setter()->ShortPrint();
764 PrintF("\n - name: ");
765 name()->ShortPrint();
766 PrintF("\n - data: ");
767 data()->ShortPrint();
768 PrintF("\n - flag: ");
769 flag()->ShortPrint();
770}
771
772void AccessCheckInfo::AccessCheckInfoVerify() {
773 CHECK(IsAccessCheckInfo());
774 VerifyPointer(named_callback());
775 VerifyPointer(indexed_callback());
776 VerifyPointer(data());
777}
778
779void AccessCheckInfo::AccessCheckInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000780 HeapObject::PrintHeader("AccessCheckInfo");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781 PrintF("\n - named_callback: ");
782 named_callback()->ShortPrint();
783 PrintF("\n - indexed_callback: ");
784 indexed_callback()->ShortPrint();
785 PrintF("\n - data: ");
786 data()->ShortPrint();
787}
788
789void InterceptorInfo::InterceptorInfoVerify() {
790 CHECK(IsInterceptorInfo());
791 VerifyPointer(getter());
792 VerifyPointer(setter());
793 VerifyPointer(query());
794 VerifyPointer(deleter());
795 VerifyPointer(enumerator());
796 VerifyPointer(data());
797}
798
799void InterceptorInfo::InterceptorInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000800 HeapObject::PrintHeader("InterceptorInfo");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801 PrintF("\n - getter: ");
802 getter()->ShortPrint();
803 PrintF("\n - setter: ");
804 setter()->ShortPrint();
805 PrintF("\n - query: ");
806 query()->ShortPrint();
807 PrintF("\n - deleter: ");
808 deleter()->ShortPrint();
809 PrintF("\n - enumerator: ");
810 enumerator()->ShortPrint();
811 PrintF("\n - data: ");
812 data()->ShortPrint();
813}
814
815void CallHandlerInfo::CallHandlerInfoVerify() {
816 CHECK(IsCallHandlerInfo());
817 VerifyPointer(callback());
818 VerifyPointer(data());
819}
820
821void CallHandlerInfo::CallHandlerInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000822 HeapObject::PrintHeader("CallHandlerInfo");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000823 PrintF("\n - callback: ");
824 callback()->ShortPrint();
825 PrintF("\n - data: ");
826 data()->ShortPrint();
827}
828
829void TemplateInfo::TemplateInfoVerify() {
830 VerifyPointer(tag());
831 VerifyPointer(property_list());
832}
833
834void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
835 CHECK(IsFunctionTemplateInfo());
836 TemplateInfoVerify();
837 VerifyPointer(serial_number());
838 VerifyPointer(call_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000839 VerifyPointer(property_accessors());
840 VerifyPointer(prototype_template());
841 VerifyPointer(parent_template());
842 VerifyPointer(named_property_handler());
843 VerifyPointer(indexed_property_handler());
844 VerifyPointer(instance_template());
845 VerifyPointer(signature());
846 VerifyPointer(access_check_info());
847}
848
849void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000850 HeapObject::PrintHeader("FunctionTemplateInfo");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851 PrintF("\n - tag: ");
852 tag()->ShortPrint();
853 PrintF("\n - property_list: ");
854 property_list()->ShortPrint();
855 PrintF("\n - serial_number: ");
856 serial_number()->ShortPrint();
857 PrintF("\n - call_code: ");
858 call_code()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000859 PrintF("\n - property_accessors: ");
860 property_accessors()->ShortPrint();
861 PrintF("\n - prototype_template: ");
862 prototype_template()->ShortPrint();
863 PrintF("\n - parent_template: ");
864 parent_template()->ShortPrint();
865 PrintF("\n - named_property_handler: ");
866 named_property_handler()->ShortPrint();
867 PrintF("\n - indexed_property_handler: ");
868 indexed_property_handler()->ShortPrint();
869 PrintF("\n - instance_template: ");
870 instance_template()->ShortPrint();
871 PrintF("\n - signature: ");
872 signature()->ShortPrint();
873 PrintF("\n - access_check_info: ");
874 access_check_info()->ShortPrint();
875 PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false");
876 PrintF("\n - undetectable: %s", undetectable() ? "true" : "false");
877 PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false");
878}
879
880void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
881 CHECK(IsObjectTemplateInfo());
882 TemplateInfoVerify();
883 VerifyPointer(constructor());
kasper.lund212ac232008-07-16 07:07:30 +0000884 VerifyPointer(internal_field_count());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000885}
886
887void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000888 HeapObject::PrintHeader("ObjectTemplateInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000889 PrintF("\n - constructor: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000890 constructor()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000891 PrintF("\n - internal_field_count: ");
892 internal_field_count()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000893}
894
895void SignatureInfo::SignatureInfoVerify() {
896 CHECK(IsSignatureInfo());
897 VerifyPointer(receiver());
898 VerifyPointer(args());
899}
900
901void SignatureInfo::SignatureInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000902 HeapObject::PrintHeader("SignatureInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000903 PrintF("\n - receiver: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904 receiver()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000905 PrintF("\n - args: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000906 args()->ShortPrint();
907}
908
909void TypeSwitchInfo::TypeSwitchInfoVerify() {
910 CHECK(IsTypeSwitchInfo());
911 VerifyPointer(types());
912}
913
914void TypeSwitchInfo::TypeSwitchInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000915 HeapObject::PrintHeader("TypeSwitchInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000916 PrintF("\n - types: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000917 types()->ShortPrint();
918}
919
920
921void Script::ScriptVerify() {
922 CHECK(IsScript());
923 VerifyPointer(source());
924 VerifyPointer(name());
925 line_offset()->SmiVerify();
926 column_offset()->SmiVerify();
927 type()->SmiVerify();
928}
929
930
931void Script::ScriptPrint() {
932 HeapObject::PrintHeader("Script");
933 PrintF("\n - source: ");
934 source()->ShortPrint();
935 PrintF("\n - name: ");
936 name()->ShortPrint();
937 PrintF("\n - line_offset: ");
938 line_offset()->ShortPrint();
939 PrintF("\n - column_offset: ");
940 column_offset()->ShortPrint();
941 PrintF("\n - type: ");
942 type()->ShortPrint();
943 PrintF("\n");
944}
945
946
947void DebugInfo::DebugInfoVerify() {
948 CHECK(IsDebugInfo());
949 VerifyPointer(shared());
950 VerifyPointer(original_code());
951 VerifyPointer(code());
952 VerifyPointer(break_points());
953}
954
955
956void DebugInfo::DebugInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000957 HeapObject::PrintHeader("DebugInfo");
958 PrintF("\n - shared: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000959 shared()->ShortPrint();
ager@chromium.org381abbb2009-02-25 13:23:22 +0000960 PrintF("\n - original_code: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000961 original_code()->ShortPrint();
ager@chromium.org381abbb2009-02-25 13:23:22 +0000962 PrintF("\n - code: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963 code()->ShortPrint();
ager@chromium.org381abbb2009-02-25 13:23:22 +0000964 PrintF("\n - break_points: ");
965 break_points()->Print();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966}
967
968
969void BreakPointInfo::BreakPointInfoVerify() {
970 CHECK(IsBreakPointInfo());
971 code_position()->SmiVerify();
972 source_position()->SmiVerify();
973 statement_position()->SmiVerify();
974 VerifyPointer(break_point_objects());
975}
976
977
978void BreakPointInfo::BreakPointInfoPrint() {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000979 HeapObject::PrintHeader("BreakPointInfo");
980 PrintF("\n - code_position: %d", code_position());
981 PrintF("\n - source_position: %d", source_position());
982 PrintF("\n - statement_position: %d", statement_position());
983 PrintF("\n - break_point_objects: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000984 break_point_objects()->ShortPrint();
985}
986
987
988void JSObject::IncrementSpillStatistics(SpillInformation* info) {
989 info->number_of_objects_++;
990 // Named properties
991 if (HasFastProperties()) {
992 info->number_of_objects_with_fast_properties_++;
993 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
994 info->number_of_fast_unused_fields_ += map()->unused_property_fields();
995 } else {
996 Dictionary* dict = property_dictionary();
997 info->number_of_slow_used_properties_ += dict->NumberOfElements();
998 info->number_of_slow_unused_properties_ +=
999 dict->Capacity() - dict->NumberOfElements();
1000 }
1001 // Indexed properties
1002 if (HasFastElements()) {
1003 info->number_of_objects_with_fast_elements_++;
1004 int holes = 0;
1005 FixedArray* e = FixedArray::cast(elements());
1006 int len = e->length();
1007 for (int i = 0; i < len; i++) {
1008 if (e->get(i) == Heap::the_hole_value()) holes++;
1009 }
1010 info->number_of_fast_used_elements_ += len - holes;
1011 info->number_of_fast_unused_elements_ += holes;
1012 } else {
1013 Dictionary* dict = element_dictionary();
1014 info->number_of_slow_used_elements_ += dict->NumberOfElements();
1015 info->number_of_slow_unused_elements_ +=
1016 dict->Capacity() - dict->NumberOfElements();
1017 }
1018}
1019
1020
1021void JSObject::SpillInformation::Clear() {
1022 number_of_objects_ = 0;
1023 number_of_objects_with_fast_properties_ = 0;
1024 number_of_objects_with_fast_elements_ = 0;
1025 number_of_fast_used_fields_ = 0;
1026 number_of_fast_unused_fields_ = 0;
1027 number_of_slow_used_properties_ = 0;
1028 number_of_slow_unused_properties_ = 0;
1029 number_of_fast_used_elements_ = 0;
1030 number_of_fast_unused_elements_ = 0;
1031 number_of_slow_used_elements_ = 0;
1032 number_of_slow_unused_elements_ = 0;
1033}
1034
1035void JSObject::SpillInformation::Print() {
1036 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
1037
1038 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
1039 number_of_objects_with_fast_properties_,
1040 number_of_fast_used_fields_, number_of_fast_unused_fields_);
1041
1042 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
1043 number_of_objects_ - number_of_objects_with_fast_properties_,
1044 number_of_slow_used_properties_, number_of_slow_unused_properties_);
1045
1046 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
1047 number_of_objects_with_fast_elements_,
1048 number_of_fast_used_elements_, number_of_fast_unused_elements_);
1049
1050 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
1051 number_of_objects_ - number_of_objects_with_fast_elements_,
1052 number_of_slow_used_elements_, number_of_slow_unused_elements_);
1053
1054 PrintF("\n");
1055}
1056
1057
1058void DescriptorArray::PrintDescriptors() {
1059 PrintF("Descriptor array %d\n", number_of_descriptors());
1060 int number = 0;
1061 for (DescriptorReader r(this); !r.eos(); r.advance()) {
1062 Descriptor desc;
1063 r.Get(&desc);
1064 PrintF(" %d: ", number++);
1065 desc.Print();
1066 }
1067 PrintF("\n");
1068}
1069
1070
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001071bool DescriptorArray::IsSortedNoDuplicates() {
1072 String* current_key = NULL;
1073 uint32_t current = 0;
1074 for (DescriptorReader r(this); !r.eos(); r.advance()) {
1075 String* key = r.GetKey();
1076 if (key == current_key) {
1077 PrintDescriptors();
1078 return false;
1079 }
1080 current_key = key;
1081 uint32_t hash = r.GetKey()->Hash();
1082 if (hash < current) {
1083 PrintDescriptors();
1084 return false;
1085 }
1086 current = hash;
1087 }
1088 return true;
1089}
1090
1091
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001092#endif // DEBUG
1093
1094} } // namespace v8::internal