• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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