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