1 // Copyright 2006-2008 the V8 project authors. 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 #include "jsregexp.h"
34
35 namespace v8 {
36 namespace internal {
37
38 #ifdef DEBUG
39
40 static const char* TypeToString(InstanceType type);
41
42
Print()43 void Object::Print() {
44 if (IsSmi()) {
45 Smi::cast(this)->SmiPrint();
46 } else if (IsFailure()) {
47 Failure::cast(this)->FailurePrint();
48 } else {
49 HeapObject::cast(this)->HeapObjectPrint();
50 }
51 Flush();
52 }
53
54
PrintLn()55 void Object::PrintLn() {
56 Print();
57 PrintF("\n");
58 }
59
60
Verify()61 void Object::Verify() {
62 if (IsSmi()) {
63 Smi::cast(this)->SmiVerify();
64 } else if (IsFailure()) {
65 Failure::cast(this)->FailureVerify();
66 } else {
67 HeapObject::cast(this)->HeapObjectVerify();
68 }
69 }
70
71
VerifyPointer(Object * p)72 void Object::VerifyPointer(Object* p) {
73 if (p->IsHeapObject()) {
74 HeapObject::VerifyHeapPointer(p);
75 } else {
76 ASSERT(p->IsSmi());
77 }
78 }
79
80
SmiVerify()81 void Smi::SmiVerify() {
82 ASSERT(IsSmi());
83 }
84
85
FailureVerify()86 void Failure::FailureVerify() {
87 ASSERT(IsFailure());
88 }
89
90
PrintHeader(const char * id)91 void HeapObject::PrintHeader(const char* id) {
92 PrintF("%p: [%s]\n", this, id);
93 }
94
95
HeapObjectPrint()96 void HeapObject::HeapObjectPrint() {
97 InstanceType instance_type = map()->instance_type();
98
99 HandleScope scope;
100 if (instance_type < FIRST_NONSTRING_TYPE) {
101 String::cast(this)->StringPrint();
102 return;
103 }
104
105 switch (instance_type) {
106 case MAP_TYPE:
107 Map::cast(this)->MapPrint();
108 break;
109 case HEAP_NUMBER_TYPE:
110 HeapNumber::cast(this)->HeapNumberPrint();
111 break;
112 case FIXED_ARRAY_TYPE:
113 FixedArray::cast(this)->FixedArrayPrint();
114 break;
115 case BYTE_ARRAY_TYPE:
116 ByteArray::cast(this)->ByteArrayPrint();
117 break;
118 case PIXEL_ARRAY_TYPE:
119 PixelArray::cast(this)->PixelArrayPrint();
120 break;
121 case FILLER_TYPE:
122 PrintF("filler");
123 break;
124 case JS_OBJECT_TYPE: // fall through
125 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
126 case JS_ARRAY_TYPE:
127 case JS_REGEXP_TYPE:
128 JSObject::cast(this)->JSObjectPrint();
129 break;
130 case ODDBALL_TYPE:
131 Oddball::cast(this)->to_string()->Print();
132 break;
133 case JS_FUNCTION_TYPE:
134 JSFunction::cast(this)->JSFunctionPrint();
135 break;
136 case JS_GLOBAL_PROXY_TYPE:
137 JSGlobalProxy::cast(this)->JSGlobalProxyPrint();
138 break;
139 case JS_GLOBAL_OBJECT_TYPE:
140 JSGlobalObject::cast(this)->JSGlobalObjectPrint();
141 break;
142 case JS_BUILTINS_OBJECT_TYPE:
143 JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint();
144 break;
145 case JS_VALUE_TYPE:
146 PrintF("Value wrapper around:");
147 JSValue::cast(this)->value()->Print();
148 break;
149 case CODE_TYPE:
150 Code::cast(this)->CodePrint();
151 break;
152 case PROXY_TYPE:
153 Proxy::cast(this)->ProxyPrint();
154 break;
155 case SHARED_FUNCTION_INFO_TYPE:
156 SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint();
157 break;
158 case JS_GLOBAL_PROPERTY_CELL_TYPE:
159 JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint();
160 break;
161 #define MAKE_STRUCT_CASE(NAME, Name, name) \
162 case NAME##_TYPE: \
163 Name::cast(this)->Name##Print(); \
164 break;
165 STRUCT_LIST(MAKE_STRUCT_CASE)
166 #undef MAKE_STRUCT_CASE
167
168 default:
169 PrintF("UNKNOWN TYPE %d", map()->instance_type());
170 UNREACHABLE();
171 break;
172 }
173 }
174
175
HeapObjectVerify()176 void HeapObject::HeapObjectVerify() {
177 InstanceType instance_type = map()->instance_type();
178
179 if (instance_type < FIRST_NONSTRING_TYPE) {
180 String::cast(this)->StringVerify();
181 return;
182 }
183
184 switch (instance_type) {
185 case MAP_TYPE:
186 Map::cast(this)->MapVerify();
187 break;
188 case HEAP_NUMBER_TYPE:
189 HeapNumber::cast(this)->HeapNumberVerify();
190 break;
191 case FIXED_ARRAY_TYPE:
192 FixedArray::cast(this)->FixedArrayVerify();
193 break;
194 case BYTE_ARRAY_TYPE:
195 ByteArray::cast(this)->ByteArrayVerify();
196 break;
197 case PIXEL_ARRAY_TYPE:
198 PixelArray::cast(this)->PixelArrayVerify();
199 break;
200 case CODE_TYPE:
201 Code::cast(this)->CodeVerify();
202 break;
203 case ODDBALL_TYPE:
204 Oddball::cast(this)->OddballVerify();
205 break;
206 case JS_OBJECT_TYPE:
207 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
208 JSObject::cast(this)->JSObjectVerify();
209 break;
210 case JS_VALUE_TYPE:
211 JSValue::cast(this)->JSValueVerify();
212 break;
213 case JS_FUNCTION_TYPE:
214 JSFunction::cast(this)->JSFunctionVerify();
215 break;
216 case JS_GLOBAL_PROXY_TYPE:
217 JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
218 break;
219 case JS_GLOBAL_OBJECT_TYPE:
220 JSGlobalObject::cast(this)->JSGlobalObjectVerify();
221 break;
222 case JS_BUILTINS_OBJECT_TYPE:
223 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
224 break;
225 case JS_GLOBAL_PROPERTY_CELL_TYPE:
226 JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
227 break;
228 case JS_ARRAY_TYPE:
229 JSArray::cast(this)->JSArrayVerify();
230 break;
231 case JS_REGEXP_TYPE:
232 JSRegExp::cast(this)->JSRegExpVerify();
233 break;
234 case FILLER_TYPE:
235 break;
236 case PROXY_TYPE:
237 Proxy::cast(this)->ProxyVerify();
238 break;
239 case SHARED_FUNCTION_INFO_TYPE:
240 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
241 break;
242
243 #define MAKE_STRUCT_CASE(NAME, Name, name) \
244 case NAME##_TYPE: \
245 Name::cast(this)->Name##Verify(); \
246 break;
247 STRUCT_LIST(MAKE_STRUCT_CASE)
248 #undef MAKE_STRUCT_CASE
249
250 default:
251 UNREACHABLE();
252 break;
253 }
254 }
255
256
VerifyHeapPointer(Object * p)257 void HeapObject::VerifyHeapPointer(Object* p) {
258 ASSERT(p->IsHeapObject());
259 ASSERT(Heap::Contains(HeapObject::cast(p)));
260 }
261
262
HeapNumberVerify()263 void HeapNumber::HeapNumberVerify() {
264 ASSERT(IsHeapNumber());
265 }
266
267
ByteArrayPrint()268 void ByteArray::ByteArrayPrint() {
269 PrintF("byte array, data starts at %p", GetDataStartAddress());
270 }
271
272
PixelArrayPrint()273 void PixelArray::PixelArrayPrint() {
274 PrintF("pixel array");
275 }
276
277
ByteArrayVerify()278 void ByteArray::ByteArrayVerify() {
279 ASSERT(IsByteArray());
280 }
281
282
PixelArrayVerify()283 void PixelArray::PixelArrayVerify() {
284 ASSERT(IsPixelArray());
285 }
286
287
PrintProperties()288 void JSObject::PrintProperties() {
289 if (HasFastProperties()) {
290 DescriptorArray* descs = map()->instance_descriptors();
291 for (int i = 0; i < descs->number_of_descriptors(); i++) {
292 PrintF(" ");
293 descs->GetKey(i)->StringPrint();
294 PrintF(": ");
295 switch (descs->GetType(i)) {
296 case FIELD: {
297 int index = descs->GetFieldIndex(i);
298 FastPropertyAt(index)->ShortPrint();
299 PrintF(" (field at offset %d)\n", index);
300 break;
301 }
302 case CONSTANT_FUNCTION:
303 descs->GetConstantFunction(i)->ShortPrint();
304 PrintF(" (constant function)\n");
305 break;
306 case CALLBACKS:
307 descs->GetCallbacksObject(i)->ShortPrint();
308 PrintF(" (callback)\n");
309 break;
310 case MAP_TRANSITION:
311 PrintF(" (map transition)\n");
312 break;
313 case CONSTANT_TRANSITION:
314 PrintF(" (constant transition)\n");
315 break;
316 case NULL_DESCRIPTOR:
317 PrintF(" (null descriptor)\n");
318 break;
319 default:
320 UNREACHABLE();
321 break;
322 }
323 }
324 } else {
325 property_dictionary()->Print();
326 }
327 }
328
329
PrintElements()330 void JSObject::PrintElements() {
331 switch (GetElementsKind()) {
332 case FAST_ELEMENTS: {
333 // Print in array notation for non-sparse arrays.
334 FixedArray* p = FixedArray::cast(elements());
335 for (int i = 0; i < p->length(); i++) {
336 PrintF(" %d: ", i);
337 p->get(i)->ShortPrint();
338 PrintF("\n");
339 }
340 break;
341 }
342 case PIXEL_ELEMENTS: {
343 PixelArray* p = PixelArray::cast(elements());
344 for (int i = 0; i < p->length(); i++) {
345 PrintF(" %d: %d\n", i, p->get(i));
346 }
347 break;
348 }
349 case DICTIONARY_ELEMENTS:
350 elements()->Print();
351 break;
352 default:
353 UNREACHABLE();
354 break;
355 }
356 }
357
358
JSObjectPrint()359 void JSObject::JSObjectPrint() {
360 PrintF("%p: [JSObject]\n", this);
361 PrintF(" - map = %p\n", map());
362 PrintF(" - prototype = %p\n", GetPrototype());
363 PrintF(" {\n");
364 PrintProperties();
365 PrintElements();
366 PrintF(" }\n");
367 }
368
369
JSObjectVerify()370 void JSObject::JSObjectVerify() {
371 VerifyHeapPointer(properties());
372 VerifyHeapPointer(elements());
373 if (HasFastProperties()) {
374 CHECK_EQ(map()->unused_property_fields(),
375 (map()->inobject_properties() + properties()->length() -
376 map()->NextFreePropertyIndex()));
377 }
378 }
379
380
TypeToString(InstanceType type)381 static const char* TypeToString(InstanceType type) {
382 switch (type) {
383 case INVALID_TYPE: return "INVALID";
384 case MAP_TYPE: return "MAP";
385 case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
386 case SHORT_SYMBOL_TYPE:
387 case MEDIUM_SYMBOL_TYPE:
388 case LONG_SYMBOL_TYPE: return "SYMBOL";
389 case SHORT_ASCII_SYMBOL_TYPE:
390 case MEDIUM_ASCII_SYMBOL_TYPE:
391 case LONG_ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
392 case SHORT_SLICED_SYMBOL_TYPE:
393 case MEDIUM_SLICED_SYMBOL_TYPE:
394 case LONG_SLICED_SYMBOL_TYPE: return "SLICED_SYMBOL";
395 case SHORT_SLICED_ASCII_SYMBOL_TYPE:
396 case MEDIUM_SLICED_ASCII_SYMBOL_TYPE:
397 case LONG_SLICED_ASCII_SYMBOL_TYPE: return "SLICED_ASCII_SYMBOL";
398 case SHORT_CONS_SYMBOL_TYPE:
399 case MEDIUM_CONS_SYMBOL_TYPE:
400 case LONG_CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
401 case SHORT_CONS_ASCII_SYMBOL_TYPE:
402 case MEDIUM_CONS_ASCII_SYMBOL_TYPE:
403 case LONG_CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
404 case SHORT_EXTERNAL_ASCII_SYMBOL_TYPE:
405 case MEDIUM_EXTERNAL_ASCII_SYMBOL_TYPE:
406 case LONG_EXTERNAL_ASCII_SYMBOL_TYPE:
407 case SHORT_EXTERNAL_SYMBOL_TYPE:
408 case MEDIUM_EXTERNAL_SYMBOL_TYPE:
409 case LONG_EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
410 case SHORT_ASCII_STRING_TYPE:
411 case MEDIUM_ASCII_STRING_TYPE:
412 case LONG_ASCII_STRING_TYPE: return "ASCII_STRING";
413 case SHORT_STRING_TYPE:
414 case MEDIUM_STRING_TYPE:
415 case LONG_STRING_TYPE: return "TWO_BYTE_STRING";
416 case SHORT_CONS_STRING_TYPE:
417 case MEDIUM_CONS_STRING_TYPE:
418 case LONG_CONS_STRING_TYPE:
419 case SHORT_CONS_ASCII_STRING_TYPE:
420 case MEDIUM_CONS_ASCII_STRING_TYPE:
421 case LONG_CONS_ASCII_STRING_TYPE: return "CONS_STRING";
422 case SHORT_SLICED_STRING_TYPE:
423 case MEDIUM_SLICED_STRING_TYPE:
424 case LONG_SLICED_STRING_TYPE:
425 case SHORT_SLICED_ASCII_STRING_TYPE:
426 case MEDIUM_SLICED_ASCII_STRING_TYPE:
427 case LONG_SLICED_ASCII_STRING_TYPE: return "SLICED_STRING";
428 case SHORT_EXTERNAL_ASCII_STRING_TYPE:
429 case MEDIUM_EXTERNAL_ASCII_STRING_TYPE:
430 case LONG_EXTERNAL_ASCII_STRING_TYPE:
431 case SHORT_EXTERNAL_STRING_TYPE:
432 case MEDIUM_EXTERNAL_STRING_TYPE:
433 case LONG_EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
434 case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
435 case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
436 case PIXEL_ARRAY_TYPE: return "PIXEL_ARRAY";
437 case FILLER_TYPE: return "FILLER";
438 case JS_OBJECT_TYPE: return "JS_OBJECT";
439 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
440 case ODDBALL_TYPE: return "ODDBALL";
441 case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL";
442 case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
443 case JS_FUNCTION_TYPE: return "JS_FUNCTION";
444 case CODE_TYPE: return "CODE";
445 case JS_ARRAY_TYPE: return "JS_ARRAY";
446 case JS_REGEXP_TYPE: return "JS_REGEXP";
447 case JS_VALUE_TYPE: return "JS_VALUE";
448 case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
449 case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
450 case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
451 case PROXY_TYPE: return "PROXY";
452 case SMI_TYPE: return "SMI";
453 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
454 STRUCT_LIST(MAKE_STRUCT_CASE)
455 #undef MAKE_STRUCT_CASE
456 }
457 return "UNKNOWN";
458 }
459
460
MapPrint()461 void Map::MapPrint() {
462 HeapObject::PrintHeader("Map");
463 PrintF(" - type: %s\n", TypeToString(instance_type()));
464 PrintF(" - instance size: %d\n", instance_size());
465 PrintF(" - inobject properties: %d\n", inobject_properties());
466 PrintF(" - pre-allocated property fields: %d\n",
467 pre_allocated_property_fields());
468 PrintF(" - unused property fields: %d\n", unused_property_fields());
469 if (is_hidden_prototype()) {
470 PrintF(" - hidden_prototype\n");
471 }
472 if (has_named_interceptor()) {
473 PrintF(" - named_interceptor\n");
474 }
475 if (has_indexed_interceptor()) {
476 PrintF(" - indexed_interceptor\n");
477 }
478 if (is_undetectable()) {
479 PrintF(" - undetectable\n");
480 }
481 if (needs_loading()) {
482 PrintF(" - needs_loading\n");
483 }
484 if (has_instance_call_handler()) {
485 PrintF(" - instance_call_handler\n");
486 }
487 if (is_access_check_needed()) {
488 PrintF(" - access_check_needed\n");
489 }
490 PrintF(" - instance descriptors: ");
491 instance_descriptors()->ShortPrint();
492 PrintF("\n - prototype: ");
493 prototype()->ShortPrint();
494 PrintF("\n - constructor: ");
495 constructor()->ShortPrint();
496 PrintF("\n");
497 }
498
499
MapVerify()500 void Map::MapVerify() {
501 ASSERT(!Heap::InNewSpace(this));
502 ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
503 ASSERT(kPointerSize <= instance_size()
504 && instance_size() < Heap::Capacity());
505 VerifyHeapPointer(prototype());
506 VerifyHeapPointer(instance_descriptors());
507 }
508
509
FixedArrayPrint()510 void FixedArray::FixedArrayPrint() {
511 HeapObject::PrintHeader("FixedArray");
512 PrintF(" - length: %d", length());
513 for (int i = 0; i < length(); i++) {
514 PrintF("\n [%d]: ", i);
515 get(i)->ShortPrint();
516 }
517 PrintF("\n");
518 }
519
520
FixedArrayVerify()521 void FixedArray::FixedArrayVerify() {
522 for (int i = 0; i < length(); i++) {
523 Object* e = get(i);
524 if (e->IsHeapObject()) {
525 VerifyHeapPointer(e);
526 } else {
527 e->Verify();
528 }
529 }
530 }
531
532
JSValuePrint()533 void JSValue::JSValuePrint() {
534 HeapObject::PrintHeader("ValueObject");
535 value()->Print();
536 }
537
538
JSValueVerify()539 void JSValue::JSValueVerify() {
540 Object* v = value();
541 if (v->IsHeapObject()) {
542 VerifyHeapPointer(v);
543 }
544 }
545
546
StringPrint()547 void String::StringPrint() {
548 if (StringShape(this).IsSymbol()) {
549 PrintF("#");
550 } else if (StringShape(this).IsCons()) {
551 PrintF("c\"");
552 } else {
553 PrintF("\"");
554 }
555
556 for (int i = 0; i < length(); i++) {
557 PrintF("%c", Get(i));
558 }
559
560 if (!StringShape(this).IsSymbol()) PrintF("\"");
561 }
562
563
StringVerify()564 void String::StringVerify() {
565 CHECK(IsString());
566 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
567 if (IsSymbol()) {
568 CHECK(!Heap::InNewSpace(this));
569 }
570 }
571
572
JSFunctionPrint()573 void JSFunction::JSFunctionPrint() {
574 HeapObject::PrintHeader("Function");
575 PrintF(" - map = 0x%p\n", map());
576 PrintF(" - is boilerplate: %s\n", IsBoilerplate() ? "yes" : "no");
577 PrintF(" - initial_map = ");
578 if (has_initial_map()) {
579 initial_map()->ShortPrint();
580 }
581 PrintF("\n - shared_info = ");
582 shared()->ShortPrint();
583 PrintF("\n - name = ");
584 shared()->name()->Print();
585 PrintF("\n - context = ");
586 unchecked_context()->ShortPrint();
587 PrintF("\n - code = ");
588 code()->ShortPrint();
589 PrintF("\n");
590
591 PrintProperties();
592 PrintElements();
593
594 PrintF("\n");
595 }
596
597
JSFunctionVerify()598 void JSFunction::JSFunctionVerify() {
599 CHECK(IsJSFunction());
600 VerifyObjectField(kPrototypeOrInitialMapOffset);
601 }
602
603
SharedFunctionInfoPrint()604 void SharedFunctionInfo::SharedFunctionInfoPrint() {
605 HeapObject::PrintHeader("SharedFunctionInfo");
606 PrintF(" - name: ");
607 name()->ShortPrint();
608 PrintF("\n - expected_nof_properties: %d", expected_nof_properties());
609 PrintF("\n - instance class name = ");
610 instance_class_name()->Print();
611 PrintF("\n - code = ");
612 code()->ShortPrint();
613 PrintF("\n - source code = ");
614 GetSourceCode()->ShortPrint();
615 // Script files are often large, hard to read.
616 // PrintF("\n - script =");
617 // script()->Print();
618 PrintF("\n - function token position = %d", function_token_position());
619 PrintF("\n - start position = %d", start_position());
620 PrintF("\n - end position = %d", end_position());
621 PrintF("\n - is expression = %d", is_expression());
622 PrintF("\n - debug info = ");
623 debug_info()->ShortPrint();
624 PrintF("\n - length = %d", length());
625 PrintF("\n - has_only_this_property_assignments = %d",
626 has_only_this_property_assignments());
627 PrintF("\n - has_only_simple_this_property_assignments = %d",
628 has_only_simple_this_property_assignments());
629 PrintF("\n - this_property_assignments = ");
630 this_property_assignments()->ShortPrint();
631 PrintF("\n");
632 }
633
SharedFunctionInfoVerify()634 void SharedFunctionInfo::SharedFunctionInfoVerify() {
635 CHECK(IsSharedFunctionInfo());
636 VerifyObjectField(kNameOffset);
637 VerifyObjectField(kCodeOffset);
638 VerifyObjectField(kInstanceClassNameOffset);
639 VerifyObjectField(kExternalReferenceDataOffset);
640 VerifyObjectField(kScriptOffset);
641 VerifyObjectField(kDebugInfoOffset);
642 }
643
644
JSGlobalProxyPrint()645 void JSGlobalProxy::JSGlobalProxyPrint() {
646 PrintF("global_proxy");
647 JSObjectPrint();
648 PrintF("context : ");
649 context()->ShortPrint();
650 PrintF("\n");
651 }
652
653
JSGlobalProxyVerify()654 void JSGlobalProxy::JSGlobalProxyVerify() {
655 CHECK(IsJSGlobalProxy());
656 JSObjectVerify();
657 VerifyObjectField(JSGlobalProxy::kContextOffset);
658 // Make sure that this object has no properties, elements.
659 CHECK_EQ(0, properties()->length());
660 CHECK_EQ(0, elements()->length());
661 }
662
663
JSGlobalObjectPrint()664 void JSGlobalObject::JSGlobalObjectPrint() {
665 PrintF("global ");
666 JSObjectPrint();
667 PrintF("global context : ");
668 global_context()->ShortPrint();
669 PrintF("\n");
670 }
671
672
JSGlobalObjectVerify()673 void JSGlobalObject::JSGlobalObjectVerify() {
674 CHECK(IsJSGlobalObject());
675 JSObjectVerify();
676 for (int i = GlobalObject::kBuiltinsOffset;
677 i < JSGlobalObject::kSize;
678 i += kPointerSize) {
679 VerifyObjectField(i);
680 }
681 }
682
683
JSBuiltinsObjectPrint()684 void JSBuiltinsObject::JSBuiltinsObjectPrint() {
685 PrintF("builtins ");
686 JSObjectPrint();
687 }
688
689
JSBuiltinsObjectVerify()690 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
691 CHECK(IsJSBuiltinsObject());
692 JSObjectVerify();
693 for (int i = GlobalObject::kBuiltinsOffset;
694 i < JSBuiltinsObject::kSize;
695 i += kPointerSize) {
696 VerifyObjectField(i);
697 }
698 }
699
700
OddballVerify()701 void Oddball::OddballVerify() {
702 CHECK(IsOddball());
703 VerifyHeapPointer(to_string());
704 Object* number = to_number();
705 if (number->IsHeapObject()) {
706 ASSERT(number == Heap::nan_value());
707 } else {
708 ASSERT(number->IsSmi());
709 int value = Smi::cast(number)->value();
710 ASSERT(value == 0 || value == 1 || value == -1 ||
711 value == -2 || value == -3);
712 }
713 }
714
715
JSGlobalPropertyCellVerify()716 void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
717 CHECK(IsJSGlobalPropertyCell());
718 VerifyObjectField(kValueOffset);
719 }
720
721
JSGlobalPropertyCellPrint()722 void JSGlobalPropertyCell::JSGlobalPropertyCellPrint() {
723 HeapObject::PrintHeader("JSGlobalPropertyCell");
724 }
725
726
CodePrint()727 void Code::CodePrint() {
728 HeapObject::PrintHeader("Code");
729 #ifdef ENABLE_DISASSEMBLER
730 Disassemble(NULL);
731 #endif
732 }
733
734
CodeVerify()735 void Code::CodeVerify() {
736 CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
737 CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
738 static_cast<intptr_t>(kCodeAlignment)));
739 Address last_gc_pc = NULL;
740 for (RelocIterator it(this); !it.done(); it.next()) {
741 it.rinfo()->Verify();
742 // Ensure that GC will not iterate twice over the same pointer.
743 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
744 CHECK(it.rinfo()->pc() != last_gc_pc);
745 last_gc_pc = it.rinfo()->pc();
746 }
747 }
748 }
749
750
JSArrayVerify()751 void JSArray::JSArrayVerify() {
752 JSObjectVerify();
753 ASSERT(length()->IsNumber() || length()->IsUndefined());
754 ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
755 }
756
757
JSRegExpVerify()758 void JSRegExp::JSRegExpVerify() {
759 JSObjectVerify();
760 ASSERT(data()->IsUndefined() || data()->IsFixedArray());
761 switch (TypeTag()) {
762 case JSRegExp::ATOM: {
763 FixedArray* arr = FixedArray::cast(data());
764 ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
765 break;
766 }
767 case JSRegExp::IRREGEXP: {
768 bool is_native = RegExpImpl::UsesNativeRegExp();
769
770 FixedArray* arr = FixedArray::cast(data());
771 Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
772 // TheHole : Not compiled yet.
773 // JSObject: Compilation error.
774 // Code/ByteArray: Compiled code.
775 ASSERT(ascii_data->IsTheHole() || ascii_data->IsJSObject() ||
776 (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
777 Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
778 ASSERT(uc16_data->IsTheHole() || ascii_data->IsJSObject() ||
779 (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
780 ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
781 ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
782 break;
783 }
784 default:
785 ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
786 ASSERT(data()->IsUndefined());
787 break;
788 }
789 }
790
791
ProxyPrint()792 void Proxy::ProxyPrint() {
793 PrintF("proxy to %p", proxy());
794 }
795
796
ProxyVerify()797 void Proxy::ProxyVerify() {
798 ASSERT(IsProxy());
799 }
800
801
AccessorInfoVerify()802 void AccessorInfo::AccessorInfoVerify() {
803 CHECK(IsAccessorInfo());
804 VerifyPointer(getter());
805 VerifyPointer(setter());
806 VerifyPointer(name());
807 VerifyPointer(data());
808 VerifyPointer(flag());
809 }
810
AccessorInfoPrint()811 void AccessorInfo::AccessorInfoPrint() {
812 HeapObject::PrintHeader("AccessorInfo");
813 PrintF("\n - getter: ");
814 getter()->ShortPrint();
815 PrintF("\n - setter: ");
816 setter()->ShortPrint();
817 PrintF("\n - name: ");
818 name()->ShortPrint();
819 PrintF("\n - data: ");
820 data()->ShortPrint();
821 PrintF("\n - flag: ");
822 flag()->ShortPrint();
823 }
824
AccessCheckInfoVerify()825 void AccessCheckInfo::AccessCheckInfoVerify() {
826 CHECK(IsAccessCheckInfo());
827 VerifyPointer(named_callback());
828 VerifyPointer(indexed_callback());
829 VerifyPointer(data());
830 }
831
AccessCheckInfoPrint()832 void AccessCheckInfo::AccessCheckInfoPrint() {
833 HeapObject::PrintHeader("AccessCheckInfo");
834 PrintF("\n - named_callback: ");
835 named_callback()->ShortPrint();
836 PrintF("\n - indexed_callback: ");
837 indexed_callback()->ShortPrint();
838 PrintF("\n - data: ");
839 data()->ShortPrint();
840 }
841
InterceptorInfoVerify()842 void InterceptorInfo::InterceptorInfoVerify() {
843 CHECK(IsInterceptorInfo());
844 VerifyPointer(getter());
845 VerifyPointer(setter());
846 VerifyPointer(query());
847 VerifyPointer(deleter());
848 VerifyPointer(enumerator());
849 VerifyPointer(data());
850 }
851
InterceptorInfoPrint()852 void InterceptorInfo::InterceptorInfoPrint() {
853 HeapObject::PrintHeader("InterceptorInfo");
854 PrintF("\n - getter: ");
855 getter()->ShortPrint();
856 PrintF("\n - setter: ");
857 setter()->ShortPrint();
858 PrintF("\n - query: ");
859 query()->ShortPrint();
860 PrintF("\n - deleter: ");
861 deleter()->ShortPrint();
862 PrintF("\n - enumerator: ");
863 enumerator()->ShortPrint();
864 PrintF("\n - data: ");
865 data()->ShortPrint();
866 }
867
CallHandlerInfoVerify()868 void CallHandlerInfo::CallHandlerInfoVerify() {
869 CHECK(IsCallHandlerInfo());
870 VerifyPointer(callback());
871 VerifyPointer(data());
872 }
873
CallHandlerInfoPrint()874 void CallHandlerInfo::CallHandlerInfoPrint() {
875 HeapObject::PrintHeader("CallHandlerInfo");
876 PrintF("\n - callback: ");
877 callback()->ShortPrint();
878 PrintF("\n - data: ");
879 data()->ShortPrint();
880 }
881
TemplateInfoVerify()882 void TemplateInfo::TemplateInfoVerify() {
883 VerifyPointer(tag());
884 VerifyPointer(property_list());
885 }
886
FunctionTemplateInfoVerify()887 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
888 CHECK(IsFunctionTemplateInfo());
889 TemplateInfoVerify();
890 VerifyPointer(serial_number());
891 VerifyPointer(call_code());
892 VerifyPointer(property_accessors());
893 VerifyPointer(prototype_template());
894 VerifyPointer(parent_template());
895 VerifyPointer(named_property_handler());
896 VerifyPointer(indexed_property_handler());
897 VerifyPointer(instance_template());
898 VerifyPointer(signature());
899 VerifyPointer(access_check_info());
900 }
901
FunctionTemplateInfoPrint()902 void FunctionTemplateInfo::FunctionTemplateInfoPrint() {
903 HeapObject::PrintHeader("FunctionTemplateInfo");
904 PrintF("\n - tag: ");
905 tag()->ShortPrint();
906 PrintF("\n - property_list: ");
907 property_list()->ShortPrint();
908 PrintF("\n - serial_number: ");
909 serial_number()->ShortPrint();
910 PrintF("\n - call_code: ");
911 call_code()->ShortPrint();
912 PrintF("\n - property_accessors: ");
913 property_accessors()->ShortPrint();
914 PrintF("\n - prototype_template: ");
915 prototype_template()->ShortPrint();
916 PrintF("\n - parent_template: ");
917 parent_template()->ShortPrint();
918 PrintF("\n - named_property_handler: ");
919 named_property_handler()->ShortPrint();
920 PrintF("\n - indexed_property_handler: ");
921 indexed_property_handler()->ShortPrint();
922 PrintF("\n - instance_template: ");
923 instance_template()->ShortPrint();
924 PrintF("\n - signature: ");
925 signature()->ShortPrint();
926 PrintF("\n - access_check_info: ");
927 access_check_info()->ShortPrint();
928 PrintF("\n - hidden_prototype: %s", hidden_prototype() ? "true" : "false");
929 PrintF("\n - undetectable: %s", undetectable() ? "true" : "false");
930 PrintF("\n - need_access_check: %s", needs_access_check() ? "true" : "false");
931 }
932
ObjectTemplateInfoVerify()933 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
934 CHECK(IsObjectTemplateInfo());
935 TemplateInfoVerify();
936 VerifyPointer(constructor());
937 VerifyPointer(internal_field_count());
938 }
939
ObjectTemplateInfoPrint()940 void ObjectTemplateInfo::ObjectTemplateInfoPrint() {
941 HeapObject::PrintHeader("ObjectTemplateInfo");
942 PrintF("\n - constructor: ");
943 constructor()->ShortPrint();
944 PrintF("\n - internal_field_count: ");
945 internal_field_count()->ShortPrint();
946 }
947
SignatureInfoVerify()948 void SignatureInfo::SignatureInfoVerify() {
949 CHECK(IsSignatureInfo());
950 VerifyPointer(receiver());
951 VerifyPointer(args());
952 }
953
SignatureInfoPrint()954 void SignatureInfo::SignatureInfoPrint() {
955 HeapObject::PrintHeader("SignatureInfo");
956 PrintF("\n - receiver: ");
957 receiver()->ShortPrint();
958 PrintF("\n - args: ");
959 args()->ShortPrint();
960 }
961
TypeSwitchInfoVerify()962 void TypeSwitchInfo::TypeSwitchInfoVerify() {
963 CHECK(IsTypeSwitchInfo());
964 VerifyPointer(types());
965 }
966
TypeSwitchInfoPrint()967 void TypeSwitchInfo::TypeSwitchInfoPrint() {
968 HeapObject::PrintHeader("TypeSwitchInfo");
969 PrintF("\n - types: ");
970 types()->ShortPrint();
971 }
972
973
ScriptVerify()974 void Script::ScriptVerify() {
975 CHECK(IsScript());
976 VerifyPointer(source());
977 VerifyPointer(name());
978 line_offset()->SmiVerify();
979 column_offset()->SmiVerify();
980 VerifyPointer(data());
981 VerifyPointer(wrapper());
982 type()->SmiVerify();
983 VerifyPointer(line_ends());
984 VerifyPointer(id());
985 }
986
987
ScriptPrint()988 void Script::ScriptPrint() {
989 HeapObject::PrintHeader("Script");
990 PrintF("\n - source: ");
991 source()->ShortPrint();
992 PrintF("\n - name: ");
993 name()->ShortPrint();
994 PrintF("\n - line_offset: ");
995 line_offset()->ShortPrint();
996 PrintF("\n - column_offset: ");
997 column_offset()->ShortPrint();
998 PrintF("\n - type: ");
999 type()->ShortPrint();
1000 PrintF("\n - id: ");
1001 id()->ShortPrint();
1002 PrintF("\n");
1003 }
1004
1005
1006 #ifdef ENABLE_DEBUGGER_SUPPORT
DebugInfoVerify()1007 void DebugInfo::DebugInfoVerify() {
1008 CHECK(IsDebugInfo());
1009 VerifyPointer(shared());
1010 VerifyPointer(original_code());
1011 VerifyPointer(code());
1012 VerifyPointer(break_points());
1013 }
1014
1015
DebugInfoPrint()1016 void DebugInfo::DebugInfoPrint() {
1017 HeapObject::PrintHeader("DebugInfo");
1018 PrintF("\n - shared: ");
1019 shared()->ShortPrint();
1020 PrintF("\n - original_code: ");
1021 original_code()->ShortPrint();
1022 PrintF("\n - code: ");
1023 code()->ShortPrint();
1024 PrintF("\n - break_points: ");
1025 break_points()->Print();
1026 }
1027
1028
BreakPointInfoVerify()1029 void BreakPointInfo::BreakPointInfoVerify() {
1030 CHECK(IsBreakPointInfo());
1031 code_position()->SmiVerify();
1032 source_position()->SmiVerify();
1033 statement_position()->SmiVerify();
1034 VerifyPointer(break_point_objects());
1035 }
1036
1037
BreakPointInfoPrint()1038 void BreakPointInfo::BreakPointInfoPrint() {
1039 HeapObject::PrintHeader("BreakPointInfo");
1040 PrintF("\n - code_position: %d", code_position());
1041 PrintF("\n - source_position: %d", source_position());
1042 PrintF("\n - statement_position: %d", statement_position());
1043 PrintF("\n - break_point_objects: ");
1044 break_point_objects()->ShortPrint();
1045 }
1046 #endif
1047
1048
IncrementSpillStatistics(SpillInformation * info)1049 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
1050 info->number_of_objects_++;
1051 // Named properties
1052 if (HasFastProperties()) {
1053 info->number_of_objects_with_fast_properties_++;
1054 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
1055 info->number_of_fast_unused_fields_ += map()->unused_property_fields();
1056 } else {
1057 StringDictionary* dict = property_dictionary();
1058 info->number_of_slow_used_properties_ += dict->NumberOfElements();
1059 info->number_of_slow_unused_properties_ +=
1060 dict->Capacity() - dict->NumberOfElements();
1061 }
1062 // Indexed properties
1063 switch (GetElementsKind()) {
1064 case FAST_ELEMENTS: {
1065 info->number_of_objects_with_fast_elements_++;
1066 int holes = 0;
1067 FixedArray* e = FixedArray::cast(elements());
1068 int len = e->length();
1069 for (int i = 0; i < len; i++) {
1070 if (e->get(i) == Heap::the_hole_value()) holes++;
1071 }
1072 info->number_of_fast_used_elements_ += len - holes;
1073 info->number_of_fast_unused_elements_ += holes;
1074 break;
1075 }
1076 case PIXEL_ELEMENTS: {
1077 info->number_of_objects_with_fast_elements_++;
1078 PixelArray* e = PixelArray::cast(elements());
1079 info->number_of_fast_used_elements_ += e->length();
1080 break;
1081 }
1082 case DICTIONARY_ELEMENTS: {
1083 NumberDictionary* dict = element_dictionary();
1084 info->number_of_slow_used_elements_ += dict->NumberOfElements();
1085 info->number_of_slow_unused_elements_ +=
1086 dict->Capacity() - dict->NumberOfElements();
1087 break;
1088 }
1089 default:
1090 UNREACHABLE();
1091 break;
1092 }
1093 }
1094
1095
Clear()1096 void JSObject::SpillInformation::Clear() {
1097 number_of_objects_ = 0;
1098 number_of_objects_with_fast_properties_ = 0;
1099 number_of_objects_with_fast_elements_ = 0;
1100 number_of_fast_used_fields_ = 0;
1101 number_of_fast_unused_fields_ = 0;
1102 number_of_slow_used_properties_ = 0;
1103 number_of_slow_unused_properties_ = 0;
1104 number_of_fast_used_elements_ = 0;
1105 number_of_fast_unused_elements_ = 0;
1106 number_of_slow_used_elements_ = 0;
1107 number_of_slow_unused_elements_ = 0;
1108 }
1109
Print()1110 void JSObject::SpillInformation::Print() {
1111 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
1112
1113 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
1114 number_of_objects_with_fast_properties_,
1115 number_of_fast_used_fields_, number_of_fast_unused_fields_);
1116
1117 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
1118 number_of_objects_ - number_of_objects_with_fast_properties_,
1119 number_of_slow_used_properties_, number_of_slow_unused_properties_);
1120
1121 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
1122 number_of_objects_with_fast_elements_,
1123 number_of_fast_used_elements_, number_of_fast_unused_elements_);
1124
1125 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
1126 number_of_objects_ - number_of_objects_with_fast_elements_,
1127 number_of_slow_used_elements_, number_of_slow_unused_elements_);
1128
1129 PrintF("\n");
1130 }
1131
1132
PrintDescriptors()1133 void DescriptorArray::PrintDescriptors() {
1134 PrintF("Descriptor array %d\n", number_of_descriptors());
1135 for (int i = 0; i < number_of_descriptors(); i++) {
1136 PrintF(" %d: ", i);
1137 Descriptor desc;
1138 Get(i, &desc);
1139 desc.Print();
1140 }
1141 PrintF("\n");
1142 }
1143
1144
IsSortedNoDuplicates()1145 bool DescriptorArray::IsSortedNoDuplicates() {
1146 String* current_key = NULL;
1147 uint32_t current = 0;
1148 for (int i = 0; i < number_of_descriptors(); i++) {
1149 String* key = GetKey(i);
1150 if (key == current_key) {
1151 PrintDescriptors();
1152 return false;
1153 }
1154 current_key = key;
1155 uint32_t hash = GetKey(i)->Hash();
1156 if (hash < current) {
1157 PrintDescriptors();
1158 return false;
1159 }
1160 current = hash;
1161 }
1162 return true;
1163 }
1164
1165
1166 #endif // DEBUG
1167
1168 } } // namespace v8::internal
1169