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.
4 
5 #include "src/objects.h"
6 
7 #include "src/bootstrapper.h"
8 #include "src/disasm.h"
9 #include "src/disassembler.h"
10 #include "src/field-type.h"
11 #include "src/macro-assembler.h"
12 #include "src/ostreams.h"
13 #include "src/regexp/jsregexp.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 #ifdef VERIFY_HEAP
19 
ObjectVerify()20 void Object::ObjectVerify() {
21   if (IsSmi()) {
22     Smi::cast(this)->SmiVerify();
23   } else {
24     HeapObject::cast(this)->HeapObjectVerify();
25   }
26   CHECK(!IsConstructor() || IsCallable());
27 }
28 
29 
VerifyPointer(Object * p)30 void Object::VerifyPointer(Object* p) {
31   if (p->IsHeapObject()) {
32     HeapObject::VerifyHeapPointer(p);
33   } else {
34     CHECK(p->IsSmi());
35   }
36 }
37 
38 
SmiVerify()39 void Smi::SmiVerify() {
40   CHECK(IsSmi());
41   CHECK(!IsCallable());
42   CHECK(!IsConstructor());
43 }
44 
45 
HeapObjectVerify()46 void HeapObject::HeapObjectVerify() {
47   InstanceType instance_type = map()->instance_type();
48 
49   if (instance_type < FIRST_NONSTRING_TYPE) {
50     String::cast(this)->StringVerify();
51     return;
52   }
53 
54   switch (instance_type) {
55     case SYMBOL_TYPE:
56       Symbol::cast(this)->SymbolVerify();
57       break;
58     case MAP_TYPE:
59       Map::cast(this)->MapVerify();
60       break;
61     case HEAP_NUMBER_TYPE:
62     case MUTABLE_HEAP_NUMBER_TYPE:
63       HeapNumber::cast(this)->HeapNumberVerify();
64       break;
65     case SIMD128_VALUE_TYPE:
66       Simd128Value::cast(this)->Simd128ValueVerify();
67       break;
68     case FIXED_ARRAY_TYPE:
69       FixedArray::cast(this)->FixedArrayVerify();
70       break;
71     case FIXED_DOUBLE_ARRAY_TYPE:
72       FixedDoubleArray::cast(this)->FixedDoubleArrayVerify();
73       break;
74     case BYTE_ARRAY_TYPE:
75       ByteArray::cast(this)->ByteArrayVerify();
76       break;
77     case BYTECODE_ARRAY_TYPE:
78       BytecodeArray::cast(this)->BytecodeArrayVerify();
79       break;
80     case TRANSITION_ARRAY_TYPE:
81       TransitionArray::cast(this)->TransitionArrayVerify();
82       break;
83     case FREE_SPACE_TYPE:
84       FreeSpace::cast(this)->FreeSpaceVerify();
85       break;
86 
87 #define VERIFY_TYPED_ARRAY(Type, type, TYPE, ctype, size)                      \
88     case FIXED_##TYPE##_ARRAY_TYPE:                                            \
89       Fixed##Type##Array::cast(this)->FixedTypedArrayVerify();                 \
90       break;
91 
92     TYPED_ARRAYS(VERIFY_TYPED_ARRAY)
93 #undef VERIFY_TYPED_ARRAY
94 
95     case CODE_TYPE:
96       Code::cast(this)->CodeVerify();
97       break;
98     case ODDBALL_TYPE:
99       Oddball::cast(this)->OddballVerify();
100       break;
101     case JS_OBJECT_TYPE:
102     case JS_ERROR_TYPE:
103     case JS_ARGUMENTS_TYPE:
104     case JS_API_OBJECT_TYPE:
105     case JS_SPECIAL_API_OBJECT_TYPE:
106     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
107     case JS_PROMISE_TYPE:
108       JSObject::cast(this)->JSObjectVerify();
109       break;
110     case JS_GENERATOR_OBJECT_TYPE:
111       JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
112       break;
113     case JS_VALUE_TYPE:
114       JSValue::cast(this)->JSValueVerify();
115       break;
116     case JS_DATE_TYPE:
117       JSDate::cast(this)->JSDateVerify();
118       break;
119     case JS_BOUND_FUNCTION_TYPE:
120       JSBoundFunction::cast(this)->JSBoundFunctionVerify();
121       break;
122     case JS_FUNCTION_TYPE:
123       JSFunction::cast(this)->JSFunctionVerify();
124       break;
125     case JS_GLOBAL_PROXY_TYPE:
126       JSGlobalProxy::cast(this)->JSGlobalProxyVerify();
127       break;
128     case JS_GLOBAL_OBJECT_TYPE:
129       JSGlobalObject::cast(this)->JSGlobalObjectVerify();
130       break;
131     case CELL_TYPE:
132       Cell::cast(this)->CellVerify();
133       break;
134     case PROPERTY_CELL_TYPE:
135       PropertyCell::cast(this)->PropertyCellVerify();
136       break;
137     case WEAK_CELL_TYPE:
138       WeakCell::cast(this)->WeakCellVerify();
139       break;
140     case JS_ARRAY_TYPE:
141       JSArray::cast(this)->JSArrayVerify();
142       break;
143     case JS_MODULE_NAMESPACE_TYPE:
144       JSModuleNamespace::cast(this)->JSModuleNamespaceVerify();
145       break;
146     case JS_FIXED_ARRAY_ITERATOR_TYPE:
147       JSFixedArrayIterator::cast(this)->JSFixedArrayIteratorVerify();
148       break;
149     case JS_SET_TYPE:
150       JSSet::cast(this)->JSSetVerify();
151       break;
152     case JS_MAP_TYPE:
153       JSMap::cast(this)->JSMapVerify();
154       break;
155     case JS_SET_ITERATOR_TYPE:
156       JSSetIterator::cast(this)->JSSetIteratorVerify();
157       break;
158     case JS_MAP_ITERATOR_TYPE:
159       JSMapIterator::cast(this)->JSMapIteratorVerify();
160       break;
161     case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
162     case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
163     case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
164     case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
165     case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
166     case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
167     case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
168     case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
169     case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
170     case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
171     case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
172     case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
173     case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
174     case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
175     case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
176     case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
177     case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
178     case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
179     case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
180     case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
181     case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
182     case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
183     case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
184     case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
185     case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
186     case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
187     case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
188     case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
189     case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
190     case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
191     case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
192     case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
193     case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
194     case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
195     case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
196       JSArrayIterator::cast(this)->JSArrayIteratorVerify();
197       break;
198 
199     case JS_STRING_ITERATOR_TYPE:
200       JSStringIterator::cast(this)->JSStringIteratorVerify();
201       break;
202     case JS_WEAK_MAP_TYPE:
203       JSWeakMap::cast(this)->JSWeakMapVerify();
204       break;
205     case JS_WEAK_SET_TYPE:
206       JSWeakSet::cast(this)->JSWeakSetVerify();
207       break;
208     case JS_REGEXP_TYPE:
209       JSRegExp::cast(this)->JSRegExpVerify();
210       break;
211     case FILLER_TYPE:
212       break;
213     case JS_PROXY_TYPE:
214       JSProxy::cast(this)->JSProxyVerify();
215       break;
216     case FOREIGN_TYPE:
217       Foreign::cast(this)->ForeignVerify();
218       break;
219     case SHARED_FUNCTION_INFO_TYPE:
220       SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify();
221       break;
222     case JS_MESSAGE_OBJECT_TYPE:
223       JSMessageObject::cast(this)->JSMessageObjectVerify();
224       break;
225     case JS_ARRAY_BUFFER_TYPE:
226       JSArrayBuffer::cast(this)->JSArrayBufferVerify();
227       break;
228     case JS_TYPED_ARRAY_TYPE:
229       JSTypedArray::cast(this)->JSTypedArrayVerify();
230       break;
231     case JS_DATA_VIEW_TYPE:
232       JSDataView::cast(this)->JSDataViewVerify();
233       break;
234 
235 #define MAKE_STRUCT_CASE(NAME, Name, name) \
236   case NAME##_TYPE:                        \
237     Name::cast(this)->Name##Verify();      \
238     break;
239     STRUCT_LIST(MAKE_STRUCT_CASE)
240 #undef MAKE_STRUCT_CASE
241 
242     default:
243       UNREACHABLE();
244       break;
245   }
246 }
247 
248 
VerifyHeapPointer(Object * p)249 void HeapObject::VerifyHeapPointer(Object* p) {
250   CHECK(p->IsHeapObject());
251   HeapObject* ho = HeapObject::cast(p);
252   CHECK(ho->GetHeap()->Contains(ho));
253 }
254 
255 
SymbolVerify()256 void Symbol::SymbolVerify() {
257   CHECK(IsSymbol());
258   CHECK(HasHashCode());
259   CHECK(Hash() > 0u);
260   CHECK(name()->IsUndefined(GetIsolate()) || name()->IsString());
261 }
262 
263 
HeapNumberVerify()264 void HeapNumber::HeapNumberVerify() {
265   CHECK(IsHeapNumber() || IsMutableHeapNumber());
266 }
267 
268 
Simd128ValueVerify()269 void Simd128Value::Simd128ValueVerify() { CHECK(IsSimd128Value()); }
270 
271 
ByteArrayVerify()272 void ByteArray::ByteArrayVerify() {
273   CHECK(IsByteArray());
274 }
275 
276 
BytecodeArrayVerify()277 void BytecodeArray::BytecodeArrayVerify() {
278   // TODO(oth): Walk bytecodes and immediate values to validate sanity.
279   // - All bytecodes are known and well formed.
280   // - Jumps must go to new instructions starts.
281   // - No Illegal bytecodes.
282   // - No consecutive sequences of prefix Wide / ExtraWide.
283   CHECK(IsBytecodeArray());
284   CHECK(constant_pool()->IsFixedArray());
285   VerifyHeapPointer(constant_pool());
286 }
287 
288 
FreeSpaceVerify()289 void FreeSpace::FreeSpaceVerify() {
290   CHECK(IsFreeSpace());
291 }
292 
293 
294 template <class Traits>
FixedTypedArrayVerify()295 void FixedTypedArray<Traits>::FixedTypedArrayVerify() {
296   CHECK(IsHeapObject() &&
297         HeapObject::cast(this)->map()->instance_type() ==
298             Traits::kInstanceType);
299   if (base_pointer() == this) {
300     CHECK(external_pointer() ==
301           ExternalReference::fixed_typed_array_base_data_offset().address());
302   } else {
303     CHECK(base_pointer() == nullptr);
304   }
305 }
306 
307 
ElementsAreSafeToExamine()308 bool JSObject::ElementsAreSafeToExamine() {
309   // If a GC was caused while constructing this object, the elements
310   // pointer may point to a one pointer filler map.
311   return reinterpret_cast<Map*>(elements()) !=
312       GetHeap()->one_pointer_filler_map();
313 }
314 
315 
JSObjectVerify()316 void JSObject::JSObjectVerify() {
317   VerifyHeapPointer(properties());
318   VerifyHeapPointer(elements());
319 
320   if (HasSloppyArgumentsElements()) {
321     CHECK(this->elements()->IsFixedArray());
322     CHECK_GE(this->elements()->length(), 2);
323   }
324 
325   if (HasFastProperties()) {
326     int actual_unused_property_fields = map()->GetInObjectProperties() +
327                                         properties()->length() -
328                                         map()->NextFreePropertyIndex();
329     if (map()->unused_property_fields() != actual_unused_property_fields) {
330       // This could actually happen in the middle of StoreTransitionStub
331       // when the new extended backing store is already set into the object and
332       // the allocation of the MutableHeapNumber triggers GC (in this case map
333       // is not updated yet).
334       CHECK_EQ(map()->unused_property_fields(),
335                actual_unused_property_fields - JSObject::kFieldsAdded);
336     }
337     DescriptorArray* descriptors = map()->instance_descriptors();
338     Isolate* isolate = GetIsolate();
339     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
340       if (descriptors->GetDetails(i).type() == DATA) {
341         Representation r = descriptors->GetDetails(i).representation();
342         FieldIndex index = FieldIndex::ForDescriptor(map(), i);
343         if (IsUnboxedDoubleField(index)) {
344           DCHECK(r.IsDouble());
345           continue;
346         }
347         Object* value = RawFastPropertyAt(index);
348         if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
349         if (value->IsUninitialized(isolate)) continue;
350         if (r.IsSmi()) DCHECK(value->IsSmi());
351         if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
352         FieldType* field_type = descriptors->GetFieldType(i);
353         bool type_is_none = field_type->IsNone();
354         bool type_is_any = field_type->IsAny();
355         if (r.IsNone()) {
356           CHECK(type_is_none);
357         } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
358           // If allocation folding is off then GC could happen during inner
359           // object literal creation and we will end up having and undefined
360           // value that does not match the field type.
361           CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
362                 (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
363         }
364       }
365     }
366   }
367 
368   // If a GC was caused while constructing this object, the elements
369   // pointer may point to a one pointer filler map.
370   if (ElementsAreSafeToExamine()) {
371     CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
372               (elements() == GetHeap()->empty_fixed_array()) ||
373               HasFastStringWrapperElements()),
374              (elements()->map() == GetHeap()->fixed_array_map() ||
375               elements()->map() == GetHeap()->fixed_cow_array_map()));
376     CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
377   }
378 }
379 
380 
MapVerify()381 void Map::MapVerify() {
382   Heap* heap = GetHeap();
383   CHECK(!heap->InNewSpace(this));
384   CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
385   CHECK(instance_size() == kVariableSizeSentinel ||
386         (kPointerSize <= instance_size() &&
387          static_cast<size_t>(instance_size()) < heap->Capacity()));
388   CHECK(GetBackPointer()->IsUndefined(heap->isolate()) ||
389         !Map::cast(GetBackPointer())->is_stable());
390   VerifyHeapPointer(prototype());
391   VerifyHeapPointer(instance_descriptors());
392   SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
393   SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this));
394   SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this));
395   // TODO(ishell): turn it back to SLOW_DCHECK.
396   CHECK(!FLAG_unbox_double_fields ||
397         layout_descriptor()->IsConsistentWithMap(this));
398 }
399 
400 
DictionaryMapVerify()401 void Map::DictionaryMapVerify() {
402   MapVerify();
403   CHECK(is_dictionary_map());
404   CHECK(instance_descriptors()->IsEmpty());
405   CHECK_EQ(0, unused_property_fields());
406   CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id());
407 }
408 
409 
VerifyOmittedMapChecks()410 void Map::VerifyOmittedMapChecks() {
411   if (!FLAG_omit_map_checks_for_leaf_maps) return;
412   if (!is_stable() ||
413       is_deprecated() ||
414       is_dictionary_map()) {
415     CHECK(dependent_code()->IsEmpty(DependentCode::kPrototypeCheckGroup));
416   }
417 }
418 
419 
TypeFeedbackInfoVerify()420 void TypeFeedbackInfo::TypeFeedbackInfoVerify() {
421   VerifyObjectField(kStorage1Offset);
422   VerifyObjectField(kStorage2Offset);
423   VerifyObjectField(kStorage3Offset);
424 }
425 
426 
AliasedArgumentsEntryVerify()427 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify() {
428   VerifySmiField(kAliasedContextSlot);
429 }
430 
431 
FixedArrayVerify()432 void FixedArray::FixedArrayVerify() {
433   for (int i = 0; i < length(); i++) {
434     Object* e = get(i);
435     VerifyPointer(e);
436   }
437 }
438 
439 
FixedDoubleArrayVerify()440 void FixedDoubleArray::FixedDoubleArrayVerify() {
441   for (int i = 0; i < length(); i++) {
442     if (!is_the_hole(i)) {
443       uint64_t value = get_representation(i);
444       uint64_t unexpected =
445           bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()) &
446           V8_UINT64_C(0x7FF8000000000000);
447       // Create implementation specific sNaN by inverting relevant bit.
448       unexpected ^= V8_UINT64_C(0x0008000000000000);
449       CHECK((value & V8_UINT64_C(0x7FF8000000000000)) != unexpected ||
450             (value & V8_UINT64_C(0x0007FFFFFFFFFFFF)) == V8_UINT64_C(0));
451     }
452   }
453 }
454 
455 
TransitionArrayVerify()456 void TransitionArray::TransitionArrayVerify() {
457   for (int i = 0; i < length(); i++) {
458     Object* e = get(i);
459     VerifyPointer(e);
460   }
461   CHECK_LE(LengthFor(number_of_transitions()), length());
462   CHECK(next_link()->IsUndefined(GetIsolate()) || next_link()->IsSmi() ||
463         next_link()->IsTransitionArray());
464 }
465 
466 
JSGeneratorObjectVerify()467 void JSGeneratorObject::JSGeneratorObjectVerify() {
468   // In an expression like "new g()", there can be a point where a generator
469   // object is allocated but its fields are all undefined, as it hasn't yet been
470   // initialized by the generator.  Hence these weak checks.
471   VerifyObjectField(kFunctionOffset);
472   VerifyObjectField(kContextOffset);
473   VerifyObjectField(kReceiverOffset);
474   VerifyObjectField(kOperandStackOffset);
475   VerifyObjectField(kContinuationOffset);
476 }
477 
478 
JSValueVerify()479 void JSValue::JSValueVerify() {
480   Object* v = value();
481   if (v->IsHeapObject()) {
482     VerifyHeapPointer(v);
483   }
484 }
485 
486 
JSDateVerify()487 void JSDate::JSDateVerify() {
488   if (value()->IsHeapObject()) {
489     VerifyHeapPointer(value());
490   }
491   Isolate* isolate = GetIsolate();
492   CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
493         value()->IsHeapNumber());
494   CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
495   CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
496   CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
497   CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
498         weekday()->IsNaN());
499   CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN());
500   CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN());
501   CHECK(sec()->IsUndefined(isolate) || sec()->IsSmi() || sec()->IsNaN());
502   CHECK(cache_stamp()->IsUndefined(isolate) || cache_stamp()->IsSmi() ||
503         cache_stamp()->IsNaN());
504 
505   if (month()->IsSmi()) {
506     int month = Smi::cast(this->month())->value();
507     CHECK(0 <= month && month <= 11);
508   }
509   if (day()->IsSmi()) {
510     int day = Smi::cast(this->day())->value();
511     CHECK(1 <= day && day <= 31);
512   }
513   if (hour()->IsSmi()) {
514     int hour = Smi::cast(this->hour())->value();
515     CHECK(0 <= hour && hour <= 23);
516   }
517   if (min()->IsSmi()) {
518     int min = Smi::cast(this->min())->value();
519     CHECK(0 <= min && min <= 59);
520   }
521   if (sec()->IsSmi()) {
522     int sec = Smi::cast(this->sec())->value();
523     CHECK(0 <= sec && sec <= 59);
524   }
525   if (weekday()->IsSmi()) {
526     int weekday = Smi::cast(this->weekday())->value();
527     CHECK(0 <= weekday && weekday <= 6);
528   }
529   if (cache_stamp()->IsSmi()) {
530     CHECK(Smi::cast(cache_stamp())->value() <=
531           Smi::cast(isolate->date_cache()->stamp())->value());
532   }
533 }
534 
535 
JSMessageObjectVerify()536 void JSMessageObject::JSMessageObjectVerify() {
537   CHECK(IsJSMessageObject());
538   VerifyObjectField(kStartPositionOffset);
539   VerifyObjectField(kEndPositionOffset);
540   VerifyObjectField(kArgumentsOffset);
541   VerifyObjectField(kScriptOffset);
542   VerifyObjectField(kStackFramesOffset);
543 }
544 
545 
StringVerify()546 void String::StringVerify() {
547   CHECK(IsString());
548   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
549   if (IsInternalizedString()) {
550     CHECK(!GetHeap()->InNewSpace(this));
551   }
552   if (IsConsString()) {
553     ConsString::cast(this)->ConsStringVerify();
554   } else if (IsSlicedString()) {
555     SlicedString::cast(this)->SlicedStringVerify();
556   }
557 }
558 
559 
ConsStringVerify()560 void ConsString::ConsStringVerify() {
561   CHECK(this->first()->IsString());
562   CHECK(this->second() == GetHeap()->empty_string() ||
563         this->second()->IsString());
564   CHECK(this->length() >= ConsString::kMinLength);
565   CHECK(this->length() == this->first()->length() + this->second()->length());
566   if (this->IsFlat()) {
567     // A flat cons can only be created by String::SlowTryFlatten.
568     // Afterwards, the first part may be externalized.
569     CHECK(this->first()->IsSeqString() || this->first()->IsExternalString());
570   }
571 }
572 
573 
SlicedStringVerify()574 void SlicedString::SlicedStringVerify() {
575   CHECK(!this->parent()->IsConsString());
576   CHECK(!this->parent()->IsSlicedString());
577   CHECK(this->length() >= SlicedString::kMinLength);
578 }
579 
580 
JSBoundFunctionVerify()581 void JSBoundFunction::JSBoundFunctionVerify() {
582   CHECK(IsJSBoundFunction());
583   JSObjectVerify();
584   VerifyObjectField(kBoundThisOffset);
585   VerifyObjectField(kBoundTargetFunctionOffset);
586   VerifyObjectField(kBoundArgumentsOffset);
587   CHECK(bound_target_function()->IsCallable());
588   CHECK(IsCallable());
589   CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
590 }
591 
592 
JSFunctionVerify()593 void JSFunction::JSFunctionVerify() {
594   CHECK(IsJSFunction());
595   VerifyObjectField(kPrototypeOrInitialMapOffset);
596   VerifyObjectField(kNextFunctionLinkOffset);
597   CHECK(code()->IsCode());
598   CHECK(next_function_link() == NULL ||
599         next_function_link()->IsUndefined(GetIsolate()) ||
600         next_function_link()->IsJSFunction());
601   CHECK(map()->is_callable());
602 }
603 
604 
SharedFunctionInfoVerify()605 void SharedFunctionInfo::SharedFunctionInfoVerify() {
606   CHECK(IsSharedFunctionInfo());
607   VerifyObjectField(kNameOffset);
608   VerifyObjectField(kCodeOffset);
609   VerifyObjectField(kOptimizedCodeMapOffset);
610   VerifyObjectField(kFeedbackMetadataOffset);
611   VerifyObjectField(kScopeInfoOffset);
612   VerifyObjectField(kOuterScopeInfoOffset);
613   VerifyObjectField(kInstanceClassNameOffset);
614   CHECK(function_data()->IsUndefined(GetIsolate()) || IsApiFunction() ||
615         HasBytecodeArray() || HasAsmWasmData());
616   VerifyObjectField(kFunctionDataOffset);
617   VerifyObjectField(kScriptOffset);
618   VerifyObjectField(kDebugInfoOffset);
619   CHECK(function_identifier()->IsUndefined(GetIsolate()) ||
620         HasBuiltinFunctionId() || HasInferredName());
621   VerifyObjectField(kFunctionIdentifierOffset);
622 }
623 
624 
JSGlobalProxyVerify()625 void JSGlobalProxy::JSGlobalProxyVerify() {
626   CHECK(IsJSGlobalProxy());
627   JSObjectVerify();
628   VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
629   // Make sure that this object has no properties, elements.
630   CHECK_EQ(0, properties()->length());
631   CHECK_EQ(0, FixedArray::cast(elements())->length());
632 }
633 
634 
JSGlobalObjectVerify()635 void JSGlobalObject::JSGlobalObjectVerify() {
636   CHECK(IsJSGlobalObject());
637   // Do not check the dummy global object for the builtins.
638   if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 &&
639       elements()->length() == 0) {
640     return;
641   }
642   JSObjectVerify();
643 }
644 
645 
OddballVerify()646 void Oddball::OddballVerify() {
647   CHECK(IsOddball());
648   Heap* heap = GetHeap();
649   VerifyHeapPointer(to_string());
650   Object* number = to_number();
651   if (number->IsHeapObject()) {
652     CHECK(number == heap->nan_value() ||
653           number == heap->hole_nan_value());
654   } else {
655     CHECK(number->IsSmi());
656     int value = Smi::cast(number)->value();
657     // Hidden oddballs have negative smis.
658     const int kLeastHiddenOddballNumber = -7;
659     CHECK_LE(value, 1);
660     CHECK(value >= kLeastHiddenOddballNumber);
661   }
662   if (map() == heap->undefined_map()) {
663     CHECK(this == heap->undefined_value());
664   } else if (map() == heap->the_hole_map()) {
665     CHECK(this == heap->the_hole_value());
666   } else if (map() == heap->null_map()) {
667     CHECK(this == heap->null_value());
668   } else if (map() == heap->boolean_map()) {
669     CHECK(this == heap->true_value() ||
670           this == heap->false_value());
671   } else if (map() == heap->uninitialized_map()) {
672     CHECK(this == heap->uninitialized_value());
673   } else if (map() == heap->no_interceptor_result_sentinel_map()) {
674     CHECK(this == heap->no_interceptor_result_sentinel());
675   } else if (map() == heap->arguments_marker_map()) {
676     CHECK(this == heap->arguments_marker());
677   } else if (map() == heap->termination_exception_map()) {
678     CHECK(this == heap->termination_exception());
679   } else if (map() == heap->exception_map()) {
680     CHECK(this == heap->exception());
681   } else if (map() == heap->optimized_out_map()) {
682     CHECK(this == heap->optimized_out());
683   } else if (map() == heap->stale_register_map()) {
684     CHECK(this == heap->stale_register());
685   } else {
686     UNREACHABLE();
687   }
688 }
689 
690 
CellVerify()691 void Cell::CellVerify() {
692   CHECK(IsCell());
693   VerifyObjectField(kValueOffset);
694 }
695 
696 
PropertyCellVerify()697 void PropertyCell::PropertyCellVerify() {
698   CHECK(IsPropertyCell());
699   VerifyObjectField(kValueOffset);
700 }
701 
702 
WeakCellVerify()703 void WeakCell::WeakCellVerify() {
704   CHECK(IsWeakCell());
705   VerifyObjectField(kValueOffset);
706   VerifyObjectField(kNextOffset);
707 }
708 
709 
CodeVerify()710 void Code::CodeVerify() {
711   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
712                   kCodeAlignment));
713   relocation_info()->ObjectVerify();
714   Address last_gc_pc = NULL;
715   Isolate* isolate = GetIsolate();
716   for (RelocIterator it(this); !it.done(); it.next()) {
717     it.rinfo()->Verify(isolate);
718     // Ensure that GC will not iterate twice over the same pointer.
719     if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
720       CHECK(it.rinfo()->pc() != last_gc_pc);
721       last_gc_pc = it.rinfo()->pc();
722     }
723   }
724   CHECK(raw_type_feedback_info() == Smi::kZero ||
725         raw_type_feedback_info()->IsSmi() == IsCodeStubOrIC());
726 }
727 
728 
VerifyEmbeddedObjectsDependency()729 void Code::VerifyEmbeddedObjectsDependency() {
730   if (!CanContainWeakObjects()) return;
731   WeakCell* cell = CachedWeakCell();
732   DisallowHeapAllocation no_gc;
733   Isolate* isolate = GetIsolate();
734   HandleScope scope(isolate);
735   int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
736   for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
737     Object* obj = it.rinfo()->target_object();
738     if (IsWeakObject(obj)) {
739       if (obj->IsMap()) {
740         Map* map = Map::cast(obj);
741         CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup,
742                                               cell));
743       } else if (obj->IsJSObject()) {
744         if (isolate->heap()->InNewSpace(obj)) {
745           ArrayList* list =
746               GetIsolate()->heap()->weak_new_space_object_to_code_list();
747           bool found = false;
748           for (int i = 0; i < list->Length(); i += 2) {
749             WeakCell* obj_cell = WeakCell::cast(list->Get(i));
750             if (!obj_cell->cleared() && obj_cell->value() == obj &&
751                 WeakCell::cast(list->Get(i + 1)) == cell) {
752               found = true;
753               break;
754             }
755           }
756           CHECK(found);
757         } else {
758           Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate);
759           DependentCode* dep =
760               GetIsolate()->heap()->LookupWeakObjectToCodeDependency(key_obj);
761           dep->Contains(DependentCode::kWeakCodeGroup, cell);
762         }
763       }
764     }
765   }
766 }
767 
768 
JSArrayVerify()769 void JSArray::JSArrayVerify() {
770   JSObjectVerify();
771   Isolate* isolate = GetIsolate();
772   CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
773   // If a GC was caused while constructing this array, the elements
774   // pointer may point to a one pointer filler map.
775   if (!ElementsAreSafeToExamine()) return;
776   if (elements()->IsUndefined(isolate)) return;
777   CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
778   if (!length()->IsNumber()) return;
779   // Verify that the length and the elements backing store are in sync.
780   if (length()->IsSmi() && HasFastElements()) {
781     int size = Smi::cast(length())->value();
782     // Holey / Packed backing stores might have slack or might have not been
783     // properly initialized yet.
784     CHECK(size <= elements()->length() ||
785           elements() == isolate->heap()->empty_fixed_array());
786   } else {
787     CHECK(HasDictionaryElements());
788     uint32_t array_length;
789     CHECK(length()->ToArrayLength(&array_length));
790     if (array_length == 0xffffffff) {
791       CHECK(length()->ToArrayLength(&array_length));
792     }
793     if (array_length != 0) {
794       SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements());
795       // The dictionary can never have more elements than the array length + 1.
796       // If the backing store grows the verification might be triggered with
797       // the old length in place.
798       uint32_t nof_elements = static_cast<uint32_t>(dict->NumberOfElements());
799       if (nof_elements != 0) nof_elements--;
800       CHECK_LE(nof_elements, array_length);
801     }
802   }
803 }
804 
805 
JSSetVerify()806 void JSSet::JSSetVerify() {
807   CHECK(IsJSSet());
808   JSObjectVerify();
809   VerifyHeapPointer(table());
810   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate()));
811   // TODO(arv): Verify OrderedHashTable too.
812 }
813 
814 
JSMapVerify()815 void JSMap::JSMapVerify() {
816   CHECK(IsJSMap());
817   JSObjectVerify();
818   VerifyHeapPointer(table());
819   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate()));
820   // TODO(arv): Verify OrderedHashTable too.
821 }
822 
823 
JSSetIteratorVerify()824 void JSSetIterator::JSSetIteratorVerify() {
825   CHECK(IsJSSetIterator());
826   JSObjectVerify();
827   VerifyHeapPointer(table());
828   Isolate* isolate = GetIsolate();
829   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(isolate));
830   CHECK(index()->IsSmi() || index()->IsUndefined(isolate));
831   CHECK(kind()->IsSmi() || kind()->IsUndefined(isolate));
832 }
833 
834 
JSMapIteratorVerify()835 void JSMapIterator::JSMapIteratorVerify() {
836   CHECK(IsJSMapIterator());
837   JSObjectVerify();
838   VerifyHeapPointer(table());
839   Isolate* isolate = GetIsolate();
840   CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(isolate));
841   CHECK(index()->IsSmi() || index()->IsUndefined(isolate));
842   CHECK(kind()->IsSmi() || kind()->IsUndefined(isolate));
843 }
844 
845 
JSWeakMapVerify()846 void JSWeakMap::JSWeakMapVerify() {
847   CHECK(IsJSWeakMap());
848   JSObjectVerify();
849   VerifyHeapPointer(table());
850   CHECK(table()->IsHashTable() || table()->IsUndefined(GetIsolate()));
851 }
852 
JSArrayIteratorVerify()853 void JSArrayIterator::JSArrayIteratorVerify() {
854   CHECK(IsJSArrayIterator());
855   JSObjectVerify();
856   CHECK(object()->IsJSReceiver() || object()->IsUndefined(GetIsolate()));
857 
858   CHECK_GE(index()->Number(), 0);
859   CHECK_LE(index()->Number(), kMaxSafeInteger);
860   CHECK(object_map()->IsMap() || object_map()->IsUndefined(GetIsolate()));
861 }
862 
JSStringIteratorVerify()863 void JSStringIterator::JSStringIteratorVerify() {
864   CHECK(IsJSStringIterator());
865   JSObjectVerify();
866   CHECK(string()->IsString());
867 
868   CHECK_GE(index(), 0);
869   CHECK_LE(index(), String::kMaxLength);
870 }
871 
JSWeakSetVerify()872 void JSWeakSet::JSWeakSetVerify() {
873   CHECK(IsJSWeakSet());
874   JSObjectVerify();
875   VerifyHeapPointer(table());
876   CHECK(table()->IsHashTable() || table()->IsUndefined(GetIsolate()));
877 }
878 
879 
JSRegExpVerify()880 void JSRegExp::JSRegExpVerify() {
881   JSObjectVerify();
882   Isolate* isolate = GetIsolate();
883   CHECK(data()->IsUndefined(isolate) || data()->IsFixedArray());
884   switch (TypeTag()) {
885     case JSRegExp::ATOM: {
886       FixedArray* arr = FixedArray::cast(data());
887       CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
888       break;
889     }
890     case JSRegExp::IRREGEXP: {
891       bool is_native = RegExpImpl::UsesNativeRegExp();
892 
893       FixedArray* arr = FixedArray::cast(data());
894       Object* one_byte_data = arr->get(JSRegExp::kIrregexpLatin1CodeIndex);
895       // Smi : Not compiled yet (-1) or code prepared for flushing.
896       // JSObject: Compilation error.
897       // Code/ByteArray: Compiled code.
898       CHECK(
899           one_byte_data->IsSmi() ||
900           (is_native ? one_byte_data->IsCode() : one_byte_data->IsByteArray()));
901       Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
902       CHECK(uc16_data->IsSmi() ||
903              (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
904 
905       Object* one_byte_saved =
906           arr->get(JSRegExp::kIrregexpLatin1CodeSavedIndex);
907       CHECK(one_byte_saved->IsSmi() || one_byte_saved->IsString() ||
908             one_byte_saved->IsCode());
909       Object* uc16_saved = arr->get(JSRegExp::kIrregexpUC16CodeSavedIndex);
910       CHECK(uc16_saved->IsSmi() || uc16_saved->IsString() ||
911              uc16_saved->IsCode());
912 
913       CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
914       CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
915       break;
916     }
917     default:
918       CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
919       CHECK(data()->IsUndefined(isolate));
920       break;
921   }
922 }
923 
JSProxyVerify()924 void JSProxy::JSProxyVerify() {
925   CHECK(IsJSProxy());
926   VerifyPointer(target());
927   VerifyPointer(handler());
928   Isolate* isolate = GetIsolate();
929   CHECK_EQ(target()->IsCallable(), map()->is_callable());
930   CHECK_EQ(target()->IsConstructor(), map()->is_constructor());
931   CHECK(hash()->IsSmi() || hash()->IsUndefined(isolate));
932   CHECK(map()->prototype()->IsNull(isolate));
933   // There should be no properties on a Proxy.
934   CHECK_EQ(0, map()->NumberOfOwnDescriptors());
935 }
936 
937 
JSArrayBufferVerify()938 void JSArrayBuffer::JSArrayBufferVerify() {
939   CHECK(IsJSArrayBuffer());
940   JSObjectVerify();
941   VerifyPointer(byte_length());
942   CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber() ||
943         byte_length()->IsUndefined(GetIsolate()));
944 }
945 
946 
JSArrayBufferViewVerify()947 void JSArrayBufferView::JSArrayBufferViewVerify() {
948   CHECK(IsJSArrayBufferView());
949   JSObjectVerify();
950   VerifyPointer(buffer());
951   Isolate* isolate = GetIsolate();
952   CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined(isolate) ||
953         buffer() == Smi::kZero);
954 
955   VerifyPointer(raw_byte_offset());
956   CHECK(raw_byte_offset()->IsSmi() || raw_byte_offset()->IsHeapNumber() ||
957         raw_byte_offset()->IsUndefined(isolate));
958 
959   VerifyPointer(raw_byte_length());
960   CHECK(raw_byte_length()->IsSmi() || raw_byte_length()->IsHeapNumber() ||
961         raw_byte_length()->IsUndefined(isolate));
962 }
963 
964 
JSTypedArrayVerify()965 void JSTypedArray::JSTypedArrayVerify() {
966   CHECK(IsJSTypedArray());
967   JSArrayBufferViewVerify();
968   VerifyPointer(raw_length());
969   CHECK(raw_length()->IsSmi() || raw_length()->IsUndefined(GetIsolate()));
970   VerifyPointer(elements());
971 }
972 
973 
JSDataViewVerify()974 void JSDataView::JSDataViewVerify() {
975   CHECK(IsJSDataView());
976   JSArrayBufferViewVerify();
977 }
978 
979 
ForeignVerify()980 void Foreign::ForeignVerify() {
981   CHECK(IsForeign());
982 }
983 
984 
BoxVerify()985 void Box::BoxVerify() {
986   CHECK(IsBox());
987   value()->ObjectVerify();
988 }
989 
PromiseResolveThenableJobInfoVerify()990 void PromiseResolveThenableJobInfo::PromiseResolveThenableJobInfoVerify() {
991   Isolate* isolate = GetIsolate();
992   CHECK(IsPromiseResolveThenableJobInfo());
993   CHECK(thenable()->IsJSReceiver());
994   CHECK(then()->IsJSReceiver());
995   CHECK(resolve()->IsJSFunction());
996   CHECK(reject()->IsJSFunction());
997   CHECK(debug_id()->IsNumber() || debug_id()->IsUndefined(isolate));
998   CHECK(debug_name()->IsString() || debug_name()->IsUndefined(isolate));
999   CHECK(context()->IsContext());
1000 }
1001 
PromiseReactionJobInfoVerify()1002 void PromiseReactionJobInfo::PromiseReactionJobInfoVerify() {
1003   Isolate* isolate = GetIsolate();
1004   CHECK(IsPromiseReactionJobInfo());
1005   CHECK(value()->IsObject());
1006   CHECK(tasks()->IsJSArray() || tasks()->IsCallable());
1007   CHECK(deferred()->IsJSObject() || deferred()->IsUndefined(isolate));
1008   CHECK(debug_id()->IsNumber() || debug_id()->IsUndefined(isolate));
1009   CHECK(debug_name()->IsString() || debug_name()->IsUndefined(isolate));
1010   CHECK(context()->IsContext());
1011 }
1012 
JSModuleNamespaceVerify()1013 void JSModuleNamespace::JSModuleNamespaceVerify() {
1014   CHECK(IsJSModuleNamespace());
1015   VerifyPointer(module());
1016 }
1017 
JSFixedArrayIteratorVerify()1018 void JSFixedArrayIterator::JSFixedArrayIteratorVerify() {
1019   CHECK(IsJSFixedArrayIterator());
1020 
1021   VerifyPointer(array());
1022   VerifyPointer(initial_next());
1023   VerifySmiField(kIndexOffset);
1024 
1025   CHECK_LE(index(), array()->length());
1026 }
1027 
ModuleInfoEntryVerify()1028 void ModuleInfoEntry::ModuleInfoEntryVerify() {
1029   Isolate* isolate = GetIsolate();
1030   CHECK(IsModuleInfoEntry());
1031 
1032   CHECK(export_name()->IsUndefined(isolate) || export_name()->IsString());
1033   CHECK(local_name()->IsUndefined(isolate) || local_name()->IsString());
1034   CHECK(import_name()->IsUndefined(isolate) || import_name()->IsString());
1035 
1036   VerifySmiField(kModuleRequestOffset);
1037   VerifySmiField(kCellIndexOffset);
1038   VerifySmiField(kBegPosOffset);
1039   VerifySmiField(kEndPosOffset);
1040 
1041   CHECK_IMPLIES(import_name()->IsString(), module_request() >= 0);
1042   CHECK_IMPLIES(export_name()->IsString() && import_name()->IsString(),
1043                 local_name()->IsUndefined(isolate));
1044 }
1045 
ModuleVerify()1046 void Module::ModuleVerify() {
1047   CHECK(IsModule());
1048 
1049   VerifyPointer(code());
1050   VerifyPointer(exports());
1051   VerifyPointer(module_namespace());
1052   VerifyPointer(requested_modules());
1053   VerifySmiField(kHashOffset);
1054 
1055   CHECK((!instantiated() && code()->IsSharedFunctionInfo()) ||
1056         (instantiated() && !evaluated() && code()->IsJSFunction()) ||
1057         (instantiated() && evaluated() && code()->IsModuleInfo()));
1058 
1059   CHECK(module_namespace()->IsUndefined(GetIsolate()) ||
1060         module_namespace()->IsJSModuleNamespace());
1061   if (module_namespace()->IsJSModuleNamespace()) {
1062     CHECK_EQ(JSModuleNamespace::cast(module_namespace())->module(), this);
1063   }
1064 
1065   CHECK_EQ(requested_modules()->length(), info()->module_requests()->length());
1066 
1067   CHECK_NE(hash(), 0);
1068 }
1069 
PrototypeInfoVerify()1070 void PrototypeInfo::PrototypeInfoVerify() {
1071   CHECK(IsPrototypeInfo());
1072   CHECK(weak_cell()->IsWeakCell() || weak_cell()->IsUndefined(GetIsolate()));
1073   if (prototype_users()->IsWeakFixedArray()) {
1074     WeakFixedArray::cast(prototype_users())->FixedArrayVerify();
1075   } else {
1076     CHECK(prototype_users()->IsSmi());
1077   }
1078   CHECK(validity_cell()->IsCell() || validity_cell()->IsSmi());
1079 }
1080 
Tuple3Verify()1081 void Tuple3::Tuple3Verify() {
1082   CHECK(IsTuple3());
1083   VerifyObjectField(kValue1Offset);
1084   VerifyObjectField(kValue2Offset);
1085   VerifyObjectField(kValue3Offset);
1086 }
1087 
ContextExtensionVerify()1088 void ContextExtension::ContextExtensionVerify() {
1089   CHECK(IsContextExtension());
1090   VerifyObjectField(kScopeInfoOffset);
1091   VerifyObjectField(kExtensionOffset);
1092 }
1093 
1094 
AccessorInfoVerify()1095 void AccessorInfo::AccessorInfoVerify() {
1096   CHECK(IsAccessorInfo());
1097   VerifyPointer(name());
1098   VerifyPointer(expected_receiver_type());
1099   VerifyPointer(getter());
1100   VerifyPointer(setter());
1101   VerifyPointer(js_getter());
1102   VerifyPointer(data());
1103 }
1104 
1105 
AccessorPairVerify()1106 void AccessorPair::AccessorPairVerify() {
1107   CHECK(IsAccessorPair());
1108   VerifyPointer(getter());
1109   VerifyPointer(setter());
1110 }
1111 
1112 
AccessCheckInfoVerify()1113 void AccessCheckInfo::AccessCheckInfoVerify() {
1114   CHECK(IsAccessCheckInfo());
1115   VerifyPointer(callback());
1116   VerifyPointer(named_interceptor());
1117   VerifyPointer(indexed_interceptor());
1118   VerifyPointer(data());
1119 }
1120 
1121 
InterceptorInfoVerify()1122 void InterceptorInfo::InterceptorInfoVerify() {
1123   CHECK(IsInterceptorInfo());
1124   VerifyPointer(getter());
1125   VerifyPointer(setter());
1126   VerifyPointer(query());
1127   VerifyPointer(deleter());
1128   VerifyPointer(enumerator());
1129   VerifyPointer(data());
1130   VerifySmiField(kFlagsOffset);
1131 }
1132 
1133 
CallHandlerInfoVerify()1134 void CallHandlerInfo::CallHandlerInfoVerify() {
1135   CHECK(IsCallHandlerInfo());
1136   VerifyPointer(callback());
1137   VerifyPointer(data());
1138 }
1139 
1140 
TemplateInfoVerify()1141 void TemplateInfo::TemplateInfoVerify() {
1142   VerifyPointer(tag());
1143   VerifyPointer(property_list());
1144   VerifyPointer(property_accessors());
1145 }
1146 
1147 
FunctionTemplateInfoVerify()1148 void FunctionTemplateInfo::FunctionTemplateInfoVerify() {
1149   CHECK(IsFunctionTemplateInfo());
1150   TemplateInfoVerify();
1151   VerifyPointer(serial_number());
1152   VerifyPointer(call_code());
1153   VerifyPointer(prototype_template());
1154   VerifyPointer(parent_template());
1155   VerifyPointer(named_property_handler());
1156   VerifyPointer(indexed_property_handler());
1157   VerifyPointer(instance_template());
1158   VerifyPointer(signature());
1159   VerifyPointer(access_check_info());
1160   VerifyPointer(cached_property_name());
1161 }
1162 
1163 
ObjectTemplateInfoVerify()1164 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
1165   CHECK(IsObjectTemplateInfo());
1166   TemplateInfoVerify();
1167   VerifyPointer(constructor());
1168   VerifyPointer(data());
1169 }
1170 
1171 
AllocationSiteVerify()1172 void AllocationSite::AllocationSiteVerify() {
1173   CHECK(IsAllocationSite());
1174 }
1175 
1176 
AllocationMementoVerify()1177 void AllocationMemento::AllocationMementoVerify() {
1178   CHECK(IsAllocationMemento());
1179   VerifyHeapPointer(allocation_site());
1180   CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
1181 }
1182 
1183 
ScriptVerify()1184 void Script::ScriptVerify() {
1185   CHECK(IsScript());
1186   VerifyPointer(source());
1187   VerifyPointer(name());
1188   VerifyPointer(wrapper());
1189   VerifyPointer(line_ends());
1190 }
1191 
1192 
NormalizedMapCacheVerify()1193 void NormalizedMapCache::NormalizedMapCacheVerify() {
1194   FixedArray::cast(this)->FixedArrayVerify();
1195   if (FLAG_enable_slow_asserts) {
1196     Isolate* isolate = GetIsolate();
1197     for (int i = 0; i < length(); i++) {
1198       Object* e = FixedArray::get(i);
1199       if (e->IsMap()) {
1200         Map::cast(e)->DictionaryMapVerify();
1201       } else {
1202         CHECK(e->IsUndefined(isolate));
1203       }
1204     }
1205   }
1206 }
1207 
1208 
DebugInfoVerify()1209 void DebugInfo::DebugInfoVerify() {
1210   CHECK(IsDebugInfo());
1211   VerifyPointer(shared());
1212   VerifyPointer(debug_bytecode_array());
1213   VerifyPointer(break_points());
1214 }
1215 
1216 
BreakPointInfoVerify()1217 void BreakPointInfo::BreakPointInfoVerify() {
1218   CHECK(IsBreakPointInfo());
1219   VerifyPointer(break_point_objects());
1220 }
1221 #endif  // VERIFY_HEAP
1222 
1223 #ifdef DEBUG
1224 
IncrementSpillStatistics(SpillInformation * info)1225 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
1226   info->number_of_objects_++;
1227   // Named properties
1228   if (HasFastProperties()) {
1229     info->number_of_objects_with_fast_properties_++;
1230     info->number_of_fast_used_fields_   += map()->NextFreePropertyIndex();
1231     info->number_of_fast_unused_fields_ += map()->unused_property_fields();
1232   } else if (IsJSGlobalObject()) {
1233     GlobalDictionary* dict = global_dictionary();
1234     info->number_of_slow_used_properties_ += dict->NumberOfElements();
1235     info->number_of_slow_unused_properties_ +=
1236         dict->Capacity() - dict->NumberOfElements();
1237   } else {
1238     NameDictionary* dict = property_dictionary();
1239     info->number_of_slow_used_properties_ += dict->NumberOfElements();
1240     info->number_of_slow_unused_properties_ +=
1241         dict->Capacity() - dict->NumberOfElements();
1242   }
1243   // Indexed properties
1244   switch (GetElementsKind()) {
1245     case FAST_HOLEY_SMI_ELEMENTS:
1246     case FAST_SMI_ELEMENTS:
1247     case FAST_HOLEY_DOUBLE_ELEMENTS:
1248     case FAST_DOUBLE_ELEMENTS:
1249     case FAST_HOLEY_ELEMENTS:
1250     case FAST_ELEMENTS:
1251     case FAST_STRING_WRAPPER_ELEMENTS: {
1252       info->number_of_objects_with_fast_elements_++;
1253       int holes = 0;
1254       FixedArray* e = FixedArray::cast(elements());
1255       int len = e->length();
1256       Isolate* isolate = GetIsolate();
1257       for (int i = 0; i < len; i++) {
1258         if (e->get(i)->IsTheHole(isolate)) holes++;
1259       }
1260       info->number_of_fast_used_elements_   += len - holes;
1261       info->number_of_fast_unused_elements_ += holes;
1262       break;
1263     }
1264 
1265 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                       \
1266     case TYPE##_ELEMENTS:
1267 
1268     TYPED_ARRAYS(TYPED_ARRAY_CASE)
1269 #undef TYPED_ARRAY_CASE
1270     { info->number_of_objects_with_fast_elements_++;
1271       FixedArrayBase* e = FixedArrayBase::cast(elements());
1272       info->number_of_fast_used_elements_ += e->length();
1273       break;
1274     }
1275     case DICTIONARY_ELEMENTS:
1276     case SLOW_STRING_WRAPPER_ELEMENTS: {
1277       SeededNumberDictionary* dict = element_dictionary();
1278       info->number_of_slow_used_elements_ += dict->NumberOfElements();
1279       info->number_of_slow_unused_elements_ +=
1280           dict->Capacity() - dict->NumberOfElements();
1281       break;
1282     }
1283     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1284     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1285     case NO_ELEMENTS:
1286       break;
1287   }
1288 }
1289 
1290 
Clear()1291 void JSObject::SpillInformation::Clear() {
1292   number_of_objects_ = 0;
1293   number_of_objects_with_fast_properties_ = 0;
1294   number_of_objects_with_fast_elements_ = 0;
1295   number_of_fast_used_fields_ = 0;
1296   number_of_fast_unused_fields_ = 0;
1297   number_of_slow_used_properties_ = 0;
1298   number_of_slow_unused_properties_ = 0;
1299   number_of_fast_used_elements_ = 0;
1300   number_of_fast_unused_elements_ = 0;
1301   number_of_slow_used_elements_ = 0;
1302   number_of_slow_unused_elements_ = 0;
1303 }
1304 
1305 
Print()1306 void JSObject::SpillInformation::Print() {
1307   PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);
1308 
1309   PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
1310          number_of_objects_with_fast_properties_,
1311          number_of_fast_used_fields_, number_of_fast_unused_fields_);
1312 
1313   PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
1314          number_of_objects_ - number_of_objects_with_fast_properties_,
1315          number_of_slow_used_properties_, number_of_slow_unused_properties_);
1316 
1317   PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
1318          number_of_objects_with_fast_elements_,
1319          number_of_fast_used_elements_, number_of_fast_unused_elements_);
1320 
1321   PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
1322          number_of_objects_ - number_of_objects_with_fast_elements_,
1323          number_of_slow_used_elements_, number_of_slow_unused_elements_);
1324 
1325   PrintF("\n");
1326 }
1327 
1328 
IsSortedNoDuplicates(int valid_entries)1329 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
1330   if (valid_entries == -1) valid_entries = number_of_descriptors();
1331   Name* current_key = NULL;
1332   uint32_t current = 0;
1333   for (int i = 0; i < number_of_descriptors(); i++) {
1334     Name* key = GetSortedKey(i);
1335     if (key == current_key) {
1336       Print();
1337       return false;
1338     }
1339     current_key = key;
1340     uint32_t hash = GetSortedKey(i)->Hash();
1341     if (hash < current) {
1342       Print();
1343       return false;
1344     }
1345     current = hash;
1346   }
1347   return true;
1348 }
1349 
1350 
IsSortedNoDuplicates(int valid_entries)1351 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
1352   DCHECK(valid_entries == -1);
1353   Name* prev_key = NULL;
1354   PropertyKind prev_kind = kData;
1355   PropertyAttributes prev_attributes = NONE;
1356   uint32_t prev_hash = 0;
1357   for (int i = 0; i < number_of_transitions(); i++) {
1358     Name* key = GetSortedKey(i);
1359     uint32_t hash = key->Hash();
1360     PropertyKind kind = kData;
1361     PropertyAttributes attributes = NONE;
1362     if (!IsSpecialTransition(key)) {
1363       Map* target = GetTarget(i);
1364       PropertyDetails details = GetTargetDetails(key, target);
1365       kind = details.kind();
1366       attributes = details.attributes();
1367     } else {
1368       // Duplicate entries are not allowed for non-property transitions.
1369       CHECK_NE(prev_key, key);
1370     }
1371 
1372     int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
1373                           hash, kind, attributes);
1374     if (cmp >= 0) {
1375       Print();
1376       return false;
1377     }
1378     prev_key = key;
1379     prev_hash = hash;
1380     prev_attributes = attributes;
1381     prev_kind = kind;
1382   }
1383   return true;
1384 }
1385 
1386 
1387 // static
IsSortedNoDuplicates(Map * map)1388 bool TransitionArray::IsSortedNoDuplicates(Map* map) {
1389   Object* raw_transitions = map->raw_transitions();
1390   if (IsFullTransitionArray(raw_transitions)) {
1391     return TransitionArray::cast(raw_transitions)->IsSortedNoDuplicates();
1392   }
1393   // Simple and non-existent transitions are always sorted.
1394   return true;
1395 }
1396 
1397 
CheckOneBackPointer(Map * current_map,Object * target)1398 static bool CheckOneBackPointer(Map* current_map, Object* target) {
1399   return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
1400 }
1401 
1402 
1403 // static
IsConsistentWithBackPointers(Map * map)1404 bool TransitionArray::IsConsistentWithBackPointers(Map* map) {
1405   Object* transitions = map->raw_transitions();
1406   for (int i = 0; i < TransitionArray::NumberOfTransitions(transitions); ++i) {
1407     Map* target = TransitionArray::GetTarget(transitions, i);
1408     if (!CheckOneBackPointer(map, target)) return false;
1409   }
1410   return true;
1411 }
1412 
1413 
1414 // Estimates if there is a path from the object to a context.
1415 // This function is not precise, and can return false even if
1416 // there is a path to a context.
CanLeak(Object * obj,Heap * heap,bool skip_weak_cell)1417 bool CanLeak(Object* obj, Heap* heap, bool skip_weak_cell) {
1418   if (!obj->IsHeapObject()) return false;
1419   if (obj->IsWeakCell()) {
1420     if (skip_weak_cell) return false;
1421     return CanLeak(WeakCell::cast(obj)->value(), heap, skip_weak_cell);
1422   }
1423   if (obj->IsCell()) {
1424     return CanLeak(Cell::cast(obj)->value(), heap, skip_weak_cell);
1425   }
1426   if (obj->IsPropertyCell()) {
1427     return CanLeak(PropertyCell::cast(obj)->value(), heap, skip_weak_cell);
1428   }
1429   if (obj->IsContext()) return true;
1430   if (obj->IsMap()) {
1431     Map* map = Map::cast(obj);
1432     for (int i = 0; i < Heap::kStrongRootListLength; i++) {
1433       Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
1434       if (map == heap->root(root_index)) return false;
1435     }
1436     return true;
1437   }
1438   return CanLeak(HeapObject::cast(obj)->map(), heap, skip_weak_cell);
1439 }
1440 
1441 
VerifyEmbeddedObjects(VerifyMode mode)1442 void Code::VerifyEmbeddedObjects(VerifyMode mode) {
1443   if (kind() == OPTIMIZED_FUNCTION) return;
1444   Heap* heap = GetIsolate()->heap();
1445   int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
1446              RelocInfo::ModeMask(RelocInfo::CELL);
1447   bool skip_weak_cell = (mode == kNoContextSpecificPointers) ? false : true;
1448   for (RelocIterator it(this, mask); !it.done(); it.next()) {
1449     Object* target = it.rinfo()->rmode() == RelocInfo::CELL
1450                          ? it.rinfo()->target_cell()
1451                          : it.rinfo()->target_object();
1452     CHECK(!CanLeak(target, heap, skip_weak_cell));
1453   }
1454 }
1455 
1456 
1457 // Verify that the debugger can redirect old code to the new code.
VerifyRecompiledCode(Code * old_code,Code * new_code)1458 void Code::VerifyRecompiledCode(Code* old_code, Code* new_code) {
1459   if (old_code->kind() != FUNCTION) return;
1460   if (new_code->kind() != FUNCTION) return;
1461   Isolate* isolate = old_code->GetIsolate();
1462   // Do not verify during bootstrapping. We may replace code using %SetCode.
1463   if (isolate->bootstrapper()->IsActive()) return;
1464 
1465   static const int mask = RelocInfo::kCodeTargetMask;
1466   RelocIterator old_it(old_code, mask);
1467   RelocIterator new_it(new_code, mask);
1468   Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck);
1469 
1470   while (!old_it.done()) {
1471     RelocInfo* rinfo = old_it.rinfo();
1472     Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1473     CHECK(!target->is_handler() && !target->is_inline_cache_stub());
1474     if (target == stack_check) break;
1475     old_it.next();
1476   }
1477 
1478   while (!new_it.done()) {
1479     RelocInfo* rinfo = new_it.rinfo();
1480     Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1481     CHECK(!target->is_handler() && !target->is_inline_cache_stub());
1482     if (target == stack_check) break;
1483     new_it.next();
1484   }
1485 
1486   // Either both are done because there is no stack check.
1487   // Or we are past the prologue for both.
1488   CHECK_EQ(new_it.done(), old_it.done());
1489 
1490   // After the prologue, each call in the old code has a corresponding call
1491   // in the new code.
1492   while (!old_it.done() && !new_it.done()) {
1493     Code* old_target =
1494         Code::GetCodeFromTargetAddress(old_it.rinfo()->target_address());
1495     Code* new_target =
1496         Code::GetCodeFromTargetAddress(new_it.rinfo()->target_address());
1497     CHECK_EQ(old_target->kind(), new_target->kind());
1498     // Check call target for equality unless it's an IC or an interrupt check.
1499     // In both cases they may be patched to be something else.
1500     if (!old_target->is_handler() && !old_target->is_inline_cache_stub() &&
1501         new_target != isolate->builtins()->builtin(Builtins::kInterruptCheck)) {
1502       CHECK_EQ(old_target, new_target);
1503     }
1504     old_it.next();
1505     new_it.next();
1506   }
1507 
1508   // Both are done at the same time.
1509   CHECK_EQ(new_it.done(), old_it.done());
1510 }
1511 
1512 
1513 #endif  // DEBUG
1514 
1515 }  // namespace internal
1516 }  // namespace v8
1517