1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "src/disasm.h"
8 #include "src/disassembler.h"
9 #include "src/heap/objects-visiting.h"
10 #include "src/jsregexp.h"
11 #include "src/macro-assembler.h"
12 #include "src/ostreams.h"
19 void Object::ObjectVerify() {
21 Smi::cast(this)->SmiVerify();
23 HeapObject::cast(this)->HeapObjectVerify();
28 void Object::VerifyPointer(Object* p) {
29 if (p->IsHeapObject()) {
30 HeapObject::VerifyHeapPointer(p);
37 void Smi::SmiVerify() {
42 void HeapObject::HeapObjectVerify() {
43 InstanceType instance_type = map()->instance_type();
45 if (instance_type < FIRST_NONSTRING_TYPE) {
46 String::cast(this)->StringVerify();
50 switch (instance_type) {
52 Symbol::cast(this)->SymbolVerify();
55 Map::cast(this)->MapVerify();
57 case HEAP_NUMBER_TYPE:
58 case MUTABLE_HEAP_NUMBER_TYPE:
59 HeapNumber::cast(this)->HeapNumberVerify();
62 Float32x4::cast(this)->Float32x4Verify();
65 Float64x2::cast(this)->Float64x2Verify();
68 Int32x4::cast(this)->Int32x4Verify();
70 case FIXED_ARRAY_TYPE:
71 FixedArray::cast(this)->FixedArrayVerify();
73 case FIXED_DOUBLE_ARRAY_TYPE:
74 FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
76 case CONSTANT_POOL_ARRAY_TYPE:
77 ConstantPoolArray::cast(this)->ConstantPoolArrayVerify();
80 ByteArray::cast(this)->ByteArrayVerify();
83 FreeSpace::cast(this)->FreeSpaceVerify();
86 #define VERIFY_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
87 case EXTERNAL_##TYPE##_ARRAY_TYPE: \
88 External##Type##Array::cast(this)->External##Type##ArrayVerify(); \
90 case FIXED_##TYPE##_ARRAY_TYPE: \
91 Fixed##Type##Array::cast(this)->FixedTypedArrayVerify(); \
94 TYPED_ARRAYS(VERIFY_TYPED_ARRAY)
95 #undef VERIFY_TYPED_ARRAY
98 Code::cast(this)->CodeVerify();
101 Oddball::cast(this)->OddballVerify();
104 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
105 JSObject::cast(this)->JSObjectVerify();
107 case JS_GENERATOR_OBJECT_TYPE:
108 JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
111 JSModule::cast(this)->JSModuleVerify();
114 JSValue::cast(this)->JSValueVerify();
117 JSDate::cast(this)->JSDateVerify();
119 case JS_FUNCTION_TYPE:
120 JSFunction::cast(this)->JSFunctionVerify();
122 case JS_GLOBAL_PROXY_TYPE:
123 JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
125 case JS_GLOBAL_OBJECT_TYPE:
126 JSGlobalObject::cast(this)->JSGlobalObjectVerify();
128 case JS_BUILTINS_OBJECT_TYPE:
129 JSBuiltinsObject::cast(this)->JSBuiltinsObjectVerify();
132 Cell::cast(this)->CellVerify();
134 case PROPERTY_CELL_TYPE:
135 PropertyCell::cast(this)->PropertyCellVerify();
138 JSArray::cast(this)->JSArrayVerify();
141 JSSet::cast(this)->JSSetVerify();
144 JSMap::cast(this)->JSMapVerify();
146 case JS_SET_ITERATOR_TYPE:
147 JSSetIterator::cast(this)->JSSetIteratorVerify();
149 case JS_MAP_ITERATOR_TYPE:
150 JSMapIterator::cast(this)->JSMapIteratorVerify();
152 case JS_WEAK_MAP_TYPE:
153 JSWeakMap::cast(this)->JSWeakMapVerify();
155 case JS_WEAK_SET_TYPE:
156 JSWeakSet::cast(this)->JSWeakSetVerify();
159 JSRegExp::cast(this)->JSRegExpVerify();
164 JSProxy::cast(this)->JSProxyVerify();
166 case JS_FUNCTION_PROXY_TYPE:
167 JSFunctionProxy::cast(this)->JSFunctionProxyVerify();
170 Foreign::cast(this)->ForeignVerify();
172 case SHARED_FUNCTION_INFO_TYPE:
173 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
175 case JS_MESSAGE_OBJECT_TYPE:
176 JSMessageObject::cast(this)->JSMessageObjectVerify();
178 case JS_ARRAY_BUFFER_TYPE:
179 JSArrayBuffer::cast(this)->JSArrayBufferVerify();
181 case JS_TYPED_ARRAY_TYPE:
182 JSTypedArray::cast(this)->JSTypedArrayVerify();
184 case JS_DATA_VIEW_TYPE:
185 JSDataView::cast(this)->JSDataViewVerify();
188 #define MAKE_STRUCT_CASE(NAME, Name, name) \
190 Name::cast(this)->Name##Verify(); \
192 STRUCT_LIST(MAKE_STRUCT_CASE)
193 #undef MAKE_STRUCT_CASE
202 void HeapObject::VerifyHeapPointer(Object* p) {
203 CHECK(p->IsHeapObject());
204 HeapObject* ho = HeapObject::cast(p);
205 CHECK(ho->GetHeap()->Contains(ho));
209 void Symbol::SymbolVerify() {
211 CHECK(HasHashCode());
213 CHECK(name()->IsUndefined() || name()->IsString());
214 CHECK(flags()->IsSmi());
218 void HeapNumber::HeapNumberVerify() {
219 CHECK(IsHeapNumber() || IsMutableHeapNumber());
223 void Float32x4::Float32x4Verify() {
224 CHECK(IsFloat32x4());
228 void Float64x2::Float64x2Verify() {
229 CHECK(IsFloat64x2());
233 void Int32x4::Int32x4Verify() {
238 void ByteArray::ByteArrayVerify() {
239 CHECK(IsByteArray());
243 void FreeSpace::FreeSpaceVerify() {
244 CHECK(IsFreeSpace());
248 #define EXTERNAL_ARRAY_VERIFY(Type, type, TYPE, ctype, size) \
249 void External##Type##Array::External##Type##ArrayVerify() { \
250 CHECK(IsExternal##Type##Array()); \
253 TYPED_ARRAYS(EXTERNAL_ARRAY_VERIFY)
254 #undef EXTERNAL_ARRAY_VERIFY
257 template <class Traits>
258 void FixedTypedArray<Traits>::FixedTypedArrayVerify() {
259 CHECK(IsHeapObject() &&
260 HeapObject::cast(this)->map()->instance_type() ==
261 Traits::kInstanceType);
265 bool JSObject::ElementsAreSafeToExamine() {
266 // If a GC was caused while constructing this object, the elements
267 // pointer may point to a one pointer filler map.
268 return reinterpret_cast<Map*>(elements()) !=
269 GetHeap()->one_pointer_filler_map();
273 void JSObject::JSObjectVerify() {
274 VerifyHeapPointer(properties());
275 VerifyHeapPointer(elements());
277 if (GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS) {
278 CHECK(this->elements()->IsFixedArray());
279 CHECK_GE(this->elements()->length(), 2);
282 if (HasFastProperties()) {
283 CHECK_EQ(map()->unused_property_fields(),
284 (map()->inobject_properties() + properties()->length() -
285 map()->NextFreePropertyIndex()));
286 DescriptorArray* descriptors = map()->instance_descriptors();
287 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
288 if (descriptors->GetDetails(i).type() == FIELD) {
289 Representation r = descriptors->GetDetails(i).representation();
290 FieldIndex index = FieldIndex::ForDescriptor(map(), i);
291 Object* value = RawFastPropertyAt(index);
292 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
293 if (value->IsUninitialized()) continue;
294 if (r.IsSmi()) DCHECK(value->IsSmi());
295 if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
296 HeapType* field_type = descriptors->GetFieldType(i);
298 CHECK(field_type->Is(HeapType::None()));
299 } else if (!HeapType::Any()->Is(field_type)) {
300 CHECK(!field_type->NowStable() || field_type->NowContains(value));
306 // If a GC was caused while constructing this object, the elements
307 // pointer may point to a one pointer filler map.
308 if (ElementsAreSafeToExamine()) {
309 CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
310 (elements() == GetHeap()->empty_fixed_array())),
311 (elements()->map() == GetHeap()->fixed_array_map() ||
312 elements()->map() == GetHeap()->fixed_cow_array_map()));
313 CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
318 void Map::MapVerify() {
319 Heap* heap = GetHeap();
320 CHECK(!heap->InNewSpace(this));
321 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
322 CHECK(instance_size() == kVariableSizeSentinel ||
323 (kPointerSize <= instance_size() &&
324 instance_size() < heap->Capacity()));
325 VerifyHeapPointer(prototype());
326 VerifyHeapPointer(instance_descriptors());
327 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
328 if (HasTransitionArray()) {
329 SLOW_DCHECK(transitions()->IsSortedNoDuplicates());
330 SLOW_DCHECK(transitions()->IsConsistentWithBackPointers(this));
335 void Map::DictionaryMapVerify() {
337 CHECK(is_dictionary_map());
338 CHECK(instance_descriptors()->IsEmpty());
339 CHECK_EQ(0, pre_allocated_property_fields());
340 CHECK_EQ(0, unused_property_fields());
341 CHECK_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
346 void Map::VerifyOmittedMapChecks() {
347 if (!FLAG_omit_map_checks_for_leaf_maps) return;
350 HasTransitionArray() ||
351 is_dictionary_map()) {
352 CHECK_EQ(0, dependent_code()->number_of_entries(
353 DependentCode::kPrototypeCheckGroup));
358 void CodeCache::CodeCacheVerify() {
359 VerifyHeapPointer(default_cache());
360 VerifyHeapPointer(normal_type_cache());
361 CHECK(default_cache()->IsFixedArray());
362 CHECK(normal_type_cache()->IsUndefined()
363 || normal_type_cache()->IsCodeCacheHashTable());
367 void PolymorphicCodeCache::PolymorphicCodeCacheVerify() {
368 VerifyHeapPointer(cache());
369 CHECK(cache()->IsUndefined() || cache()->IsPolymorphicCodeCacheHashTable());
373 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
374 VerifyObjectField(kStorage1Offset);
375 VerifyObjectField(kStorage2Offset);
376 VerifyObjectField(kStorage3Offset);
380 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
381 VerifySmiField(kAliasedContextSlot);
385 void FixedArray::FixedArrayVerify() {
386 for (int i = 0; i < length(); i++) {
393 void FixedDoubleArray::FixedDoubleArrayVerify() {
394 for (int i = 0; i < length(); i++) {
395 if (!is_the_hole(i)) {
396 double value = get_scalar(i);
397 CHECK(!std::isnan(value) ||
398 (bit_cast<uint64_t>(value) ==
399 bit_cast<uint64_t>(canonical_not_the_hole_nan_as_double())) ||
400 ((bit_cast<uint64_t>(value) & Double::kSignMask) != 0));
406 void ConstantPoolArray::ConstantPoolArrayVerify() {
407 CHECK(IsConstantPoolArray());
408 ConstantPoolArray::Iterator code_iter(this, ConstantPoolArray::CODE_PTR);
409 while (!code_iter.is_finished()) {
410 Address code_entry = get_code_ptr_entry(code_iter.next_index());
411 VerifyPointer(Code::GetCodeFromTargetAddress(code_entry));
413 ConstantPoolArray::Iterator heap_iter(this, ConstantPoolArray::HEAP_PTR);
414 while (!heap_iter.is_finished()) {
415 VerifyObjectField(OffsetOfElementAt(heap_iter.next_index()));
420 void JSGeneratorObject::JSGeneratorObjectVerify() {
421 // In an expression like "new g()", there can be a point where a generator
422 // object is allocated but its fields are all undefined, as it hasn't yet been
423 // initialized by the generator. Hence these weak checks.
424 VerifyObjectField(kFunctionOffset);
425 VerifyObjectField(kContextOffset);
426 VerifyObjectField(kReceiverOffset);
427 VerifyObjectField(kOperandStackOffset);
428 VerifyObjectField(kContinuationOffset);
429 VerifyObjectField(kStackHandlerIndexOffset);
433 void JSModule::JSModuleVerify() {
434 VerifyObjectField(kContextOffset);
435 VerifyObjectField(kScopeInfoOffset);
436 CHECK(context()->IsUndefined() ||
437 Context::cast(context())->IsModuleContext());
441 void JSValue::JSValueVerify() {
443 if (v->IsHeapObject()) {
444 VerifyHeapPointer(v);
449 void JSDate::JSDateVerify() {
450 if (value()->IsHeapObject()) {
451 VerifyHeapPointer(value());
453 CHECK(value()->IsUndefined() || value()->IsSmi() || value()->IsHeapNumber());
454 CHECK(year()->IsUndefined() || year()->IsSmi() || year()->IsNaN());
455 CHECK(month()->IsUndefined() || month()->IsSmi() || month()->IsNaN());
456 CHECK(day()->IsUndefined() || day()->IsSmi() || day()->IsNaN());
457 CHECK(weekday()->IsUndefined() || weekday()->IsSmi() || weekday()->IsNaN());
458 CHECK(hour()->IsUndefined() || hour()->IsSmi() || hour()->IsNaN());
459 CHECK(min()->IsUndefined() || min()->IsSmi() || min()->IsNaN());
460 CHECK(sec()->IsUndefined() || sec()->IsSmi() || sec()->IsNaN());
461 CHECK(cache_stamp()->IsUndefined() ||
462 cache_stamp()->IsSmi() ||
463 cache_stamp()->IsNaN());
465 if (month()->IsSmi()) {
466 int month = Smi::cast(this->month())->value();
467 CHECK(0 <= month && month <= 11);
469 if (day()->IsSmi()) {
470 int day = Smi::cast(this->day())->value();
471 CHECK(1 <= day && day <= 31);
473 if (hour()->IsSmi()) {
474 int hour = Smi::cast(this->hour())->value();
475 CHECK(0 <= hour && hour <= 23);
477 if (min()->IsSmi()) {
478 int min = Smi::cast(this->min())->value();
479 CHECK(0 <= min && min <= 59);
481 if (sec()->IsSmi()) {
482 int sec = Smi::cast(this->sec())->value();
483 CHECK(0 <= sec && sec <= 59);
485 if (weekday()->IsSmi()) {
486 int weekday = Smi::cast(this->weekday())->value();
487 CHECK(0 <= weekday && weekday <= 6);
489 if (cache_stamp()->IsSmi()) {
490 CHECK(Smi::cast(cache_stamp())->value() <=
491 Smi::cast(GetIsolate()->date_cache()->stamp())->value());
496 void JSMessageObject::JSMessageObjectVerify() {
497 CHECK(IsJSMessageObject());
498 CHECK(type()->IsString());
499 CHECK(arguments()->IsJSArray());
500 VerifyObjectField(kStartPositionOffset);
501 VerifyObjectField(kEndPositionOffset);
502 VerifyObjectField(kArgumentsOffset);
503 VerifyObjectField(kScriptOffset);
504 VerifyObjectField(kStackFramesOffset);
508 void String::StringVerify() {
510 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
511 if (IsInternalizedString()) {
512 CHECK(!GetHeap()->InNewSpace(this));
514 if (IsConsString()) {
515 ConsString::cast(this)->ConsStringVerify();
516 } else if (IsSlicedString()) {
517 SlicedString::cast(this)->SlicedStringVerify();
522 void ConsString::ConsStringVerify() {
523 CHECK(this->first()->IsString());
524 CHECK(this->second() == GetHeap()->empty_string() ||
525 this->second()->IsString());
526 CHECK(this->length() >= ConsString::kMinLength);
527 CHECK(this->length() == this->first()->length() + this->second()->length());
528 if (this->IsFlat()) {
529 // A flat cons can only be created by String::SlowTryFlatten.
530 // Afterwards, the first part may be externalized.
531 CHECK(this->first()->IsSeqString() || this->first()->IsExternalString());
536 void SlicedString::SlicedStringVerify() {
537 CHECK(!this->parent()->IsConsString());
538 CHECK(!this->parent()->IsSlicedString());
539 CHECK(this->length() >= SlicedString::kMinLength);
543 void JSFunction::JSFunctionVerify() {
544 CHECK(IsJSFunction());
545 VerifyObjectField(kPrototypeOrInitialMapOffset);
546 VerifyObjectField(kNextFunctionLinkOffset);
547 CHECK(code()->IsCode());
548 CHECK(next_function_link() == NULL ||
549 next_function_link()->IsUndefined() ||
550 next_function_link()->IsJSFunction());
554 void SharedFunctionInfo::SharedFunctionInfoVerify() {
555 CHECK(IsSharedFunctionInfo());
556 VerifyObjectField(kNameOffset);
557 VerifyObjectField(kCodeOffset);
558 VerifyObjectField(kOptimizedCodeMapOffset);
559 VerifyObjectField(kFeedbackVectorOffset);
560 VerifyObjectField(kScopeInfoOffset);
561 VerifyObjectField(kInstanceClassNameOffset);
562 VerifyObjectField(kFunctionDataOffset);
563 VerifyObjectField(kScriptOffset);
564 VerifyObjectField(kDebugInfoOffset);
568 void JSGlobalProxy::JSGlobalProxyVerify() {
569 CHECK(IsJSGlobalProxy());
571 VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
572 // Make sure that this object has no properties, elements.
573 CHECK_EQ(0, properties()->length());
574 CHECK(HasFastSmiElements());
575 CHECK_EQ(0, FixedArray::cast(elements())->length());
579 void JSGlobalObject::JSGlobalObjectVerify() {
580 CHECK(IsJSGlobalObject());
582 for (int i = GlobalObject::kBuiltinsOffset;
583 i < JSGlobalObject::kSize;
585 VerifyObjectField(i);
590 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
591 CHECK(IsJSBuiltinsObject());
593 for (int i = GlobalObject::kBuiltinsOffset;
594 i < JSBuiltinsObject::kSize;
596 VerifyObjectField(i);
601 void Oddball::OddballVerify() {
603 Heap* heap = GetHeap();
604 VerifyHeapPointer(to_string());
605 Object* number = to_number();
606 if (number->IsHeapObject()) {
607 CHECK(number == heap->nan_value());
609 CHECK(number->IsSmi());
610 int value = Smi::cast(number)->value();
611 // Hidden oddballs have negative smis.
612 const int kLeastHiddenOddballNumber = -5;
614 CHECK(value >= kLeastHiddenOddballNumber);
616 if (map() == heap->undefined_map()) {
617 CHECK(this == heap->undefined_value());
618 } else if (map() == heap->the_hole_map()) {
619 CHECK(this == heap->the_hole_value());
620 } else if (map() == heap->null_map()) {
621 CHECK(this == heap->null_value());
622 } else if (map() == heap->boolean_map()) {
623 CHECK(this == heap->true_value() ||
624 this == heap->false_value());
625 } else if (map() == heap->uninitialized_map()) {
626 CHECK(this == heap->uninitialized_value());
627 } else if (map() == heap->no_interceptor_result_sentinel_map()) {
628 CHECK(this == heap->no_interceptor_result_sentinel());
629 } else if (map() == heap->arguments_marker_map()) {
630 CHECK(this == heap->arguments_marker());
631 } else if (map() == heap->termination_exception_map()) {
632 CHECK(this == heap->termination_exception());
633 } else if (map() == heap->exception_map()) {
634 CHECK(this == heap->exception());
641 void Cell::CellVerify() {
643 VerifyObjectField(kValueOffset);
647 void PropertyCell::PropertyCellVerify() {
648 CHECK(IsPropertyCell());
649 VerifyObjectField(kValueOffset);
650 VerifyObjectField(kTypeOffset);
654 void Code::CodeVerify() {
655 CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
657 relocation_info()->ObjectVerify();
658 Address last_gc_pc = NULL;
659 Isolate* isolate = GetIsolate();
660 for (RelocIterator it(this); !it.done(); it.next()) {
661 it.rinfo()->Verify(isolate);
662 // Ensure that GC will not iterate twice over the same pointer.
663 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
664 CHECK(it.rinfo()->pc() != last_gc_pc);
665 last_gc_pc = it.rinfo()->pc();
668 CHECK(raw_type_feedback_info() == Smi::FromInt(0) ||
669 raw_type_feedback_info()->IsSmi() == IsCodeStubOrIC());
673 void Code::VerifyEmbeddedObjectsDependency() {
674 if (!CanContainWeakObjects()) return;
675 DisallowHeapAllocation no_gc;
676 Isolate* isolate = GetIsolate();
677 HandleScope scope(isolate);
678 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
679 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
680 Object* obj = it.rinfo()->target_object();
681 if (IsWeakObject(obj)) {
683 Map* map = Map::cast(obj);
684 DependentCode::DependencyGroup group = is_optimized_code() ?
685 DependentCode::kWeakCodeGroup : DependentCode::kWeakICGroup;
686 CHECK(map->dependent_code()->Contains(group, this));
687 } else if (obj->IsJSObject()) {
688 Object* raw_table = GetIsolate()->heap()->weak_object_to_code_table();
689 WeakHashTable* table = WeakHashTable::cast(raw_table);
690 Handle<Object> key_obj(obj, isolate);
691 CHECK(DependentCode::cast(table->Lookup(key_obj))->Contains(
692 DependentCode::kWeakCodeGroup, this));
699 void JSArray::JSArrayVerify() {
701 CHECK(length()->IsNumber() || length()->IsUndefined());
702 // If a GC was caused while constructing this array, the elements
703 // pointer may point to a one pointer filler map.
704 if (ElementsAreSafeToExamine()) {
705 CHECK(elements()->IsUndefined() ||
706 elements()->IsFixedArray() ||
707 elements()->IsFixedDoubleArray());
712 void JSSet::JSSetVerify() {
715 VerifyHeapPointer(table());
716 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
717 // TODO(arv): Verify OrderedHashTable too.
721 void JSMap::JSMapVerify() {
724 VerifyHeapPointer(table());
725 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
726 // TODO(arv): Verify OrderedHashTable too.
730 void JSSetIterator::JSSetIteratorVerify() {
731 CHECK(IsJSSetIterator());
733 VerifyHeapPointer(table());
734 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
735 CHECK(index()->IsSmi() || index()->IsUndefined());
736 CHECK(kind()->IsSmi() || kind()->IsUndefined());
740 void JSMapIterator::JSMapIteratorVerify() {
741 CHECK(IsJSMapIterator());
743 VerifyHeapPointer(table());
744 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined());
745 CHECK(index()->IsSmi() || index()->IsUndefined());
746 CHECK(kind()->IsSmi() || kind()->IsUndefined());
750 void JSWeakMap::JSWeakMapVerify() {
751 CHECK(IsJSWeakMap());
753 VerifyHeapPointer(table());
754 CHECK(table()->IsHashTable() || table()->IsUndefined());
758 void JSWeakSet::JSWeakSetVerify() {
759 CHECK(IsJSWeakSet());
761 VerifyHeapPointer(table());
762 CHECK(table()->IsHashTable() || table()->IsUndefined());
766 void JSRegExp::JSRegExpVerify() {
768 CHECK(data()->IsUndefined() || data()->IsFixedArray());
770 case JSRegExp::ATOM: {
771 FixedArray* arr = FixedArray::cast(data());
772 CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
775 case JSRegExp::IRREGEXP: {
776 bool is_native = RegExpImpl::UsesNativeRegExp();
778 FixedArray* arr = FixedArray::cast(data());
779 Object* one_byte_data = arr->get(JSRegExp::kIrregexpLatin1CodeIndex);
780 // Smi : Not compiled yet (-1) or code prepared for flushing.
781 // JSObject: Compilation error.
782 // Code/ByteArray: Compiled code.
784 one_byte_data->IsSmi() ||
785 (is_native ? one_byte_data->IsCode() : one_byte_data->IsByteArray()));
786 Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
787 CHECK(uc16_data->IsSmi() ||
788 (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
790 Object* one_byte_saved =
791 arr->get(JSRegExp::kIrregexpLatin1CodeSavedIndex);
792 CHECK(one_byte_saved->IsSmi() || one_byte_saved->IsString() ||
793 one_byte_saved->IsCode());
794 Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
795 CHECK(uc16_saved->IsSmi() || uc16_saved->IsString() ||
796 uc16_saved->IsCode());
798 CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
799 CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
803 CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
804 CHECK(data()->IsUndefined());
810 void JSProxy::JSProxyVerify() {
812 VerifyPointer(handler());
813 CHECK(hash()->IsSmi() || hash()->IsUndefined());
817 void JSFunctionProxy::JSFunctionProxyVerify() {
818 CHECK(IsJSFunctionProxy());
820 VerifyPointer(call_trap());
821 VerifyPointer(construct_trap());
825 void JSArrayBuffer::JSArrayBufferVerify() {
826 CHECK(IsJSArrayBuffer());
828 VerifyPointer(byte_length());
829 CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber()
830 || byte_length()->IsUndefined());
834 void JSArrayBufferView::JSArrayBufferViewVerify() {
835 CHECK(IsJSArrayBufferView());
837 VerifyPointer(buffer());
838 CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined()
839 || buffer() == Smi::FromInt(0));
841 VerifyPointer(byte_offset());
842 CHECK(byte_offset()->IsSmi() || byte_offset()->IsHeapNumber()
843 || byte_offset()->IsUndefined());
845 VerifyPointer(byte_length());
846 CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber()
847 || byte_length()->IsUndefined());
851 void JSTypedArray::JSTypedArrayVerify() {
852 CHECK(IsJSTypedArray());
853 JSArrayBufferViewVerify();
854 VerifyPointer(length());
855 CHECK(length()->IsSmi() || length()->IsHeapNumber()
856 || length()->IsUndefined());
858 VerifyPointer(elements());
862 void JSDataView::JSDataViewVerify() {
863 CHECK(IsJSDataView());
864 JSArrayBufferViewVerify();
868 void Foreign::ForeignVerify() {
873 void Box::BoxVerify() {
875 value()->ObjectVerify();
879 void AccessorInfo::AccessorInfoVerify() {
880 VerifyPointer(name());
881 VerifyPointer(flag());
882 VerifyPointer(expected_receiver_type());
886 void ExecutableAccessorInfo::ExecutableAccessorInfoVerify() {
887 CHECK(IsExecutableAccessorInfo());
888 AccessorInfoVerify();
889 VerifyPointer(getter());
890 VerifyPointer(setter());
891 VerifyPointer(data());
895 void DeclaredAccessorDescriptor::DeclaredAccessorDescriptorVerify() {
896 CHECK(IsDeclaredAccessorDescriptor());
897 VerifyPointer(serialized_data());
901 void DeclaredAccessorInfo::DeclaredAccessorInfoVerify() {
902 CHECK(IsDeclaredAccessorInfo());
903 AccessorInfoVerify();
904 VerifyPointer(descriptor());
908 void AccessorPair::AccessorPairVerify() {
909 CHECK(IsAccessorPair());
910 VerifyPointer(getter());
911 VerifyPointer(setter());
915 void AccessCheckInfo::AccessCheckInfoVerify() {
916 CHECK(IsAccessCheckInfo());
917 VerifyPointer(named_callback());
918 VerifyPointer(indexed_callback());
919 VerifyPointer(data());
923 void InterceptorInfo::InterceptorInfoVerify() {
924 CHECK(IsInterceptorInfo());
925 VerifyPointer(getter());
926 VerifyPointer(setter());
927 VerifyPointer(query());
928 VerifyPointer(deleter());
929 VerifyPointer(enumerator());
930 VerifyPointer(data());
934 void CallHandlerInfo::CallHandlerInfoVerify() {
935 CHECK(IsCallHandlerInfo());
936 VerifyPointer(callback());
937 VerifyPointer(data());
941 void TemplateInfo::TemplateInfoVerify() {
942 VerifyPointer(tag());
943 VerifyPointer(property_list());
944 VerifyPointer(property_accessors());
948 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
949 CHECK(IsFunctionTemplateInfo());
950 TemplateInfoVerify();
951 VerifyPointer(serial_number());
952 VerifyPointer(call_code());
953 VerifyPointer(prototype_template());
954 VerifyPointer(parent_template());
955 VerifyPointer(named_property_handler());
956 VerifyPointer(indexed_property_handler());
957 VerifyPointer(instance_template());
958 VerifyPointer(signature());
959 VerifyPointer(access_check_info());
963 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
964 CHECK(IsObjectTemplateInfo());
965 TemplateInfoVerify();
966 VerifyPointer(constructor());
967 VerifyPointer(internal_field_count());
971 void SignatureInfo::SignatureInfoVerify() {
972 CHECK(IsSignatureInfo());
973 VerifyPointer(receiver());
974 VerifyPointer(args());
978 void TypeSwitchInfo::TypeSwitchInfoVerify() {
979 CHECK(IsTypeSwitchInfo());
980 VerifyPointer(types());
984 void AllocationSite::AllocationSiteVerify() {
985 CHECK(IsAllocationSite());
989 void AllocationMemento::AllocationMementoVerify() {
990 CHECK(IsAllocationMemento());
991 VerifyHeapPointer(allocation_site());
992 CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
996 void Script::ScriptVerify() {
998 VerifyPointer(source());
999 VerifyPointer(name());
1000 line_offset()->SmiVerify();
1001 column_offset()->SmiVerify();
1002 VerifyPointer(wrapper());
1003 type()->SmiVerify();
1004 VerifyPointer(line_ends());
1005 VerifyPointer(id());
1009 void JSFunctionResultCache::JSFunctionResultCacheVerify() {
1010 JSFunction::cast(get(kFactoryIndex))->ObjectVerify();
1012 int size = Smi::cast(get(kCacheSizeIndex))->value();
1013 CHECK(kEntriesIndex <= size);
1014 CHECK(size <= length());
1015 CHECK_EQ(0, size % kEntrySize);
1017 int finger = Smi::cast(get(kFingerIndex))->value();
1018 CHECK(kEntriesIndex <= finger);
1019 CHECK((finger < size) || (finger == kEntriesIndex && finger == size));
1020 CHECK_EQ(0, finger % kEntrySize);
1022 if (FLAG_enable_slow_asserts) {
1023 for (int i = kEntriesIndex; i < size; i++) {
1024 CHECK(!get(i)->IsTheHole());
1025 get(i)->ObjectVerify();
1027 for (int i = size; i < length(); i++) {
1028 CHECK(get(i)->IsTheHole());
1029 get(i)->ObjectVerify();
1035 void NormalizedMapCache::NormalizedMapCacheVerify() {
1036 FixedArray::cast(this)->FixedArrayVerify();
1037 if (FLAG_enable_slow_asserts) {
1038 for (int i = 0; i < length(); i++) {
1039 Object* e = FixedArray::get(i);
1041 Map::cast(e)->DictionaryMapVerify();
1043 CHECK(e->IsUndefined());
1050 void DebugInfo::DebugInfoVerify() {
1051 CHECK(IsDebugInfo());
1052 VerifyPointer(shared());
1053 VerifyPointer(original_code());
1054 VerifyPointer(code());
1055 VerifyPointer(break_points());
1059 void BreakPointInfo::BreakPointInfoVerify() {
1060 CHECK(IsBreakPointInfo());
1061 code_position()->SmiVerify();
1062 source_position()->SmiVerify();
1063 statement_position()->SmiVerify();
1064 VerifyPointer(break_point_objects());
1066 #endif // VERIFY_HEAP
1070 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
1071 info->number_of_objects_++;
1073 if (HasFastProperties()) {
1074 info->number_of_objects_with_fast_properties_++;
1075 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
1076 info->number_of_fast_unused_fields_ += map()->unused_property_fields();
1078 NameDictionary* dict = property_dictionary();
1079 info->number_of_slow_used_properties_ += dict->NumberOfElements();
1080 info->number_of_slow_unused_properties_ +=
1081 dict->Capacity() - dict->NumberOfElements();
1083 // Indexed properties
1084 switch (GetElementsKind()) {
1085 case FAST_HOLEY_SMI_ELEMENTS:
1086 case FAST_SMI_ELEMENTS:
1087 case FAST_HOLEY_DOUBLE_ELEMENTS:
1088 case FAST_DOUBLE_ELEMENTS:
1089 case FAST_HOLEY_ELEMENTS:
1090 case FAST_ELEMENTS: {
1091 info->number_of_objects_with_fast_elements_++;
1093 FixedArray* e = FixedArray::cast(elements());
1094 int len = e->length();
1095 Heap* heap = GetHeap();
1096 for (int i = 0; i < len; i++) {
1097 if (e->get(i) == heap->the_hole_value()) holes++;
1099 info->number_of_fast_used_elements_ += len - holes;
1100 info->number_of_fast_unused_elements_ += holes;
1104 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1105 case EXTERNAL_##TYPE##_ELEMENTS: \
1106 case TYPE##_ELEMENTS:
1108 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1109 #undef TYPED_ARRAY_CASE
1110 { info->number_of_objects_with_fast_elements_++;
1111 FixedArrayBase* e = FixedArrayBase::cast(elements());
1112 info->number_of_fast_used_elements_ += e->length();
1115 case DICTIONARY_ELEMENTS: {
1116 SeededNumberDictionary* dict = element_dictionary();
1117 info->number_of_slow_used_elements_ += dict->NumberOfElements();
1118 info->number_of_slow_unused_elements_ +=
1119 dict->Capacity() - dict->NumberOfElements();
1122 case SLOPPY_ARGUMENTS_ELEMENTS:
1128 void JSObject::SpillInformation::Clear() {
1129 number_of_objects_ = 0;
1130 number_of_objects_with_fast_properties_ = 0;
1131 number_of_objects_with_fast_elements_ = 0;
1132 number_of_fast_used_fields_ = 0;
1133 number_of_fast_unused_fields_ = 0;
1134 number_of_slow_used_properties_ = 0;
1135 number_of_slow_unused_properties_ = 0;
1136 number_of_fast_used_elements_ = 0;
1137 number_of_fast_unused_elements_ = 0;
1138 number_of_slow_used_elements_ = 0;
1139 number_of_slow_unused_elements_ = 0;
1143 void JSObject::SpillInformation::Print() {
1144 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
1146 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
1147 number_of_objects_with_fast_properties_,
1148 number_of_fast_used_fields_, number_of_fast_unused_fields_);
1150 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
1151 number_of_objects_ - number_of_objects_with_fast_properties_,
1152 number_of_slow_used_properties_, number_of_slow_unused_properties_);
1154 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
1155 number_of_objects_with_fast_elements_,
1156 number_of_fast_used_elements_, number_of_fast_unused_elements_);
1158 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
1159 number_of_objects_ - number_of_objects_with_fast_elements_,
1160 number_of_slow_used_elements_, number_of_slow_unused_elements_);
1166 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
1167 if (valid_entries == -1) valid_entries = number_of_descriptors();
1168 Name* current_key = NULL;
1169 uint32_t current = 0;
1170 for (int i = 0; i < number_of_descriptors(); i++) {
1171 Name* key = GetSortedKey(i);
1172 if (key == current_key) {
1173 OFStream os(stdout);
1174 PrintDescriptors(os);
1178 uint32_t hash = GetSortedKey(i)->Hash();
1179 if (hash < current) {
1180 OFStream os(stdout);
1181 PrintDescriptors(os);
1190 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
1191 DCHECK(valid_entries == -1);
1192 Name* current_key = NULL;
1193 uint32_t current = 0;
1194 for (int i = 0; i < number_of_transitions(); i++) {
1195 Name* key = GetSortedKey(i);
1196 if (key == current_key) {
1197 OFStream os(stdout);
1198 PrintTransitions(os);
1202 uint32_t hash = GetSortedKey(i)->Hash();
1203 if (hash < current) {
1204 OFStream os(stdout);
1205 PrintTransitions(os);
1214 static bool CheckOneBackPointer(Map* current_map, Object* target) {
1215 return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
1219 bool TransitionArray::IsConsistentWithBackPointers(Map* current_map) {
1220 for (int i = 0; i < number_of_transitions(); ++i) {
1221 if (!CheckOneBackPointer(current_map, GetTarget(i))) return false;
1229 } } // namespace v8::internal