blob: c70ab16df6bc17f147db13847cf8b660fa616358 [file] [log] [blame]
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001// Copyright 2006-2008 Google Inc. All Rights Reserved.
2// 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
120 case JS_ARRAY_TYPE:
121 JSObject::cast(this)->JSObjectPrint();
122 break;
123 case ODDBALL_TYPE:
124 Oddball::cast(this)->to_string()->Print();
125 break;
126 case JS_FUNCTION_TYPE:
127 JSFunction::cast(this)->JSFunctionPrint();
128 break;
129 case JS_GLOBAL_OBJECT_TYPE:
130 JSGlobalObject::cast(this)->JSGlobalObjectPrint();
131 break;
132 case JS_BUILTINS_OBJECT_TYPE:
133 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
134 break;
135 case JS_VALUE_TYPE:
136 JSValue::cast(this)->value()->Print();
137 break;
138 case CODE_TYPE:
139 Code::cast(this)->CodePrint();
140 break;
141 case PROXY_TYPE:
142 Proxy::cast(this)->ProxyPrint();
143 break;
144 case SHARED_FUNCTION_INFO_TYPE:
145 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint();
146 break;
147
148#define MAKE_STRUCT_CASE(NAME, Name, name) \
149 case NAME##_TYPE: \
150 Name::cast(this)->Name##Print(); \
151 break;
152 STRUCT_LIST(MAKE_STRUCT_CASE)
153#undef MAKE_STRUCT_CASE
154
155 default:
156 PrintF("UNKNOWN TYPE %d", map()->instance_type());
157 UNREACHABLE();
158 break;
159 }
160}
161
162
163void HeapObject::HeapObjectVerify() {
164 InstanceType instance_type = map()->instance_type();
165
166 if (instance_type < FIRST_NONSTRING_TYPE) {
167 String::cast(this)->StringVerify();
168 return;
169 }
170
171 switch (instance_type) {
172 case MAP_TYPE:
173 Map::cast(this)->MapVerify();
174 break;
175 case HEAP_NUMBER_TYPE:
176 HeapNumber::cast(this)->HeapNumberVerify();
177 break;
178 case FIXED_ARRAY_TYPE:
179 FixedArray::cast(this)->FixedArrayVerify();
180 break;
181 case BYTE_ARRAY_TYPE:
182 ByteArray::cast(this)->ByteArrayVerify();
183 break;
184 case CODE_TYPE:
185 Code::cast(this)->CodeVerify();
186 break;
187 case ODDBALL_TYPE:
188 Oddball::cast(this)->OddballVerify();
189 break;
190 case JS_OBJECT_TYPE:
191 JSObject::cast(this)->JSObjectVerify();
192 break;
193 case JS_VALUE_TYPE:
194 JSValue::cast(this)->JSValueVerify();
195 break;
196 case JS_FUNCTION_TYPE:
197 JSFunction::cast(this)->JSFunctionVerify();
198 break;
199 case JS_GLOBAL_OBJECT_TYPE:
200 JSGlobalObject::cast(this)->JSGlobalObjectVerify();
201 break;
202 case JS_BUILTINS_OBJECT_TYPE:
203 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
204 break;
205 case JS_ARRAY_TYPE:
206 JSArray::cast(this)->JSArrayVerify();
207 break;
208 case FILLER_TYPE:
209 break;
210 case PROXY_TYPE:
211 Proxy::cast(this)->ProxyVerify();
212 break;
213 case SHARED_FUNCTION_INFO_TYPE:
214 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
215 break;
216
217#define MAKE_STRUCT_CASE(NAME, Name, name) \
218 case NAME##_TYPE: \
219 Name::cast(this)->Name##Verify(); \
220 break;
221 STRUCT_LIST(MAKE_STRUCT_CASE)
222#undef MAKE_STRUCT_CASE
223
224 default:
225 UNREACHABLE();
226 break;
227 }
228}
229
230
231void HeapObject::VerifyHeapPointer(Object* p) {
232 ASSERT(p->IsHeapObject());
233 ASSERT(Heap::Contains(HeapObject::cast(p)));
234}
235
236
237void HeapNumber::HeapNumberVerify() {
238 ASSERT(IsHeapNumber());
239}
240
241
242void ByteArray::ByteArrayPrint() {
243 PrintF("byte array, data starts at %p", GetDataStartAddress());
244}
245
246
247void ByteArray::ByteArrayVerify() {
248 ASSERT(IsByteArray());
249}
250
251
252void JSObject::PrintProperties() {
253 if (HasFastProperties()) {
254 for (DescriptorReader r(map()->instance_descriptors());
255 !r.eos();
256 r.advance()) {
257 PrintF(" ");
258 r.GetKey()->StringPrint();
259 PrintF(": ");
260 if (r.type() == FIELD) {
261 properties()->get(r.GetFieldIndex())->ShortPrint();
262 PrintF(" (field at offset %d)\n", r.GetFieldIndex());
263 } else if (r.type() == CONSTANT_FUNCTION) {
264 r.GetConstantFunction()->ShortPrint();
265 PrintF(" (constant function)\n");
266 } else if (r.type() == CALLBACKS) {
267 r.GetCallbacksObject()->ShortPrint();
268 PrintF(" (callback)\n");
269 } else if (r.type() == MAP_TRANSITION) {
270 PrintF(" (map transition)\n");
271 } else {
272 UNREACHABLE();
273 }
274 }
275 } else {
276 property_dictionary()->Print();
277 }
278}
279
280
281void JSObject::PrintElements() {
282 if (HasFastElements()) {
283 FixedArray* p = FixedArray::cast(elements());
284 for (int i = 0; i < p->length(); i++) {
285 PrintF(" %d: ", i);
286 p->get(i)->ShortPrint();
287 PrintF("\n");
288 }
289 } else {
290 elements()->Print();
291 }
292}
293
294
295void JSObject::JSObjectPrint() {
296 PrintF("%p: [JSObject]\n", this);
297 PrintF(" - map = %p\n", map());
298 PrintF(" - prototype = %p\n", GetPrototype());
299 PrintF(" {\n");
300 PrintProperties();
301 PrintElements();
302 PrintF(" }\n");
303}
304
305
306void JSObject::JSObjectVerify() {
307 VerifyHeapPointer(properties());
308 VerifyHeapPointer(elements());
309 if (HasFastProperties()) {
310 CHECK(map()->unused_property_fields() ==
311 (properties()->length() - map()->NextFreePropertyIndex()));
312 }
313}
314
315
316static const char* TypeToString(InstanceType type) {
317 switch (type) {
318 case MAP_TYPE: return "MAP";
319 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
320 case SHORT_SYMBOL_TYPE:
321 case MEDIUM_SYMBOL_TYPE:
322 case LONG_SYMBOL_TYPE: return "SYMBOL";
323 case SHORT_ASCII_SYMBOL_TYPE:
324 case MEDIUM_ASCII_SYMBOL_TYPE:
325 case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
326 case SHORT_SLICED_SYMBOL_TYPE:
327 case MEDIUM_SLICED_SYMBOL_TYPE:
328 case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL";
329 case SHORT_SLICED_ASCII_SYMBOL_TYPE:
330 case MEDIUM_SLICED_ASCII_SYMBOL_TYPE:
331 case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL";
332 case SHORT_CONS_SYMBOL_TYPE:
333 case MEDIUM_CONS_SYMBOL_TYPE:
334 case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
335 case SHORT_CONS_ASCII_SYMBOL_TYPE:
336 case MEDIUM_CONS_ASCII_SYMBOL_TYPE:
337 case LONG_CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
338 case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
339 case MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE:
340 case LONG_EXTERNAL_ASCII_SYMBOL_TYPE:
341 case SHORT_EXTERNAL_SYMBOL_TYPE:
342 case MEDIUM_EXTERNAL_SYMBOL_TYPE:
343 case LONG_EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
344 case SHORT_ASCII_STRING_TYPE:
345 case MEDIUM_ASCII_STRING_TYPE:
346 case LONG_ASCII_STRING_TYPE: return "ASCII_STRING";
347 case SHORT_STRING_TYPE:
348 case MEDIUM_STRING_TYPE:
349 case LONG_STRING_TYPE: return "TWO_BYTE_STRING";
350 case SHORT_CONS_STRING_TYPE:
351 case MEDIUM_CONS_STRING_TYPE:
352 case LONG_CONS_STRING_TYPE:
353 case SHORT_CONS_ASCII_STRING_TYPE:
354 case MEDIUM_CONS_ASCII_STRING_TYPE:
355 case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING";
356 case SHORT_SLICED_STRING_TYPE:
357 case MEDIUM_SLICED_STRING_TYPE:
358 case LONG_SLICED_STRING_TYPE:
359 case SHORT_SLICED_ASCII_STRING_TYPE:
360 case MEDIUM_SLICED_ASCII_STRING_TYPE:
361 case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING";
362 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
363 case MEDIUM_EXTERNAL_ASCII_STRING_TYPE:
364 case LONG_EXTERNAL_ASCII_STRING_TYPE:
365 case SHORT_EXTERNAL_STRING_TYPE:
366 case MEDIUM_EXTERNAL_STRING_TYPE:
367 case LONG_EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
368 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
369 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
370 case FILLER_TYPE: return "FILLER";
371 case JS_OBJECT_TYPE: return "JS_OBJECT";
372 case ODDBALL_TYPE: return "ODDBALL";
373 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
374 case JS_FUNCTION_TYPE: return "JS_FUNCTION";
375 case CODE_TYPE: return "CODE";
376 case JS_ARRAY_TYPE: return "JS_ARRAY";
377 case JS_VALUE_TYPE: return "JS_VALUE";
378 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
379 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
380 case PROXY_TYPE: return "PROXY";
381 case SMI_TYPE: return "SMI";
382#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
383 STRUCT_LIST(MAKE_STRUCT_CASE)
384#undef MAKE_STRUCT_CASE
385 }
386 return "UNKNOWN";
387}
388
389
390void Map::MapPrint() {
391 HeapObject::PrintHeader("Map");
392 PrintF(" - type: %s\n", TypeToString(instance_type()));
393 PrintF(" - instance size: %d\n", instance_size());
394 PrintF(" - unused property fields: %d\n", unused_property_fields());
395 PrintF(" - instance descriptors: ");
396 instance_descriptors()->ShortPrint();
397 PrintF("\n - prototype: ");
398 prototype()->ShortPrint();
399 PrintF("\n - constructor: ");
400 constructor()->ShortPrint();
401 PrintF("\n");
402}
403
404
405void Map::MapVerify() {
406 ASSERT(!Heap::InNewSpace(this));
407 ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
408 ASSERT(kPointerSize <= instance_size()
409 && instance_size() < Heap::Capacity());
410 VerifyHeapPointer(prototype());
411 VerifyHeapPointer(instance_descriptors());
412}
413
414
415void FixedArray::FixedArrayPrint() {
416 HeapObject::PrintHeader("FixedArray");
417 PrintF(" - length: %d", length());
418 for (int i = 0; i < length(); i++) {
419 PrintF("\n [%d]: ", i);
420 get(i)->ShortPrint();
421 }
422 PrintF("\n");
423}
424
425
426void FixedArray::FixedArrayVerify() {
427 for (int i = 0; i < length(); i++) {
428 Object* e = get(i);
429 if (e->IsHeapObject()) {
430 VerifyHeapPointer(e);
431 } else {
432 e->Verify();
433 }
434 }
435}
436
437
438void JSValue::JSValuePrint() {
439 HeapObject::PrintHeader("ValueObject");
440 value()->Print();
441}
442
443
444void JSValue::JSValueVerify() {
445 Object* v = value();
446 if (v->IsHeapObject()) {
447 VerifyHeapPointer(v);
448 }
449}
450
451
452void String::StringPrint() {
453 if (IsSymbol()) {
454 PrintF("#");
455 } else if (IsConsString()) {
456 PrintF("c\"");
457 } else {
458 PrintF("\"");
459 }
460
461 for (int i = 0; i < length(); i++) {
462 PrintF("%c", Get(i));
463 }
464
465 if (!IsSymbol()) PrintF("\"");
466}
467
468
469void String::StringVerify() {
470 CHECK(IsString());
471 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
472 if (IsSymbol()) {
473 CHECK(!Heap::InNewSpace(this));
474 }
475}
476
477
478void JSFunction::JSFunctionPrint() {
479 HeapObject::PrintHeader("Function");
480 PrintF(" - map = 0x%p\n", map());
481 PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no");
482 PrintF(" - initial_map = ");
483 if (has_initial_map()) {
484 initial_map()->ShortPrint();
485 }
486 PrintF("\n - shared_info = ");
487 shared()->ShortPrint();
488 PrintF("\n - name = ");
489 shared()->name()->Print();
490 PrintF("\n - context = ");
491 unchecked_context()->ShortPrint();
492 PrintF("\n - code = ");
493 code()->ShortPrint();
494 PrintF("\n");
495
496 PrintProperties();
497 PrintElements();
498
499 PrintF("\n");
500}
501
502
503void JSFunction::JSFunctionVerify() {
504 CHECK(IsJSFunction());
505 VerifyObjectField(kPrototypeOrInitialMapOffset);
506}
507
508
509void SharedFunctionInfo::SharedFunctionInfoPrint() {
510 HeapObject::PrintHeader("SharedFunctionInfo");
511 PrintF(" - name: ");
512 name()->ShortPrint();
513 PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
514 PrintF("\n - instance class name =");
515 instance_class_name()->Print();
516 PrintF("\n - code =");
517 code()->ShortPrint();
518 PrintF("\n - source code =");
519 GetSourceCode()->ShortPrint();
520 PrintF("\n - lazy load: %s",
521 lazy_load_data() == Heap::undefined_value() ? "no" : "yes");
522 // Script files are often large, hard to read.
523 // PrintF("\n - script =");
524 // script()->Print();
525 PrintF("\n - function token position = %d", function_token_position());
526 PrintF("\n - start position = %d", start_position());
527 PrintF("\n - end position = %d", end_position());
528 PrintF("\n - is expression = %d", is_expression());
529 PrintF("\n - debug info = ");
530 debug_info()->Print();
531 PrintF("\n - length = %d", length());
532 PrintF("\n");
533}
534
535void SharedFunctionInfo::SharedFunctionInfoVerify() {
536 CHECK(IsSharedFunctionInfo());
537 VerifyObjectField(kNameOffset);
538 VerifyObjectField(kCodeOffset);
539 VerifyObjectField(kInstanceClassNameOffset);
540 VerifyObjectField(kExternalReferenceDataOffset);
541 VerifyObjectField(kLazyLoadDataOffset);
542 VerifyObjectField(kScriptOffset);
543 VerifyObjectField(kDebugInfoOffset);
544}
545
546
547void JSGlobalObject::JSGlobalObjectPrint() {
548 PrintF("global ");
549 JSObjectPrint();
550}
551
552
553void JSGlobalObject::JSGlobalObjectVerify() {
554 CHECK(IsJSGlobalObject());
555 JSObjectVerify();
556 for (int i = GlobalObject::kBuiltinsOffset;
557 i < JSGlobalObject::kSize;
558 i += kPointerSize) {
559 VerifyObjectField(i);
560 }
561}
562
563
564void JSBuiltinsObject::JSBuiltinsObjectPrint() {
565 PrintF("builtins ");
566 JSObjectPrint();
567}
568
569
570void JSBuiltinsObject::JSBuiltinsObjectVerify() {
571 CHECK(IsJSBuiltinsObject());
572 JSObjectVerify();
573 for (int i = GlobalObject::kBuiltinsOffset;
574 i < JSBuiltinsObject::kSize;
575 i += kPointerSize) {
576 VerifyObjectField(i);
577 }
578}
579
580
581void Oddball::OddballVerify() {
582 CHECK(IsOddball());
583 VerifyHeapPointer(to_string());
584 Object* number = to_number();
585 if (number->IsHeapObject()) {
586 ASSERT(number == Heap::nan_value());
587 } else {
588 ASSERT(number->IsSmi());
589 int value = Smi::cast(number)->value();
590 ASSERT(value == 0 || value == 1 || value == -1);
591 }
592}
593
594
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595void Code::CodePrint() {
596 HeapObject::PrintHeader("Code");
597 PrintF("kind = %s", Kind2String(kind()));
598
599 PrintF("\nInstructions (size = %d)\n", instruction_size());
600 Disassembler::Decode(NULL /*use PrintF*/, this);
601 PrintF("\n");
602
603 PrintF("RelocInfo (size = %d)\n", relocation_size());
604 for (RelocIterator it(this); !it.done(); it.next())
605 it.rinfo()->Print();
606 PrintF("\n");
607}
608
609
610void Code::CodeVerify() {
kasper.lund7276f142008-07-30 08:49:36 +0000611 CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
612 Address last_gc_pc = NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000613 for (RelocIterator it(this); !it.done(); it.next()) {
614 it.rinfo()->Verify();
kasper.lund7276f142008-07-30 08:49:36 +0000615 // Ensure that GC will not iterate twice over the same pointer.
616 if (is_gc_reloc_mode(it.rinfo()->rmode())) {
617 CHECK(it.rinfo()->pc() != last_gc_pc);
618 last_gc_pc = it.rinfo()->pc();
619 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 }
621}
622
623
624void JSArray::JSArrayVerify() {
625 JSObjectVerify();
626 ASSERT(length()->IsNumber() || length()->IsUndefined());
627 ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
628}
629
630
631void Proxy::ProxyPrint() {
632 PrintF("proxy to %p", proxy());
633}
634
635
636void Proxy::ProxyVerify() {
637 ASSERT(IsProxy());
638}
639
640
641void Dictionary::Print() {
642 int capacity = Capacity();
643 for (int i = 0; i < capacity; i++) {
644 Object* k = KeyAt(i);
645 if (IsKey(k)) {
646 PrintF(" ");
647 if (k->IsString()) {
648 String::cast(k)->StringPrint();
649 } else {
650 k->ShortPrint();
651 }
652 PrintF(": ");
653 ValueAt(i)->ShortPrint();
654 PrintF("\n");
655 }
656 }
657}
658
659
660void AccessorInfo::AccessorInfoVerify() {
661 CHECK(IsAccessorInfo());
662 VerifyPointer(getter());
663 VerifyPointer(setter());
664 VerifyPointer(name());
665 VerifyPointer(data());
666 VerifyPointer(flag());
667}
668
669void AccessorInfo::AccessorInfoPrint() {
670 PrintF("AccessorInfo");
671 PrintF("\n - getter: ");
672 getter()->ShortPrint();
673 PrintF("\n - setter: ");
674 setter()->ShortPrint();
675 PrintF("\n - name: ");
676 name()->ShortPrint();
677 PrintF("\n - data: ");
678 data()->ShortPrint();
679 PrintF("\n - flag: ");
680 flag()->ShortPrint();
681}
682
683void AccessCheckInfo::AccessCheckInfoVerify() {
684 CHECK(IsAccessCheckInfo());
685 VerifyPointer(named_callback());
686 VerifyPointer(indexed_callback());
687 VerifyPointer(data());
688}
689
690void AccessCheckInfo::AccessCheckInfoPrint() {
691 PrintF("AccessCheckInfo");
692 PrintF("\n - named_callback: ");
693 named_callback()->ShortPrint();
694 PrintF("\n - indexed_callback: ");
695 indexed_callback()->ShortPrint();
696 PrintF("\n - data: ");
697 data()->ShortPrint();
698}
699
700void InterceptorInfo::InterceptorInfoVerify() {
701 CHECK(IsInterceptorInfo());
702 VerifyPointer(getter());
703 VerifyPointer(setter());
704 VerifyPointer(query());
705 VerifyPointer(deleter());
706 VerifyPointer(enumerator());
707 VerifyPointer(data());
708}
709
710void InterceptorInfo::InterceptorInfoPrint() {
711 PrintF("InterceptorInfo");
712 PrintF("\n - getter: ");
713 getter()->ShortPrint();
714 PrintF("\n - setter: ");
715 setter()->ShortPrint();
716 PrintF("\n - query: ");
717 query()->ShortPrint();
718 PrintF("\n - deleter: ");
719 deleter()->ShortPrint();
720 PrintF("\n - enumerator: ");
721 enumerator()->ShortPrint();
722 PrintF("\n - data: ");
723 data()->ShortPrint();
724}
725
726void CallHandlerInfo::CallHandlerInfoVerify() {
727 CHECK(IsCallHandlerInfo());
728 VerifyPointer(callback());
729 VerifyPointer(data());
730}
731
732void CallHandlerInfo::CallHandlerInfoPrint() {
733 PrintF("CallHandlerInfo");
734 PrintF("\n - callback: ");
735 callback()->ShortPrint();
736 PrintF("\n - data: ");
737 data()->ShortPrint();
738}
739
740void TemplateInfo::TemplateInfoVerify() {
741 VerifyPointer(tag());
742 VerifyPointer(property_list());
743}
744
745void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
746 CHECK(IsFunctionTemplateInfo());
747 TemplateInfoVerify();
748 VerifyPointer(serial_number());
749 VerifyPointer(call_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750 VerifyPointer(property_accessors());
751 VerifyPointer(prototype_template());
752 VerifyPointer(parent_template());
753 VerifyPointer(named_property_handler());
754 VerifyPointer(indexed_property_handler());
755 VerifyPointer(instance_template());
756 VerifyPointer(signature());
757 VerifyPointer(access_check_info());
758}
759
760void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
761 PrintF("FunctionTemplateInfo");
762 PrintF("\n - tag: ");
763 tag()->ShortPrint();
764 PrintF("\n - property_list: ");
765 property_list()->ShortPrint();
766 PrintF("\n - serial_number: ");
767 serial_number()->ShortPrint();
768 PrintF("\n - call_code: ");
769 call_code()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770 PrintF("\n - property_accessors: ");
771 property_accessors()->ShortPrint();
772 PrintF("\n - prototype_template: ");
773 prototype_template()->ShortPrint();
774 PrintF("\n - parent_template: ");
775 parent_template()->ShortPrint();
776 PrintF("\n - named_property_handler: ");
777 named_property_handler()->ShortPrint();
778 PrintF("\n - indexed_property_handler: ");
779 indexed_property_handler()->ShortPrint();
780 PrintF("\n - instance_template: ");
781 instance_template()->ShortPrint();
782 PrintF("\n - signature: ");
783 signature()->ShortPrint();
784 PrintF("\n - access_check_info: ");
785 access_check_info()->ShortPrint();
786 PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false");
787 PrintF("\n - undetectable: %s", undetectable() ? "true" : "false");
788 PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false");
789}
790
791void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
792 CHECK(IsObjectTemplateInfo());
793 TemplateInfoVerify();
794 VerifyPointer(constructor());
kasper.lund212ac232008-07-16 07:07:30 +0000795 VerifyPointer(internal_field_count());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796}
797
798void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
799 PrintF("ObjectTemplateInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000800 PrintF("\n - constructor: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801 constructor()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000802 PrintF("\n - internal_field_count: ");
803 internal_field_count()->ShortPrint();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804}
805
806void SignatureInfo::SignatureInfoVerify() {
807 CHECK(IsSignatureInfo());
808 VerifyPointer(receiver());
809 VerifyPointer(args());
810}
811
812void SignatureInfo::SignatureInfoPrint() {
813 PrintF("SignatureInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000814 PrintF("\n - receiver: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000815 receiver()->ShortPrint();
kasper.lund212ac232008-07-16 07:07:30 +0000816 PrintF("\n - args: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817 args()->ShortPrint();
818}
819
820void TypeSwitchInfo::TypeSwitchInfoVerify() {
821 CHECK(IsTypeSwitchInfo());
822 VerifyPointer(types());
823}
824
825void TypeSwitchInfo::TypeSwitchInfoPrint() {
826 PrintF("TypeSwitchInfo");
kasper.lund212ac232008-07-16 07:07:30 +0000827 PrintF("\n - types: ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 types()->ShortPrint();
829}
830
831
832void Script::ScriptVerify() {
833 CHECK(IsScript());
834 VerifyPointer(source());
835 VerifyPointer(name());
836 line_offset()->SmiVerify();
837 column_offset()->SmiVerify();
838 type()->SmiVerify();
839}
840
841
842void Script::ScriptPrint() {
843 HeapObject::PrintHeader("Script");
844 PrintF("\n - source: ");
845 source()->ShortPrint();
846 PrintF("\n - name: ");
847 name()->ShortPrint();
848 PrintF("\n - line_offset: ");
849 line_offset()->ShortPrint();
850 PrintF("\n - column_offset: ");
851 column_offset()->ShortPrint();
852 PrintF("\n - type: ");
853 type()->ShortPrint();
854 PrintF("\n");
855}
856
857
858void DebugInfo::DebugInfoVerify() {
859 CHECK(IsDebugInfo());
860 VerifyPointer(shared());
861 VerifyPointer(original_code());
862 VerifyPointer(code());
863 VerifyPointer(break_points());
864}
865
866
867void DebugInfo::DebugInfoPrint() {
868 PrintF("DebugInfo");
869 PrintF("\n - shared");
870 shared()->ShortPrint();
871 PrintF("\n - original_code");
872 original_code()->ShortPrint();
873 PrintF("\n - code");
874 code()->ShortPrint();
875 PrintF("\n - break_points");
876 break_points()->ShortPrint();
877}
878
879
880void BreakPointInfo::BreakPointInfoVerify() {
881 CHECK(IsBreakPointInfo());
882 code_position()->SmiVerify();
883 source_position()->SmiVerify();
884 statement_position()->SmiVerify();
885 VerifyPointer(break_point_objects());
886}
887
888
889void BreakPointInfo::BreakPointInfoPrint() {
890 PrintF("BreakPointInfo");
891 PrintF("\n - code_position %d", code_position());
892 PrintF("\n - source_position %d", source_position());
893 PrintF("\n - statement_position %d", statement_position());
894 PrintF("\n - break_point_objects ");
895 break_point_objects()->ShortPrint();
896}
897
898
899void JSObject::IncrementSpillStatistics(SpillInformation* info) {
900 info->number_of_objects_++;
901 // Named properties
902 if (HasFastProperties()) {
903 info->number_of_objects_with_fast_properties_++;
904 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
905 info->number_of_fast_unused_fields_ += map()->unused_property_fields();
906 } else {
907 Dictionary* dict = property_dictionary();
908 info->number_of_slow_used_properties_ += dict->NumberOfElements();
909 info->number_of_slow_unused_properties_ +=
910 dict->Capacity() - dict->NumberOfElements();
911 }
912 // Indexed properties
913 if (HasFastElements()) {
914 info->number_of_objects_with_fast_elements_++;
915 int holes = 0;
916 FixedArray* e = FixedArray::cast(elements());
917 int len = e->length();
918 for (int i = 0; i < len; i++) {
919 if (e->get(i) == Heap::the_hole_value()) holes++;
920 }
921 info->number_of_fast_used_elements_ += len - holes;
922 info->number_of_fast_unused_elements_ += holes;
923 } else {
924 Dictionary* dict = element_dictionary();
925 info->number_of_slow_used_elements_ += dict->NumberOfElements();
926 info->number_of_slow_unused_elements_ +=
927 dict->Capacity() - dict->NumberOfElements();
928 }
929}
930
931
932void JSObject::SpillInformation::Clear() {
933 number_of_objects_ = 0;
934 number_of_objects_with_fast_properties_ = 0;
935 number_of_objects_with_fast_elements_ = 0;
936 number_of_fast_used_fields_ = 0;
937 number_of_fast_unused_fields_ = 0;
938 number_of_slow_used_properties_ = 0;
939 number_of_slow_unused_properties_ = 0;
940 number_of_fast_used_elements_ = 0;
941 number_of_fast_unused_elements_ = 0;
942 number_of_slow_used_elements_ = 0;
943 number_of_slow_unused_elements_ = 0;
944}
945
946void JSObject::SpillInformation::Print() {
947 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
948
949 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
950 number_of_objects_with_fast_properties_,
951 number_of_fast_used_fields_, number_of_fast_unused_fields_);
952
953 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
954 number_of_objects_ - number_of_objects_with_fast_properties_,
955 number_of_slow_used_properties_, number_of_slow_unused_properties_);
956
957 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
958 number_of_objects_with_fast_elements_,
959 number_of_fast_used_elements_, number_of_fast_unused_elements_);
960
961 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
962 number_of_objects_ - number_of_objects_with_fast_elements_,
963 number_of_slow_used_elements_, number_of_slow_unused_elements_);
964
965 PrintF("\n");
966}
967
968
969void DescriptorArray::PrintDescriptors() {
970 PrintF("Descriptor array %d\n", number_of_descriptors());
971 int number = 0;
972 for (DescriptorReader r(this); !r.eos(); r.advance()) {
973 Descriptor desc;
974 r.Get(&desc);
975 PrintF(" %d: ", number++);
976 desc.Print();
977 }
978 PrintF("\n");
979}
980
981
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000982bool DescriptorArray::IsSortedNoDuplicates() {
983 String* current_key = NULL;
984 uint32_t current = 0;
985 for (DescriptorReader r(this); !r.eos(); r.advance()) {
986 String* key = r.GetKey();
987 if (key == current_key) {
988 PrintDescriptors();
989 return false;
990 }
991 current_key = key;
992 uint32_t hash = r.GetKey()->Hash();
993 if (hash < current) {
994 PrintDescriptors();
995 return false;
996 }
997 current = hash;
998 }
999 return true;
1000}
1001
1002
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001003#endif // DEBUG
1004
1005} } // namespace v8::internal