• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 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 #include "objects-visiting.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 #ifdef DEBUG
39 
Verify()40 void MaybeObject::Verify() {
41   Object* this_as_object;
42   if (ToObject(&this_as_object)) {
43     if (this_as_object->IsSmi()) {
44       Smi::cast(this_as_object)->SmiVerify();
45     } else {
46       HeapObject::cast(this_as_object)->HeapObjectVerify();
47     }
48   } else {
49     Failure::cast(this)->FailureVerify();
50   }
51 }
52 
53 
VerifyPointer(Object * p)54 void Object::VerifyPointer(Object* p) {
55   if (p->IsHeapObject()) {
56     HeapObject::VerifyHeapPointer(p);
57   } else {
58     ASSERT(p->IsSmi());
59   }
60 }
61 
62 
SmiVerify()63 void Smi::SmiVerify() {
64   ASSERT(IsSmi());
65 }
66 
67 
FailureVerify()68 void Failure::FailureVerify() {
69   ASSERT(IsFailure());
70 }
71 
72 
HeapObjectVerify()73 void HeapObject::HeapObjectVerify() {
74   InstanceType instance_type = map()->instance_type();
75 
76   if (instance_type < FIRST_NONSTRING_TYPE) {
77     String::cast(this)->StringVerify();
78     return;
79   }
80 
81   switch (instance_type) {
82     case MAP_TYPE:
83       Map::cast(this)->MapVerify();
84       break;
85     case HEAP_NUMBER_TYPE:
86       HeapNumber::cast(this)->HeapNumberVerify();
87       break;
88     case FIXED_ARRAY_TYPE:
89       FixedArray::cast(this)->FixedArrayVerify();
90       break;
91     case BYTE_ARRAY_TYPE:
92       ByteArray::cast(this)->ByteArrayVerify();
93       break;
94     case EXTERNAL_PIXEL_ARRAY_TYPE:
95       ExternalPixelArray::cast(this)->ExternalPixelArrayVerify();
96       break;
97     case EXTERNAL_BYTE_ARRAY_TYPE:
98       ExternalByteArray::cast(this)->ExternalByteArrayVerify();
99       break;
100     case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
101       ExternalUnsignedByteArray::cast(this)->ExternalUnsignedByteArrayVerify();
102       break;
103     case EXTERNAL_SHORT_ARRAY_TYPE:
104       ExternalShortArray::cast(this)->ExternalShortArrayVerify();
105       break;
106     case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
107       ExternalUnsignedShortArray::cast(this)->
108           ExternalUnsignedShortArrayVerify();
109       break;
110     case EXTERNAL_INT_ARRAY_TYPE:
111       ExternalIntArray::cast(this)->ExternalIntArrayVerify();
112       break;
113     case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
114       ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayVerify();
115       break;
116     case EXTERNAL_FLOAT_ARRAY_TYPE:
117       ExternalFloatArray::cast(this)->ExternalFloatArrayVerify();
118       break;
119     case CODE_TYPE:
120       Code::cast(this)->CodeVerify();
121       break;
122     case ODDBALL_TYPE:
123       Oddball::cast(this)->OddballVerify();
124       break;
125     case JS_OBJECT_TYPE:
126     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
127       JSObject::cast(this)->JSObjectVerify();
128       break;
129     case JS_VALUE_TYPE:
130       JSValue::cast(this)->JSValueVerify();
131       break;
132     case JS_FUNCTION_TYPE:
133       JSFunction::cast(this)->JSFunctionVerify();
134       break;
135     case JS_GLOBAL_PROXY_TYPE:
136       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
137       break;
138     case JS_GLOBAL_OBJECT_TYPE:
139       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
140       break;
141     case JS_BUILTINS_OBJECT_TYPE:
142       JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
143       break;
144     case JS_GLOBAL_PROPERTY_CELL_TYPE:
145       JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellVerify();
146       break;
147     case JS_ARRAY_TYPE:
148       JSArray::cast(this)->JSArrayVerify();
149       break;
150     case JS_REGEXP_TYPE:
151       JSRegExp::cast(this)->JSRegExpVerify();
152       break;
153     case FILLER_TYPE:
154       break;
155     case PROXY_TYPE:
156       Proxy::cast(this)->ProxyVerify();
157       break;
158     case SHARED_FUNCTION_INFO_TYPE:
159       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
160       break;
161     case JS_MESSAGE_OBJECT_TYPE:
162       JSMessageObject::cast(this)->JSMessageObjectVerify();
163       break;
164 
165 #define MAKE_STRUCT_CASE(NAME, Name, name) \
166   case NAME##_TYPE:                        \
167     Name::cast(this)->Name##Verify();      \
168     break;
169     STRUCT_LIST(MAKE_STRUCT_CASE)
170 #undef MAKE_STRUCT_CASE
171 
172     default:
173       UNREACHABLE();
174       break;
175   }
176 }
177 
178 
VerifyHeapPointer(Object * p)179 void HeapObject::VerifyHeapPointer(Object* p) {
180   ASSERT(p->IsHeapObject());
181   ASSERT(HEAP->Contains(HeapObject::cast(p)));
182 }
183 
184 
HeapNumberVerify()185 void HeapNumber::HeapNumberVerify() {
186   ASSERT(IsHeapNumber());
187 }
188 
189 
ByteArrayVerify()190 void ByteArray::ByteArrayVerify() {
191   ASSERT(IsByteArray());
192 }
193 
194 
ExternalPixelArrayVerify()195 void ExternalPixelArray::ExternalPixelArrayVerify() {
196   ASSERT(IsExternalPixelArray());
197 }
198 
199 
ExternalByteArrayVerify()200 void ExternalByteArray::ExternalByteArrayVerify() {
201   ASSERT(IsExternalByteArray());
202 }
203 
204 
ExternalUnsignedByteArrayVerify()205 void ExternalUnsignedByteArray::ExternalUnsignedByteArrayVerify() {
206   ASSERT(IsExternalUnsignedByteArray());
207 }
208 
209 
ExternalShortArrayVerify()210 void ExternalShortArray::ExternalShortArrayVerify() {
211   ASSERT(IsExternalShortArray());
212 }
213 
214 
ExternalUnsignedShortArrayVerify()215 void ExternalUnsignedShortArray::ExternalUnsignedShortArrayVerify() {
216   ASSERT(IsExternalUnsignedShortArray());
217 }
218 
219 
ExternalIntArrayVerify()220 void ExternalIntArray::ExternalIntArrayVerify() {
221   ASSERT(IsExternalIntArray());
222 }
223 
224 
ExternalUnsignedIntArrayVerify()225 void ExternalUnsignedIntArray::ExternalUnsignedIntArrayVerify() {
226   ASSERT(IsExternalUnsignedIntArray());
227 }
228 
229 
ExternalFloatArrayVerify()230 void ExternalFloatArray::ExternalFloatArrayVerify() {
231   ASSERT(IsExternalFloatArray());
232 }
233 
234 
JSObjectVerify()235 void JSObject::JSObjectVerify() {
236   VerifyHeapPointer(properties());
237   VerifyHeapPointer(elements());
238   if (HasFastProperties()) {
239     CHECK_EQ(map()->unused_property_fields(),
240              (map()->inobject_properties() + properties()->length() -
241               map()->NextFreePropertyIndex()));
242   }
243   ASSERT(map()->has_fast_elements() ==
244          (elements()->map() == GetHeap()->fixed_array_map() ||
245           elements()->map() == GetHeap()->fixed_cow_array_map()));
246   ASSERT(map()->has_fast_elements() == HasFastElements());
247 }
248 
249 
MapVerify()250 void Map::MapVerify() {
251   ASSERT(!HEAP->InNewSpace(this));
252   ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
253   ASSERT(instance_size() == kVariableSizeSentinel ||
254          (kPointerSize <= instance_size() &&
255           instance_size() < HEAP->Capacity()));
256   VerifyHeapPointer(prototype());
257   VerifyHeapPointer(instance_descriptors());
258 }
259 
260 
SharedMapVerify()261 void Map::SharedMapVerify() {
262   MapVerify();
263   ASSERT(is_shared());
264   ASSERT_EQ(GetHeap()->empty_descriptor_array(), instance_descriptors());
265   ASSERT_EQ(0, pre_allocated_property_fields());
266   ASSERT_EQ(0, unused_property_fields());
267   ASSERT_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
268       visitor_id());
269 }
270 
271 
CodeCacheVerify()272 void CodeCache::CodeCacheVerify() {
273   VerifyHeapPointer(default_cache());
274   VerifyHeapPointer(normal_type_cache());
275   ASSERT(default_cache()->IsFixedArray());
276   ASSERT(normal_type_cache()->IsUndefined()
277          || normal_type_cache()->IsCodeCacheHashTable());
278 }
279 
280 
FixedArrayVerify()281 void FixedArray::FixedArrayVerify() {
282   for (int i = 0; i < length(); i++) {
283     Object* e = get(i);
284     if (e->IsHeapObject()) {
285       VerifyHeapPointer(e);
286     } else {
287       e->Verify();
288     }
289   }
290 }
291 
292 
JSValueVerify()293 void JSValue::JSValueVerify() {
294   Object* v = value();
295   if (v->IsHeapObject()) {
296     VerifyHeapPointer(v);
297   }
298 }
299 
300 
JSMessageObjectVerify()301 void JSMessageObject::JSMessageObjectVerify() {
302   CHECK(IsJSMessageObject());
303   CHECK(type()->IsString());
304   CHECK(arguments()->IsJSArray());
305   VerifyObjectField(kStartPositionOffset);
306   VerifyObjectField(kEndPositionOffset);
307   VerifyObjectField(kArgumentsOffset);
308   VerifyObjectField(kScriptOffset);
309   VerifyObjectField(kStackTraceOffset);
310   VerifyObjectField(kStackFramesOffset);
311 }
312 
313 
StringVerify()314 void String::StringVerify() {
315   CHECK(IsString());
316   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
317   if (IsSymbol()) {
318     CHECK(!HEAP->InNewSpace(this));
319   }
320 }
321 
322 
JSFunctionVerify()323 void JSFunction::JSFunctionVerify() {
324   CHECK(IsJSFunction());
325   VerifyObjectField(kPrototypeOrInitialMapOffset);
326   VerifyObjectField(kNextFunctionLinkOffset);
327   CHECK(next_function_link()->IsUndefined() ||
328         next_function_link()->IsJSFunction());
329 }
330 
331 
SharedFunctionInfoVerify()332 void SharedFunctionInfo::SharedFunctionInfoVerify() {
333   CHECK(IsSharedFunctionInfo());
334   VerifyObjectField(kNameOffset);
335   VerifyObjectField(kCodeOffset);
336   VerifyObjectField(kScopeInfoOffset);
337   VerifyObjectField(kInstanceClassNameOffset);
338   VerifyObjectField(kFunctionDataOffset);
339   VerifyObjectField(kScriptOffset);
340   VerifyObjectField(kDebugInfoOffset);
341 }
342 
343 
JSGlobalProxyVerify()344 void JSGlobalProxy::JSGlobalProxyVerify() {
345   CHECK(IsJSGlobalProxy());
346   JSObjectVerify();
347   VerifyObjectField(JSGlobalProxy::kContextOffset);
348   // Make sure that this object has no properties, elements.
349   CHECK_EQ(0, properties()->length());
350   CHECK(HasFastElements());
351   CHECK_EQ(0, FixedArray::cast(elements())->length());
352 }
353 
354 
JSGlobalObjectVerify()355 void JSGlobalObject::JSGlobalObjectVerify() {
356   CHECK(IsJSGlobalObject());
357   JSObjectVerify();
358   for (int i = GlobalObject::kBuiltinsOffset;
359        i < JSGlobalObject::kSize;
360        i += kPointerSize) {
361     VerifyObjectField(i);
362   }
363 }
364 
365 
JSBuiltinsObjectVerify()366 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
367   CHECK(IsJSBuiltinsObject());
368   JSObjectVerify();
369   for (int i = GlobalObject::kBuiltinsOffset;
370        i < JSBuiltinsObject::kSize;
371        i += kPointerSize) {
372     VerifyObjectField(i);
373   }
374 }
375 
376 
OddballVerify()377 void Oddball::OddballVerify() {
378   CHECK(IsOddball());
379   VerifyHeapPointer(to_string());
380   Object* number = to_number();
381   if (number->IsHeapObject()) {
382     ASSERT(number == HEAP->nan_value());
383   } else {
384     ASSERT(number->IsSmi());
385     int value = Smi::cast(number)->value();
386     // Hidden oddballs have negative smis.
387     const int kLeastHiddenOddballNumber = -4;
388     ASSERT(value <= 1);
389     ASSERT(value >= kLeastHiddenOddballNumber);
390   }
391 }
392 
393 
JSGlobalPropertyCellVerify()394 void JSGlobalPropertyCell::JSGlobalPropertyCellVerify() {
395   CHECK(IsJSGlobalPropertyCell());
396   VerifyObjectField(kValueOffset);
397 }
398 
399 
CodeVerify()400 void Code::CodeVerify() {
401   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
402                   kCodeAlignment));
403   Address last_gc_pc = NULL;
404   for (RelocIterator it(this); !it.done(); it.next()) {
405     it.rinfo()->Verify();
406     // Ensure that GC will not iterate twice over the same pointer.
407     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
408       CHECK(it.rinfo()->pc() != last_gc_pc);
409       last_gc_pc = it.rinfo()->pc();
410     }
411   }
412 }
413 
414 
JSArrayVerify()415 void JSArray::JSArrayVerify() {
416   JSObjectVerify();
417   ASSERT(length()->IsNumber() || length()->IsUndefined());
418   ASSERT(elements()->IsUndefined() || elements()->IsFixedArray());
419 }
420 
421 
JSRegExpVerify()422 void JSRegExp::JSRegExpVerify() {
423   JSObjectVerify();
424   ASSERT(data()->IsUndefined() || data()->IsFixedArray());
425   switch (TypeTag()) {
426     case JSRegExp::ATOM: {
427       FixedArray* arr = FixedArray::cast(data());
428       ASSERT(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
429       break;
430     }
431     case JSRegExp::IRREGEXP: {
432       bool is_native = RegExpImpl::UsesNativeRegExp();
433 
434       FixedArray* arr = FixedArray::cast(data());
435       Object* ascii_data = arr->get(JSRegExp::kIrregexpASCIICodeIndex);
436       // TheHole : Not compiled yet.
437       // JSObject: Compilation error.
438       // Code/ByteArray: Compiled code.
439       ASSERT(ascii_data->IsTheHole() || ascii_data->IsJSObject() ||
440           (is_native ? ascii_data->IsCode() : ascii_data->IsByteArray()));
441       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
442       ASSERT(uc16_data->IsTheHole() || uc16_data->IsJSObject() ||
443           (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
444       ASSERT(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
445       ASSERT(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
446       break;
447     }
448     default:
449       ASSERT_EQ(JSRegExp::NOT_COMPILED, TypeTag());
450       ASSERT(data()->IsUndefined());
451       break;
452   }
453 }
454 
455 
ProxyVerify()456 void Proxy::ProxyVerify() {
457   ASSERT(IsProxy());
458 }
459 
460 
AccessorInfoVerify()461 void AccessorInfo::AccessorInfoVerify() {
462   CHECK(IsAccessorInfo());
463   VerifyPointer(getter());
464   VerifyPointer(setter());
465   VerifyPointer(name());
466   VerifyPointer(data());
467   VerifyPointer(flag());
468 }
469 
470 
AccessCheckInfoVerify()471 void AccessCheckInfo::AccessCheckInfoVerify() {
472   CHECK(IsAccessCheckInfo());
473   VerifyPointer(named_callback());
474   VerifyPointer(indexed_callback());
475   VerifyPointer(data());
476 }
477 
478 
InterceptorInfoVerify()479 void InterceptorInfo::InterceptorInfoVerify() {
480   CHECK(IsInterceptorInfo());
481   VerifyPointer(getter());
482   VerifyPointer(setter());
483   VerifyPointer(query());
484   VerifyPointer(deleter());
485   VerifyPointer(enumerator());
486   VerifyPointer(data());
487 }
488 
489 
CallHandlerInfoVerify()490 void CallHandlerInfo::CallHandlerInfoVerify() {
491   CHECK(IsCallHandlerInfo());
492   VerifyPointer(callback());
493   VerifyPointer(data());
494 }
495 
496 
TemplateInfoVerify()497 void TemplateInfo::TemplateInfoVerify() {
498   VerifyPointer(tag());
499   VerifyPointer(property_list());
500 }
501 
FunctionTemplateInfoVerify()502 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
503   CHECK(IsFunctionTemplateInfo());
504   TemplateInfoVerify();
505   VerifyPointer(serial_number());
506   VerifyPointer(call_code());
507   VerifyPointer(property_accessors());
508   VerifyPointer(prototype_template());
509   VerifyPointer(parent_template());
510   VerifyPointer(named_property_handler());
511   VerifyPointer(indexed_property_handler());
512   VerifyPointer(instance_template());
513   VerifyPointer(signature());
514   VerifyPointer(access_check_info());
515 }
516 
517 
ObjectTemplateInfoVerify()518 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
519   CHECK(IsObjectTemplateInfo());
520   TemplateInfoVerify();
521   VerifyPointer(constructor());
522   VerifyPointer(internal_field_count());
523 }
524 
525 
SignatureInfoVerify()526 void SignatureInfo::SignatureInfoVerify() {
527   CHECK(IsSignatureInfo());
528   VerifyPointer(receiver());
529   VerifyPointer(args());
530 }
531 
532 
TypeSwitchInfoVerify()533 void TypeSwitchInfo::TypeSwitchInfoVerify() {
534   CHECK(IsTypeSwitchInfo());
535   VerifyPointer(types());
536 }
537 
538 
ScriptVerify()539 void Script::ScriptVerify() {
540   CHECK(IsScript());
541   VerifyPointer(source());
542   VerifyPointer(name());
543   line_offset()->SmiVerify();
544   column_offset()->SmiVerify();
545   VerifyPointer(data());
546   VerifyPointer(wrapper());
547   type()->SmiVerify();
548   VerifyPointer(line_ends());
549   VerifyPointer(id());
550 }
551 
552 
553 #ifdef ENABLE_DEBUGGER_SUPPORT
DebugInfoVerify()554 void DebugInfo::DebugInfoVerify() {
555   CHECK(IsDebugInfo());
556   VerifyPointer(shared());
557   VerifyPointer(original_code());
558   VerifyPointer(code());
559   VerifyPointer(break_points());
560 }
561 
562 
BreakPointInfoVerify()563 void BreakPointInfo::BreakPointInfoVerify() {
564   CHECK(IsBreakPointInfo());
565   code_position()->SmiVerify();
566   source_position()->SmiVerify();
567   statement_position()->SmiVerify();
568   VerifyPointer(break_point_objects());
569 }
570 #endif  // ENABLE_DEBUGGER_SUPPORT
571 
572 
IncrementSpillStatistics(SpillInformation * info)573 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
574   info->number_of_objects_++;
575   // Named properties
576   if (HasFastProperties()) {
577     info->number_of_objects_with_fast_properties_++;
578     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
579     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
580   } else {
581     StringDictionary* dict = property_dictionary();
582     info->number_of_slow_used_properties_ += dict->NumberOfElements();
583     info->number_of_slow_unused_properties_ +=
584         dict->Capacity() - dict->NumberOfElements();
585   }
586   // Indexed properties
587   switch (GetElementsKind()) {
588     case FAST_ELEMENTS: {
589       info->number_of_objects_with_fast_elements_++;
590       int holes = 0;
591       FixedArray* e = FixedArray::cast(elements());
592       int len = e->length();
593       Heap* heap = HEAP;
594       for (int i = 0; i < len; i++) {
595         if (e->get(i) == heap->the_hole_value()) holes++;
596       }
597       info->number_of_fast_used_elements_   += len - holes;
598       info->number_of_fast_unused_elements_ += holes;
599       break;
600     }
601     case EXTERNAL_PIXEL_ELEMENTS: {
602       info->number_of_objects_with_fast_elements_++;
603       ExternalPixelArray* e = ExternalPixelArray::cast(elements());
604       info->number_of_fast_used_elements_ += e->length();
605       break;
606     }
607     case DICTIONARY_ELEMENTS: {
608       NumberDictionary* dict = element_dictionary();
609       info->number_of_slow_used_elements_ += dict->NumberOfElements();
610       info->number_of_slow_unused_elements_ +=
611           dict->Capacity() - dict->NumberOfElements();
612       break;
613     }
614     default:
615       UNREACHABLE();
616       break;
617   }
618 }
619 
620 
Clear()621 void JSObject::SpillInformation::Clear() {
622   number_of_objects_ = 0;
623   number_of_objects_with_fast_properties_ = 0;
624   number_of_objects_with_fast_elements_ = 0;
625   number_of_fast_used_fields_ = 0;
626   number_of_fast_unused_fields_ = 0;
627   number_of_slow_used_properties_ = 0;
628   number_of_slow_unused_properties_ = 0;
629   number_of_fast_used_elements_ = 0;
630   number_of_fast_unused_elements_ = 0;
631   number_of_slow_used_elements_ = 0;
632   number_of_slow_unused_elements_ = 0;
633 }
634 
Print()635 void JSObject::SpillInformation::Print() {
636   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
637 
638   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
639          number_of_objects_with_fast_properties_,
640          number_of_fast_used_fields_, number_of_fast_unused_fields_);
641 
642   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
643          number_of_objects_ - number_of_objects_with_fast_properties_,
644          number_of_slow_used_properties_, number_of_slow_unused_properties_);
645 
646   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
647          number_of_objects_with_fast_elements_,
648          number_of_fast_used_elements_, number_of_fast_unused_elements_);
649 
650   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
651          number_of_objects_ - number_of_objects_with_fast_elements_,
652          number_of_slow_used_elements_, number_of_slow_unused_elements_);
653 
654   PrintF("\n");
655 }
656 
657 
IsSortedNoDuplicates()658 bool DescriptorArray::IsSortedNoDuplicates() {
659   String* current_key = NULL;
660   uint32_t current = 0;
661   for (int i = 0; i < number_of_descriptors(); i++) {
662     String* key = GetKey(i);
663     if (key == current_key) {
664       PrintDescriptors();
665       return false;
666     }
667     current_key = key;
668     uint32_t hash = GetKey(i)->Hash();
669     if (hash < current) {
670       PrintDescriptors();
671       return false;
672     }
673     current = hash;
674   }
675   return true;
676 }
677 
678 
JSFunctionResultCacheVerify()679 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
680   JSFunction::cast(get(kFactoryIndex))->Verify();
681 
682   int size = Smi::cast(get(kCacheSizeIndex))->value();
683   ASSERT(kEntriesIndex <= size);
684   ASSERT(size <= length());
685   ASSERT_EQ(0, size % kEntrySize);
686 
687   int finger = Smi::cast(get(kFingerIndex))->value();
688   ASSERT(kEntriesIndex <= finger);
689   ASSERT((finger < size) || (finger == kEntriesIndex && finger == size));
690   ASSERT_EQ(0, finger % kEntrySize);
691 
692   if (FLAG_enable_slow_asserts) {
693     for (int i = kEntriesIndex; i < size; i++) {
694       ASSERT(!get(i)->IsTheHole());
695       get(i)->Verify();
696     }
697     for (int i = size; i < length(); i++) {
698       ASSERT(get(i)->IsTheHole());
699       get(i)->Verify();
700     }
701   }
702 }
703 
704 
NormalizedMapCacheVerify()705 void NormalizedMapCache::NormalizedMapCacheVerify() {
706   FixedArray::cast(this)->Verify();
707   if (FLAG_enable_slow_asserts) {
708     for (int i = 0; i < length(); i++) {
709       Object* e = get(i);
710       if (e->IsMap()) {
711         Map::cast(e)->SharedMapVerify();
712       } else {
713         ASSERT(e->IsUndefined());
714       }
715     }
716   }
717 }
718 
719 
720 #endif  // DEBUG
721 
722 } }  // namespace v8::internal
723