blob: 6b58f255a8296de636a656f6528abf6ca20a508a [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"
33
34namespace v8 { namespace internal {
35
36#ifdef DEBUG
37
38static const char* TypeToString(InstanceType type);
39
40
41void Object::Print() {
42 if (IsSmi()) {
43 Smi::cast(this)->SmiPrint();
44 } else if (IsFailure()) {
45 Failure::cast(this)->FailurePrint();
46 } else {
47 HeapObject::cast(this)->HeapObjectPrint();
48 }
49 Flush();
50}
51
52
53void Object::PrintLn() {
54 Print();
55 PrintF("\n");
56}
57
58
59void Object::Verify() {
60 if (IsSmi()) {
61 Smi::cast(this)->SmiVerify();
62 } else if (IsFailure()) {
63 Failure::cast(this)->FailureVerify();
64 } else {
65 HeapObject::cast(this)->HeapObjectVerify();
66 }
67}
68
69
70void Object::VerifyPointer(Object* p) {
71 if (p->IsHeapObject()) {
72 HeapObject::VerifyHeapPointer(p);
73 } else {
74 ASSERT(p->IsSmi());
75 }
76}
77
78
79void Smi::SmiVerify() {
80 ASSERT(IsSmi());
81}
82
83
84void Failure::FailureVerify() {
85 ASSERT(IsFailure());
86}
87
88
89void HeapObject::PrintHeader(const char* id) {
90 PrintF("%p: [%s]\n", this, id);
91}
92
93
94void HeapObject::HeapObjectPrint() {
95 InstanceType instance_type = map()->instance_type();
96
97 HandleScope scope;
98 if (instance_type < FIRST_NONSTRING_TYPE) {
99 String::cast(this)->StringPrint();
100 return;
101 }
102
103 switch (instance_type) {
104 case MAP_TYPE:
105 Map::cast(this)->MapPrint();
106 break;
107 case HEAP_NUMBER_TYPE:
108 HeapNumber::cast(this)->HeapNumberPrint();
109 break;
110 case FIXED_ARRAY_TYPE:
111 FixedArray::cast(this)->FixedArrayPrint();
112 break;
113 case BYTE_ARRAY_TYPE:
114 ByteArray::cast(this)->ByteArrayPrint();
115 break;
116 case FILLER_TYPE:
117 PrintF("filler");
118 break;
119 case JS_OBJECT_TYPE: // fall through
ager@chromium.org32912102009-01-16 10:38:43 +0000120 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000121 case JS_ARRAY_TYPE:
ager@chromium.org236ad962008-09-25 09:45:57 +0000122 case JS_REGEXP_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 JSObject::cast(this)->JSObjectPrint();
124 break;
125 case ODDBALL_TYPE:
126 Oddball::cast(this)->to_string()->Print();
127 break;
128 case JS_FUNCTION_TYPE:
129 JSFunction::cast(this)->JSFunctionPrint();
130 break;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000131 case JS_GLOBAL_PROXY_TYPE:
132 JSGlobalProxy::cast(this)->JSGlobalProxyPrint();
133 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000134 case JS_GLOBAL_OBJECT_TYPE:
135 JSGlobalObject::cast(this)->JSGlobalObjectPrint();
136 break;
137 case JS_BUILTINS_OBJECT_TYPE:
138 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
139 break;
140 case JS_VALUE_TYPE:
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000141 PrintF("Value wrapper around:");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000142 JSValue::cast(this)->value()->Print();
143 break;
144 case CODE_TYPE:
145 Code::cast(this)->CodePrint();
146 break;
147 case PROXY_TYPE:
148 Proxy::cast(this)->ProxyPrint();
149 break;
150 case SHARED_FUNCTION_INFO_TYPE:
151 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint();
152 break;
153
154#define MAKE_STRUCT_CASE(NAME, Name, name) \
155 case NAME##_TYPE: \
156 Name::cast(this)->Name##Print(); \
157 break;
158 STRUCT_LIST(MAKE_STRUCT_CASE)
159#undef MAKE_STRUCT_CASE
160
161 default:
162 PrintF("UNKNOWN TYPE %d", map()->instance_type());
163 UNREACHABLE();
164 break;
165 }
166}
167
168
169void HeapObject::HeapObjectVerify() {
170 InstanceType instance_type = map()->instance_type();
171
172 if (instance_type < FIRST_NONSTRING_TYPE) {
173 String::cast(this)->StringVerify();
174 return;
175 }
176
177 switch (instance_type) {
178 case MAP_TYPE:
179 Map::cast(this)->MapVerify();
180 break;
181 case HEAP_NUMBER_TYPE:
182 HeapNumber::cast(this)->HeapNumberVerify();
183 break;
184 case FIXED_ARRAY_TYPE:
185 FixedArray::cast(this)->FixedArrayVerify();
186 break;
187 case BYTE_ARRAY_TYPE:
188 ByteArray::cast(this)->ByteArrayVerify();
189 break;
190 case CODE_TYPE:
191 Code::cast(this)->CodeVerify();
192 break;
193 case ODDBALL_TYPE:
194 Oddball::cast(this)->OddballVerify();
195 break;
196 case JS_OBJECT_TYPE:
ager@chromium.org32912102009-01-16 10:38:43 +0000197 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198 JSObject::cast(this)->JSObjectVerify();
199 break;
200 case JS_VALUE_TYPE:
201 JSValue::cast(this)->JSValueVerify();
202 break;
203 case JS_FUNCTION_TYPE:
204 JSFunction::cast(this)->JSFunctionVerify();
205 break;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000206 case JS_GLOBAL_PROXY_TYPE:
207 JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
208 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000209 case JS_GLOBAL_OBJECT_TYPE:
210 JSGlobalObject::cast(this)->JSGlobalObjectVerify();
211 break;
212 case JS_BUILTINS_OBJECT_TYPE:
213 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
214 break;
215 case JS_ARRAY_TYPE:
216 JSArray::cast(this)->JSArrayVerify();
217 break;
ager@chromium.org236ad962008-09-25 09:45:57 +0000218 case JS_REGEXP_TYPE:
219 JSRegExp::cast(this)->JSRegExpVerify();
220 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221 case FILLER_TYPE:
222 break;
223 case PROXY_TYPE:
224 Proxy::cast(this)->ProxyVerify();
225 break;
226 case SHARED_FUNCTION_INFO_TYPE:
227 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
228 break;
229
230#define MAKE_STRUCT_CASE(NAME, Name, name) \
231 case NAME##_TYPE: \
232 Name::cast(this)->Name##Verify(); \
233 break;
234 STRUCT_LIST(MAKE_STRUCT_CASE)
235#undef MAKE_STRUCT_CASE
236
237 default:
238 UNREACHABLE();
239 break;
240 }
241}
242
243
244void HeapObject::VerifyHeapPointer(Object* p) {
245 ASSERT(p->IsHeapObject());
246 ASSERT(Heap::Contains(HeapObject::cast(p)));
247}
248
249
250void HeapNumber::HeapNumberVerify() {
251 ASSERT(IsHeapNumber());
252}
253
254
255void ByteArray::ByteArrayPrint() {
256 PrintF("byte array, data starts at %p", GetDataStartAddress());
257}
258
259
260void ByteArray::ByteArrayVerify() {
261 ASSERT(IsByteArray());
262}
263
264
265void JSObject::PrintProperties() {
266 if (HasFastProperties()) {
267 for (DescriptorReader r(map()->instance_descriptors());
268 !r.eos();
269 r.advance()) {
270 PrintF(" ");
271 r.GetKey()->StringPrint();
272 PrintF(": ");
273 if (r.type() == FIELD) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000274 FastPropertyAt(r.GetFieldIndex())->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275 PrintF(" (field at offset %d)\n", r.GetFieldIndex());
276 } else if (r.type() == CONSTANT_FUNCTION) {
277 r.GetConstantFunction()->ShortPrint();
278 PrintF(" (constant function)\n");
279 } else if (r.type() == CALLBACKS) {
280 r.GetCallbacksObject()->ShortPrint();
281 PrintF(" (callback)\n");
282 } else if (r.type() == MAP_TRANSITION) {
283 PrintF(" (map transition)\n");
284 } else {
285 UNREACHABLE();
286 }
287 }
288 } else {
289 property_dictionary()->Print();
290 }
291}
292
293
294void JSObject::PrintElements() {
295 if (HasFastElements()) {
296 FixedArray* p = FixedArray::cast(elements());
297 for (int i = 0; i < p->length(); i++) {
298 PrintF(" %d: ", i);
299 p->get(i)->ShortPrint();
300 PrintF("\n");
301 }
302 } else {
303 elements()->Print();
304 }
305}
306
307
308void JSObject::JSObjectPrint() {
309 PrintF("%p: [JSObject]\n", this);
310 PrintF(" - map = %p\n", map());
311 PrintF(" - prototype = %p\n", GetPrototype());
312 PrintF(" {\n");
313 PrintProperties();
314 PrintElements();
315 PrintF(" }\n");
316}
317
318
319void JSObject::JSObjectVerify() {
320 VerifyHeapPointer(properties());
321 VerifyHeapPointer(elements());
322 if (HasFastProperties()) {
323 CHECK(map()->unused_property_fields() ==
ager@chromium.org7c537e22008-10-16 08:43:32 +0000324 (map()->inobject_properties() + properties()->length() -
325 map()->NextFreePropertyIndex()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000326 }
327}
328
329
330static const char* TypeToString(InstanceType type) {
331 switch (type) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000332 case INVALID_TYPE: return "INVALID";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000333 case MAP_TYPE: return "MAP";
334 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
335 case SHORT_SYMBOL_TYPE:
336 case MEDIUM_SYMBOL_TYPE:
337 case LONG_SYMBOL_TYPE: return "SYMBOL";
338 case SHORT_ASCII_SYMBOL_TYPE:
339 case MEDIUM_ASCII_SYMBOL_TYPE:
340 case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
341 case SHORT_SLICED_SYMBOL_TYPE:
342 case MEDIUM_SLICED_SYMBOL_TYPE:
343 case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL";
344 case SHORT_SLICED_ASCII_SYMBOL_TYPE:
345 case MEDIUM_SLICED_ASCII_SYMBOL_TYPE:
346 case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL";
347 case SHORT_CONS_SYMBOL_TYPE:
348 case MEDIUM_CONS_SYMBOL_TYPE:
349 case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
350 case SHORT_CONS_ASCII_SYMBOL_TYPE:
351 case MEDIUM_CONS_ASCII_SYMBOL_TYPE:
352 case LONG_CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
353 case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
354 case MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE:
355 case LONG_EXTERNAL_ASCII_SYMBOL_TYPE:
356 case SHORT_EXTERNAL_SYMBOL_TYPE:
357 case MEDIUM_EXTERNAL_SYMBOL_TYPE:
358 case LONG_EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
359 case SHORT_ASCII_STRING_TYPE:
360 case MEDIUM_ASCII_STRING_TYPE:
361 case LONG_ASCII_STRING_TYPE: return "ASCII_STRING";
362 case SHORT_STRING_TYPE:
363 case MEDIUM_STRING_TYPE:
364 case LONG_STRING_TYPE: return "TWO_BYTE_STRING";
365 case SHORT_CONS_STRING_TYPE:
366 case MEDIUM_CONS_STRING_TYPE:
367 case LONG_CONS_STRING_TYPE:
368 case SHORT_CONS_ASCII_STRING_TYPE:
369 case MEDIUM_CONS_ASCII_STRING_TYPE:
370 case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING";
371 case SHORT_SLICED_STRING_TYPE:
372 case MEDIUM_SLICED_STRING_TYPE:
373 case LONG_SLICED_STRING_TYPE:
374 case SHORT_SLICED_ASCII_STRING_TYPE:
375 case MEDIUM_SLICED_ASCII_STRING_TYPE:
376 case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING";
377 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
378 case MEDIUM_EXTERNAL_ASCII_STRING_TYPE:
379 case LONG_EXTERNAL_ASCII_STRING_TYPE:
380 case SHORT_EXTERNAL_STRING_TYPE:
381 case MEDIUM_EXTERNAL_STRING_TYPE:
382 case LONG_EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
383 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
384 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
385 case FILLER_TYPE: return "FILLER";
386 case JS_OBJECT_TYPE: return "JS_OBJECT";
ager@chromium.org32912102009-01-16 10:38:43 +0000387 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000388 case ODDBALL_TYPE: return "ODDBALL";
389 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
390 case JS_FUNCTION_TYPE: return "JS_FUNCTION";
391 case CODE_TYPE: return "CODE";
392 case JS_ARRAY_TYPE: return "JS_ARRAY";
ager@chromium.org236ad962008-09-25 09:45:57 +0000393 case JS_REGEXP_TYPE: return "JS_REGEXP";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000394 case JS_VALUE_TYPE: return "JS_VALUE";
395 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
396 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000397 case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398 case PROXY_TYPE: return "PROXY";
399 case SMI_TYPE: return "SMI";
400#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
401 STRUCT_LIST(MAKE_STRUCT_CASE)
402#undef MAKE_STRUCT_CASE
403 }
404 return "UNKNOWN";
405}
406
407
408void Map::MapPrint() {
409 HeapObject::PrintHeader("Map");
410 PrintF(" - type: %s\n", TypeToString(instance_type()));
411 PrintF(" - instance size: %d\n", instance_size());
412 PrintF(" - unused property fields: %d\n", unused_property_fields());
413 PrintF(" - instance descriptors: ");
414 instance_descriptors()->ShortPrint();
415 PrintF("\n - prototype: ");
416 prototype()->ShortPrint();
417 PrintF("\n - constructor: ");
418 constructor()->ShortPrint();
419 PrintF("\n");
420}
421
422
423void Map::MapVerify() {
424 ASSERT(!Heap::InNewSpace(this));
425 ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
426 ASSERT(kPointerSize <= instance_size()
427 && instance_size() < Heap::Capacity());
428 VerifyHeapPointer(prototype());
429 VerifyHeapPointer(instance_descriptors());
430}
431
432
433void FixedArray::FixedArrayPrint() {
434 HeapObject::PrintHeader("FixedArray");
435 PrintF(" - length: %d", length());
436 for (int i = 0; i < length(); i++) {
437 PrintF("\n [%d]: ", i);
438 get(i)->ShortPrint();
439 }
440 PrintF("\n");
441}
442
443
444void FixedArray::FixedArrayVerify() {
445 for (int i = 0; i < length(); i++) {
446 Object* e = get(i);
447 if (e->IsHeapObject()) {
448 VerifyHeapPointer(e);
449 } else {
450 e->Verify();
451 }
452 }
453}
454
455
456void JSValue::JSValuePrint() {
457 HeapObject::PrintHeader("ValueObject");
458 value()->Print();
459}
460
461
462void JSValue::JSValueVerify() {
463 Object* v = value();
464 if (v->IsHeapObject()) {
465 VerifyHeapPointer(v);
466 }
467}
468
469
470void String::StringPrint() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000471 StringShape shape(this);
472 if (shape.IsSymbol()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000473 PrintF("#");
ager@chromium.org870a0b62008-11-04 11:43:05 +0000474 } else if (shape.IsCons()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000475 PrintF("c\"");
476 } else {
477 PrintF("\"");
478 }
479
480 for (int i = 0; i < length(); i++) {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000481 PrintF("%c", Get(shape, i));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000482 }
483
ager@chromium.org870a0b62008-11-04 11:43:05 +0000484 if (!shape.IsSymbol()) PrintF("\"");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000485}
486
487
488void String::StringVerify() {
489 CHECK(IsString());
490 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
491 if (IsSymbol()) {
492 CHECK(!Heap::InNewSpace(this));
493 }
494}
495
496
497void JSFunction::JSFunctionPrint() {
498 HeapObject::PrintHeader("Function");
499 PrintF(" - map = 0x%p\n", map());
500 PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no");
501 PrintF(" - initial_map = ");
502 if (has_initial_map()) {
503 initial_map()->ShortPrint();
504 }
505 PrintF("\n - shared_info = ");
506 shared()->ShortPrint();
507 PrintF("\n - name = ");
508 shared()->name()->Print();
509 PrintF("\n - context = ");
510 unchecked_context()->ShortPrint();
511 PrintF("\n - code = ");
512 code()->ShortPrint();
513 PrintF("\n");
514
515 PrintProperties();
516 PrintElements();
517
518 PrintF("\n");
519}
520
521
522void JSFunction::JSFunctionVerify() {
523 CHECK(IsJSFunction());
524 VerifyObjectField(kPrototypeOrInitialMapOffset);
525}
526
527
528void SharedFunctionInfo::SharedFunctionInfoPrint() {
529 HeapObject::PrintHeader("SharedFunctionInfo");
530 PrintF(" - name: ");
531 name()->ShortPrint();
532 PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
533 PrintF("\n - instance class name =");
534 instance_class_name()->Print();
535 PrintF("\n - code =");
536 code()->ShortPrint();
537 PrintF("\n - source code =");
538 GetSourceCode()->ShortPrint();
539 PrintF("\n - lazy load: %s",
540 lazy_load_data() == Heap::undefined_value() ? "no" : "yes");
541 // Script files are often large, hard to read.
542 // PrintF("\n - script =");
543 // script()->Print();
544 PrintF("\n - function token position = %d", function_token_position());
545 PrintF("\n - start position = %d", start_position());
546 PrintF("\n - end position = %d", end_position());
547 PrintF("\n - is expression = %d", is_expression());
548 PrintF("\n - debug info = ");
549 debug_info()->Print();
550 PrintF("\n - length = %d", length());
551 PrintF("\n");
552}
553
554void SharedFunctionInfo::SharedFunctionInfoVerify() {
555 CHECK(IsSharedFunctionInfo());
556 VerifyObjectField(kNameOffset);
557 VerifyObjectField(kCodeOffset);
558 VerifyObjectField(kInstanceClassNameOffset);
559 VerifyObjectField(kExternalReferenceDataOffset);
560 VerifyObjectField(kLazyLoadDataOffset);
561 VerifyObjectField(kScriptOffset);
562 VerifyObjectField(kDebugInfoOffset);
563}
564
565
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000566void JSGlobalProxy::JSGlobalProxyPrint() {
567 PrintF("global_proxy");
568 JSObjectPrint();
569 PrintF("context : ");
570 context()->ShortPrint();
571 PrintF("\n");
572}
573
574
575void JSGlobalProxy::JSGlobalProxyVerify() {
576 CHECK(IsJSGlobalProxy());
577 JSObjectVerify();
578 VerifyObjectField(JSGlobalProxy::kContextOffset);
579 // Make sure that this object has no properties, elements.
580 CHECK_EQ(0, properties()->length());
581 CHECK_EQ(0, elements()->length());
582}
583
584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000585void JSGlobalObject::JSGlobalObjectPrint() {
586 PrintF("global ");
587 JSObjectPrint();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000588 PrintF("global context : ");
589 global_context()->ShortPrint();
590 PrintF("\n");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000591}
592
593
594void JSGlobalObject::JSGlobalObjectVerify() {
595 CHECK(IsJSGlobalObject());
596 JSObjectVerify();
597 for (int i = GlobalObject::kBuiltinsOffset;
598 i < JSGlobalObject::kSize;
599 i += kPointerSize) {
600 VerifyObjectField(i);
601 }
602}
603
604
605void JSBuiltinsObject::JSBuiltinsObjectPrint() {
606 PrintF("builtins ");
607 JSObjectPrint();
608}
609
610
611void JSBuiltinsObject::JSBuiltinsObjectVerify() {
612 CHECK(IsJSBuiltinsObject());
613 JSObjectVerify();
614 for (int i = GlobalObject::kBuiltinsOffset;
615 i < JSBuiltinsObject::kSize;
616 i += kPointerSize) {
617 VerifyObjectField(i);
618 }
619}
620
621
622void Oddball::OddballVerify() {
623 CHECK(IsOddball());
624 VerifyHeapPointer(to_string());
625 Object* number = to_number();
626 if (number->IsHeapObject()) {
627 ASSERT(number == Heap::nan_value());
628 } else {
629 ASSERT(number->IsSmi());
630 int value = Smi::cast(number)->value();
631 ASSERT(value == 0 || value == 1 || value == -1);
632 }
633}
634
635
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000636void Code::CodePrint() {
637 HeapObject::PrintHeader("Code");
mads.s.ager31e71382008-08-13 09:32:07 +0000638#ifdef ENABLE_DISASSEMBLER
639 Disassemble();
640#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641}
642
643
644void Code::CodeVerify() {
kasper.lund7276f142008-07-30 08:49:36 +0000645 CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
646 Address last_gc_pc = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000647 for (RelocIterator it(this); !it.done(); it.next()) {
648 it.rinfo()->Verify();
kasper.lund7276f142008-07-30 08:49:36 +0000649 // Ensure that GC will not iterate twice over the same pointer.
ager@chromium.org236ad962008-09-25 09:45:57 +0000650 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
kasper.lund7276f142008-07-30 08:49:36 +0000651 CHECK(it.rinfo()->pc() != last_gc_pc);
652 last_gc_pc = it.rinfo()->pc();
653 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000654 }
655}
656
657
658void JSArray::JSArrayVerify() {
659 JSObjectVerify();
660 ASSERT(length()->IsNumber() || length()->IsUndefined());
661 ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
662}
663
664
ager@chromium.org236ad962008-09-25 09:45:57 +0000665void JSRegExp::JSRegExpVerify() {
666 JSObjectVerify();
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000667 ASSERT(data()->IsUndefined() || data()->IsFixedArray());
668 switch (TypeTag()) {
669 case JSRegExp::ATOM: {
670 FixedArray* arr = FixedArray::cast(data());
671 ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
672 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000673 }
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000674 case JSRegExp::JSCRE: {
675 FixedArray* arr = FixedArray::cast(data());
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000676 Object* jscre_data = arr->get(JSRegExp::kJscreDataIndex);
677 ASSERT(jscre_data->IsFixedArray() || jscre_data->IsUndefined());
678 break;
679 }
680 case JSRegExp::IRREGEXP: {
681 FixedArray* arr = FixedArray::cast(data());
682 Object* jscre_data = arr->get(JSRegExp::kJscreDataIndex);
683 ASSERT(jscre_data->IsFixedArray());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000684 break;
685 }
686 default:
687 ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
688 ASSERT(data()->IsUndefined());
689 break;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000690 }
ager@chromium.org236ad962008-09-25 09:45:57 +0000691}
692
693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000694void Proxy::ProxyPrint() {
695 PrintF("proxy to %p", proxy());
696}
697
698
699void Proxy::ProxyVerify() {
700 ASSERT(IsProxy());
701}
702
703
704void Dictionary::Print() {
705 int capacity = Capacity();
706 for (int i = 0; i < capacity; i++) {
707 Object* k = KeyAt(i);
708 if (IsKey(k)) {
709 PrintF(" ");
710 if (k->IsString()) {
711 String::cast(k)->StringPrint();
712 } else {
713 k->ShortPrint();
714 }
715 PrintF(": ");
716 ValueAt(i)->ShortPrint();
717 PrintF("\n");
718 }
719 }
720}
721
722
723void AccessorInfo::AccessorInfoVerify() {
724 CHECK(IsAccessorInfo());
725 VerifyPointer(getter());
726 VerifyPointer(setter());
727 VerifyPointer(name());
728 VerifyPointer(data());
729 VerifyPointer(flag());
730}
731
732void AccessorInfo::AccessorInfoPrint() {
733 PrintF("AccessorInfo");
734 PrintF("\n - getter: ");
735 getter()->ShortPrint();
736 PrintF("\n - setter: ");
737 setter()->ShortPrint();
738 PrintF("\n - name: ");
739 name()->ShortPrint();
740 PrintF("\n - data: ");
741 data()->ShortPrint();
742 PrintF("\n - flag: ");
743 flag()->ShortPrint();
744}
745
746void AccessCheckInfo::AccessCheckInfoVerify() {
747 CHECK(IsAccessCheckInfo());
748 VerifyPointer(named_callback());
749 VerifyPointer(indexed_callback());
750 VerifyPointer(data());
751}
752
753void AccessCheckInfo::AccessCheckInfoPrint() {
754 PrintF("AccessCheckInfo");
755 PrintF("\n - named_callback: ");
756 named_callback()->ShortPrint();
757 PrintF("\n - indexed_callback: ");
758 indexed_callback()->ShortPrint();
759 PrintF("\n - data: ");
760 data()->ShortPrint();
761}
762
763void InterceptorInfo::InterceptorInfoVerify() {
764 CHECK(IsInterceptorInfo());
765 VerifyPointer(getter());
766 VerifyPointer(setter());
767 VerifyPointer(query());
768 VerifyPointer(deleter());
769 VerifyPointer(enumerator());
770 VerifyPointer(data());
771}
772
773void InterceptorInfo::InterceptorInfoPrint() {
774 PrintF("InterceptorInfo");
775 PrintF("\n - getter: ");
776 getter()->ShortPrint();
777 PrintF("\n - setter: ");
778 setter()->ShortPrint();
779 PrintF("\n - query: ");
780 query()->ShortPrint();
781 PrintF("\n - deleter: ");
782 deleter()->ShortPrint();
783 PrintF("\n - enumerator: ");
784 enumerator()->ShortPrint();
785 PrintF("\n - data: ");
786 data()->ShortPrint();
787}
788
789void CallHandlerInfo::CallHandlerInfoVerify() {
790 CHECK(IsCallHandlerInfo());
791 VerifyPointer(callback());
792 VerifyPointer(data());
793}
794
795void CallHandlerInfo::CallHandlerInfoPrint() {
796 PrintF("CallHandlerInfo");
797 PrintF("\n - callback: ");
798 callback()->ShortPrint();
799 PrintF("\n - data: ");
800 data()->ShortPrint();
801}
802
803void TemplateInfo::TemplateInfoVerify() {
804 VerifyPointer(tag());
805 VerifyPointer(property_list());
806}
807
808void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
809 CHECK(IsFunctionTemplateInfo());
810 TemplateInfoVerify();
811 VerifyPointer(serial_number());
812 VerifyPointer(call_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000813 VerifyPointer(property_accessors());
814 VerifyPointer(prototype_template());
815 VerifyPointer(parent_template());
816 VerifyPointer(named_property_handler());
817 VerifyPointer(indexed_property_handler());
818 VerifyPointer(instance_template());
819 VerifyPointer(signature());
820 VerifyPointer(access_check_info());
821}
822
823void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
824 PrintF("FunctionTemplateInfo");
825 PrintF("\n - tag: ");
826 tag()->ShortPrint();
827 PrintF("\n - property_list: ");
828 property_list()->ShortPrint();
829 PrintF("\n - serial_number: ");
830 serial_number()->ShortPrint();
831 PrintF("\n - call_code: ");
832 call_code()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000833 PrintF("\n - property_accessors: ");
834 property_accessors()->ShortPrint();
835 PrintF("\n - prototype_template: ");
836 prototype_template()->ShortPrint();
837 PrintF("\n - parent_template: ");
838 parent_template()->ShortPrint();
839 PrintF("\n - named_property_handler: ");
840 named_property_handler()->ShortPrint();
841 PrintF("\n - indexed_property_handler: ");
842 indexed_property_handler()->ShortPrint();
843 PrintF("\n - instance_template: ");
844 instance_template()->ShortPrint();
845 PrintF("\n - signature: ");
846 signature()->ShortPrint();
847 PrintF("\n - access_check_info: ");
848 access_check_info()->ShortPrint();
849 PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false");
850 PrintF("\n - undetectable: %s", undetectable() ? "true" : "false");
851 PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false");
852}
853
854void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
855 CHECK(IsObjectTemplateInfo());
856 TemplateInfoVerify();
857 VerifyPointer(constructor());
kasper.lund212ac232008-07-16 07:07:30 +0000858 VerifyPointer(internal_field_count());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000859}
860
861void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
862 PrintF("ObjectTemplateInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000863 PrintF("\n - constructor: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864 constructor()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000865 PrintF("\n - internal_field_count: ");
866 internal_field_count()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000867}
868
869void SignatureInfo::SignatureInfoVerify() {
870 CHECK(IsSignatureInfo());
871 VerifyPointer(receiver());
872 VerifyPointer(args());
873}
874
875void SignatureInfo::SignatureInfoPrint() {
876 PrintF("SignatureInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000877 PrintF("\n - receiver: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000878 receiver()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000879 PrintF("\n - args: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000880 args()->ShortPrint();
881}
882
883void TypeSwitchInfo::TypeSwitchInfoVerify() {
884 CHECK(IsTypeSwitchInfo());
885 VerifyPointer(types());
886}
887
888void TypeSwitchInfo::TypeSwitchInfoPrint() {
889 PrintF("TypeSwitchInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000890 PrintF("\n - types: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000891 types()->ShortPrint();
892}
893
894
895void Script::ScriptVerify() {
896 CHECK(IsScript());
897 VerifyPointer(source());
898 VerifyPointer(name());
899 line_offset()->SmiVerify();
900 column_offset()->SmiVerify();
901 type()->SmiVerify();
902}
903
904
905void Script::ScriptPrint() {
906 HeapObject::PrintHeader("Script");
907 PrintF("\n - source: ");
908 source()->ShortPrint();
909 PrintF("\n - name: ");
910 name()->ShortPrint();
911 PrintF("\n - line_offset: ");
912 line_offset()->ShortPrint();
913 PrintF("\n - column_offset: ");
914 column_offset()->ShortPrint();
915 PrintF("\n - type: ");
916 type()->ShortPrint();
917 PrintF("\n");
918}
919
920
921void DebugInfo::DebugInfoVerify() {
922 CHECK(IsDebugInfo());
923 VerifyPointer(shared());
924 VerifyPointer(original_code());
925 VerifyPointer(code());
926 VerifyPointer(break_points());
927}
928
929
930void DebugInfo::DebugInfoPrint() {
931 PrintF("DebugInfo");
932 PrintF("\n - shared");
933 shared()->ShortPrint();
934 PrintF("\n - original_code");
935 original_code()->ShortPrint();
936 PrintF("\n - code");
937 code()->ShortPrint();
938 PrintF("\n - break_points");
939 break_points()->ShortPrint();
940}
941
942
943void BreakPointInfo::BreakPointInfoVerify() {
944 CHECK(IsBreakPointInfo());
945 code_position()->SmiVerify();
946 source_position()->SmiVerify();
947 statement_position()->SmiVerify();
948 VerifyPointer(break_point_objects());
949}
950
951
952void BreakPointInfo::BreakPointInfoPrint() {
953 PrintF("BreakPointInfo");
954 PrintF("\n - code_position %d", code_position());
955 PrintF("\n - source_position %d", source_position());
956 PrintF("\n - statement_position %d", statement_position());
957 PrintF("\n - break_point_objects ");
958 break_point_objects()->ShortPrint();
959}
960
961
962void JSObject::IncrementSpillStatistics(SpillInformation* info) {
963 info->number_of_objects_++;
964 // Named properties
965 if (HasFastProperties()) {
966 info->number_of_objects_with_fast_properties_++;
967 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
968 info->number_of_fast_unused_fields_ += map()->unused_property_fields();
969 } else {
970 Dictionary* dict = property_dictionary();
971 info->number_of_slow_used_properties_ += dict->NumberOfElements();
972 info->number_of_slow_unused_properties_ +=
973 dict->Capacity() - dict->NumberOfElements();
974 }
975 // Indexed properties
976 if (HasFastElements()) {
977 info->number_of_objects_with_fast_elements_++;
978 int holes = 0;
979 FixedArray* e = FixedArray::cast(elements());
980 int len = e->length();
981 for (int i = 0; i < len; i++) {
982 if (e->get(i) == Heap::the_hole_value()) holes++;
983 }
984 info->number_of_fast_used_elements_ += len - holes;
985 info->number_of_fast_unused_elements_ += holes;
986 } else {
987 Dictionary* dict = element_dictionary();
988 info->number_of_slow_used_elements_ += dict->NumberOfElements();
989 info->number_of_slow_unused_elements_ +=
990 dict->Capacity() - dict->NumberOfElements();
991 }
992}
993
994
995void JSObject::SpillInformation::Clear() {
996 number_of_objects_ = 0;
997 number_of_objects_with_fast_properties_ = 0;
998 number_of_objects_with_fast_elements_ = 0;
999 number_of_fast_used_fields_ = 0;
1000 number_of_fast_unused_fields_ = 0;
1001 number_of_slow_used_properties_ = 0;
1002 number_of_slow_unused_properties_ = 0;
1003 number_of_fast_used_elements_ = 0;
1004 number_of_fast_unused_elements_ = 0;
1005 number_of_slow_used_elements_ = 0;
1006 number_of_slow_unused_elements_ = 0;
1007}
1008
1009void JSObject::SpillInformation::Print() {
1010 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
1011
1012 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
1013 number_of_objects_with_fast_properties_,
1014 number_of_fast_used_fields_, number_of_fast_unused_fields_);
1015
1016 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
1017 number_of_objects_ - number_of_objects_with_fast_properties_,
1018 number_of_slow_used_properties_, number_of_slow_unused_properties_);
1019
1020 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
1021 number_of_objects_with_fast_elements_,
1022 number_of_fast_used_elements_, number_of_fast_unused_elements_);
1023
1024 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
1025 number_of_objects_ - number_of_objects_with_fast_elements_,
1026 number_of_slow_used_elements_, number_of_slow_unused_elements_);
1027
1028 PrintF("\n");
1029}
1030
1031
1032void DescriptorArray::PrintDescriptors() {
1033 PrintF("Descriptor array %d\n", number_of_descriptors());
1034 int number = 0;
1035 for (DescriptorReader r(this); !r.eos(); r.advance()) {
1036 Descriptor desc;
1037 r.Get(&desc);
1038 PrintF(" %d: ", number++);
1039 desc.Print();
1040 }
1041 PrintF("\n");
1042}
1043
1044
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +00001045bool DescriptorArray::IsSortedNoDuplicates() {
1046 String* current_key = NULL;
1047 uint32_t current = 0;
1048 for (DescriptorReader r(this); !r.eos(); r.advance()) {
1049 String* key = r.GetKey();
1050 if (key == current_key) {
1051 PrintDescriptors();
1052 return false;
1053 }
1054 current_key = key;
1055 uint32_t hash = r.GetKey()->Hash();
1056 if (hash < current) {
1057 PrintDescriptors();
1058 return false;
1059 }
1060 current = hash;
1061 }
1062 return true;
1063}
1064
1065
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001066#endif // DEBUG
1067
1068} } // namespace v8::internal