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/assembler-inl.h"
8 #include "src/bootstrapper.h"
9 #include "src/disasm.h"
10 #include "src/disassembler.h"
11 #include "src/elements.h"
12 #include "src/field-type.h"
13 #include "src/layout-descriptor.h"
14 #include "src/macro-assembler.h"
15 #include "src/objects-inl.h"
16 #include "src/objects/arguments-inl.h"
17 #include "src/objects/bigint.h"
18 #ifdef V8_INTL_SUPPORT
19 #include "src/objects/js-collator-inl.h"
20 #endif // V8_INTL_SUPPORT
21 #include "src/objects/data-handler-inl.h"
22 #include "src/objects/debug-objects-inl.h"
23 #include "src/objects/hash-table-inl.h"
24 #include "src/objects/js-array-inl.h"
25 #include "src/objects/js-collection-inl.h"
26 #include "src/objects/js-generator-inl.h"
27 #include "src/objects/literal-objects-inl.h"
28 #ifdef V8_INTL_SUPPORT
29 #include "src/objects/js-list-format-inl.h"
30 #include "src/objects/js-locale-inl.h"
31 #endif // V8_INTL_SUPPORT
32 #include "src/objects/js-regexp-inl.h"
33 #include "src/objects/js-regexp-string-iterator-inl.h"
34 #ifdef V8_INTL_SUPPORT
35 #include "src/objects/js-plural-rules-inl.h"
36 #include "src/objects/js-relative-time-format-inl.h"
37 #endif // V8_INTL_SUPPORT
38 #include "src/objects/maybe-object.h"
39 #include "src/objects/microtask-inl.h"
40 #include "src/objects/module-inl.h"
41 #include "src/objects/promise-inl.h"
42 #include "src/ostreams.h"
43 #include "src/regexp/jsregexp.h"
44 #include "src/transitions.h"
45 #include "src/wasm/wasm-objects-inl.h"
46
47 namespace v8 {
48 namespace internal {
49
50 // Heap Verification Overview
51 // --------------------------
52 // - Each InstanceType has a separate XXXVerify method which checks an object's
53 // integrity in isolation.
54 // - --verify-heap will iterate over all gc spaces and call ObjectVerify() on
55 // every encountered tagged pointer.
56 // - Verification should be pushed down to the specific instance type if its
57 // integrity is independent of an outer object.
58 // - In cases where the InstanceType is too genernic (e.g. FixedArray) the
59 // XXXVerify of the outer method has to do recursive verification.
60 // - If the corresponding objects have inheritence the parent's Verify method
61 // is called as well.
62 // - For any field containing pointes VerifyPointer(...) should be called.
63 //
64 // Caveats
65 // -------
66 // - Assume that any of the verify methods is incomplete!
67 // - Some integrity checks are only partially done due to objects being in
68 // partially initialized states when a gc happens, for instance when outer
69 // objects are allocted before inner ones.
70 //
71
72 #ifdef VERIFY_HEAP
73
ObjectVerify(Isolate * isolate)74 void Object::ObjectVerify(Isolate* isolate) {
75 if (IsSmi()) {
76 Smi::cast(this)->SmiVerify(isolate);
77 } else {
78 HeapObject::cast(this)->HeapObjectVerify(isolate);
79 }
80 CHECK(!IsConstructor() || IsCallable());
81 }
82
VerifyPointer(Isolate * isolate,Object * p)83 void Object::VerifyPointer(Isolate* isolate, Object* p) {
84 if (p->IsHeapObject()) {
85 HeapObject::VerifyHeapPointer(isolate, p);
86 } else {
87 CHECK(p->IsSmi());
88 }
89 }
90
VerifyMaybeObjectPointer(Isolate * isolate,MaybeObject * p)91 void MaybeObject::VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject* p) {
92 HeapObject* heap_object;
93 if (p->ToStrongOrWeakHeapObject(&heap_object)) {
94 HeapObject::VerifyHeapPointer(isolate, heap_object);
95 } else {
96 CHECK(p->IsSmi() || p->IsClearedWeakHeapObject());
97 }
98 }
99
100 namespace {
VerifyForeignPointer(Isolate * isolate,HeapObject * host,Object * foreign)101 void VerifyForeignPointer(Isolate* isolate, HeapObject* host, Object* foreign) {
102 host->VerifyPointer(isolate, foreign);
103 CHECK(foreign->IsUndefined(isolate) || Foreign::IsNormalized(foreign));
104 }
105 } // namespace
106
SmiVerify(Isolate * isolate)107 void Smi::SmiVerify(Isolate* isolate) {
108 CHECK(IsSmi());
109 CHECK(!IsCallable());
110 CHECK(!IsConstructor());
111 }
112
HeapObjectVerify(Isolate * isolate)113 void HeapObject::HeapObjectVerify(Isolate* isolate) {
114 VerifyHeapPointer(isolate, map());
115 CHECK(map()->IsMap());
116
117 switch (map()->instance_type()) {
118 #define STRING_TYPE_CASE(TYPE, size, name, camel_name) case TYPE:
119 STRING_TYPE_LIST(STRING_TYPE_CASE)
120 #undef STRING_TYPE_CASE
121 String::cast(this)->StringVerify(isolate);
122 break;
123 case SYMBOL_TYPE:
124 Symbol::cast(this)->SymbolVerify(isolate);
125 break;
126 case MAP_TYPE:
127 Map::cast(this)->MapVerify(isolate);
128 break;
129 case HEAP_NUMBER_TYPE:
130 CHECK(IsHeapNumber());
131 break;
132 case MUTABLE_HEAP_NUMBER_TYPE:
133 CHECK(IsMutableHeapNumber());
134 break;
135 case BIGINT_TYPE:
136 BigInt::cast(this)->BigIntVerify(isolate);
137 break;
138 case CALL_HANDLER_INFO_TYPE:
139 CallHandlerInfo::cast(this)->CallHandlerInfoVerify(isolate);
140 break;
141 case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
142 ObjectBoilerplateDescription::cast(this)
143 ->ObjectBoilerplateDescriptionVerify(isolate);
144 break;
145 // FixedArray types
146 case HASH_TABLE_TYPE:
147 case ORDERED_HASH_MAP_TYPE:
148 case ORDERED_HASH_SET_TYPE:
149 case NAME_DICTIONARY_TYPE:
150 case GLOBAL_DICTIONARY_TYPE:
151 case NUMBER_DICTIONARY_TYPE:
152 case SIMPLE_NUMBER_DICTIONARY_TYPE:
153 case STRING_TABLE_TYPE:
154 case EPHEMERON_HASH_TABLE_TYPE:
155 case FIXED_ARRAY_TYPE:
156 case SCOPE_INFO_TYPE:
157 case SCRIPT_CONTEXT_TABLE_TYPE:
158 case BLOCK_CONTEXT_TYPE:
159 case CATCH_CONTEXT_TYPE:
160 case DEBUG_EVALUATE_CONTEXT_TYPE:
161 case EVAL_CONTEXT_TYPE:
162 case FUNCTION_CONTEXT_TYPE:
163 case MODULE_CONTEXT_TYPE:
164 case NATIVE_CONTEXT_TYPE:
165 case SCRIPT_CONTEXT_TYPE:
166 case WITH_CONTEXT_TYPE:
167 FixedArray::cast(this)->FixedArrayVerify(isolate);
168 break;
169 case WEAK_FIXED_ARRAY_TYPE:
170 WeakFixedArray::cast(this)->WeakFixedArrayVerify(isolate);
171 break;
172 case WEAK_ARRAY_LIST_TYPE:
173 WeakArrayList::cast(this)->WeakArrayListVerify(isolate);
174 break;
175 case FIXED_DOUBLE_ARRAY_TYPE:
176 FixedDoubleArray::cast(this)->FixedDoubleArrayVerify(isolate);
177 break;
178 case FEEDBACK_METADATA_TYPE:
179 FeedbackMetadata::cast(this)->FeedbackMetadataVerify(isolate);
180 break;
181 case BYTE_ARRAY_TYPE:
182 ByteArray::cast(this)->ByteArrayVerify(isolate);
183 break;
184 case BYTECODE_ARRAY_TYPE:
185 BytecodeArray::cast(this)->BytecodeArrayVerify(isolate);
186 break;
187 case DESCRIPTOR_ARRAY_TYPE:
188 DescriptorArray::cast(this)->DescriptorArrayVerify(isolate);
189 break;
190 case TRANSITION_ARRAY_TYPE:
191 TransitionArray::cast(this)->TransitionArrayVerify(isolate);
192 break;
193 case PROPERTY_ARRAY_TYPE:
194 PropertyArray::cast(this)->PropertyArrayVerify(isolate);
195 break;
196 case FREE_SPACE_TYPE:
197 FreeSpace::cast(this)->FreeSpaceVerify(isolate);
198 break;
199 case FEEDBACK_CELL_TYPE:
200 FeedbackCell::cast(this)->FeedbackCellVerify(isolate);
201 break;
202 case FEEDBACK_VECTOR_TYPE:
203 FeedbackVector::cast(this)->FeedbackVectorVerify(isolate);
204 break;
205
206 #define VERIFY_TYPED_ARRAY(Type, type, TYPE, ctype) \
207 case FIXED_##TYPE##_ARRAY_TYPE: \
208 Fixed##Type##Array::cast(this)->FixedTypedArrayVerify(isolate); \
209 break;
210
211 TYPED_ARRAYS(VERIFY_TYPED_ARRAY)
212 #undef VERIFY_TYPED_ARRAY
213
214 case CODE_TYPE:
215 Code::cast(this)->CodeVerify(isolate);
216 break;
217 case ODDBALL_TYPE:
218 Oddball::cast(this)->OddballVerify(isolate);
219 break;
220 case JS_OBJECT_TYPE:
221 case JS_ERROR_TYPE:
222 case JS_API_OBJECT_TYPE:
223 case JS_SPECIAL_API_OBJECT_TYPE:
224 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
225 case WASM_GLOBAL_TYPE:
226 case WASM_MEMORY_TYPE:
227 case WASM_TABLE_TYPE:
228 JSObject::cast(this)->JSObjectVerify(isolate);
229 break;
230 case WASM_MODULE_TYPE:
231 WasmModuleObject::cast(this)->WasmModuleObjectVerify(isolate);
232 break;
233 case WASM_INSTANCE_TYPE:
234 WasmInstanceObject::cast(this)->WasmInstanceObjectVerify(isolate);
235 break;
236 case JS_ARGUMENTS_TYPE:
237 JSArgumentsObject::cast(this)->JSArgumentsObjectVerify(isolate);
238 break;
239 case JS_GENERATOR_OBJECT_TYPE:
240 JSGeneratorObject::cast(this)->JSGeneratorObjectVerify(isolate);
241 break;
242 case JS_ASYNC_GENERATOR_OBJECT_TYPE:
243 JSAsyncGeneratorObject::cast(this)->JSAsyncGeneratorObjectVerify(isolate);
244 break;
245 case JS_VALUE_TYPE:
246 JSValue::cast(this)->JSValueVerify(isolate);
247 break;
248 case JS_DATE_TYPE:
249 JSDate::cast(this)->JSDateVerify(isolate);
250 break;
251 case JS_BOUND_FUNCTION_TYPE:
252 JSBoundFunction::cast(this)->JSBoundFunctionVerify(isolate);
253 break;
254 case JS_FUNCTION_TYPE:
255 JSFunction::cast(this)->JSFunctionVerify(isolate);
256 break;
257 case JS_GLOBAL_PROXY_TYPE:
258 JSGlobalProxy::cast(this)->JSGlobalProxyVerify(isolate);
259 break;
260 case JS_GLOBAL_OBJECT_TYPE:
261 JSGlobalObject::cast(this)->JSGlobalObjectVerify(isolate);
262 break;
263 case CELL_TYPE:
264 Cell::cast(this)->CellVerify(isolate);
265 break;
266 case PROPERTY_CELL_TYPE:
267 PropertyCell::cast(this)->PropertyCellVerify(isolate);
268 break;
269 case JS_ARRAY_TYPE:
270 JSArray::cast(this)->JSArrayVerify(isolate);
271 break;
272 case JS_MODULE_NAMESPACE_TYPE:
273 JSModuleNamespace::cast(this)->JSModuleNamespaceVerify(isolate);
274 break;
275 case JS_SET_TYPE:
276 JSSet::cast(this)->JSSetVerify(isolate);
277 break;
278 case JS_MAP_TYPE:
279 JSMap::cast(this)->JSMapVerify(isolate);
280 break;
281 case JS_SET_KEY_VALUE_ITERATOR_TYPE:
282 case JS_SET_VALUE_ITERATOR_TYPE:
283 JSSetIterator::cast(this)->JSSetIteratorVerify(isolate);
284 break;
285 case JS_MAP_KEY_ITERATOR_TYPE:
286 case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
287 case JS_MAP_VALUE_ITERATOR_TYPE:
288 JSMapIterator::cast(this)->JSMapIteratorVerify(isolate);
289 break;
290 case JS_ARRAY_ITERATOR_TYPE:
291 JSArrayIterator::cast(this)->JSArrayIteratorVerify(isolate);
292 break;
293 case JS_STRING_ITERATOR_TYPE:
294 JSStringIterator::cast(this)->JSStringIteratorVerify(isolate);
295 break;
296 case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
297 JSAsyncFromSyncIterator::cast(this)->JSAsyncFromSyncIteratorVerify(
298 isolate);
299 break;
300 case JS_WEAK_MAP_TYPE:
301 JSWeakMap::cast(this)->JSWeakMapVerify(isolate);
302 break;
303 case JS_WEAK_SET_TYPE:
304 JSWeakSet::cast(this)->JSWeakSetVerify(isolate);
305 break;
306 case JS_PROMISE_TYPE:
307 JSPromise::cast(this)->JSPromiseVerify(isolate);
308 break;
309 case JS_REGEXP_TYPE:
310 JSRegExp::cast(this)->JSRegExpVerify(isolate);
311 break;
312 case JS_REGEXP_STRING_ITERATOR_TYPE:
313 JSRegExpStringIterator::cast(this)->JSRegExpStringIteratorVerify(isolate);
314 break;
315 case FILLER_TYPE:
316 break;
317 case JS_PROXY_TYPE:
318 JSProxy::cast(this)->JSProxyVerify(isolate);
319 break;
320 case FOREIGN_TYPE:
321 Foreign::cast(this)->ForeignVerify(isolate);
322 break;
323 case PRE_PARSED_SCOPE_DATA_TYPE:
324 PreParsedScopeData::cast(this)->PreParsedScopeDataVerify(isolate);
325 break;
326 case UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE:
327 UncompiledDataWithoutPreParsedScope::cast(this)
328 ->UncompiledDataWithoutPreParsedScopeVerify(isolate);
329 break;
330 case UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE:
331 UncompiledDataWithPreParsedScope::cast(this)
332 ->UncompiledDataWithPreParsedScopeVerify(isolate);
333 break;
334 case SHARED_FUNCTION_INFO_TYPE:
335 SharedFunctionInfo::cast(this)->SharedFunctionInfoVerify(isolate);
336 break;
337 case JS_MESSAGE_OBJECT_TYPE:
338 JSMessageObject::cast(this)->JSMessageObjectVerify(isolate);
339 break;
340 case JS_ARRAY_BUFFER_TYPE:
341 JSArrayBuffer::cast(this)->JSArrayBufferVerify(isolate);
342 break;
343 case JS_TYPED_ARRAY_TYPE:
344 JSTypedArray::cast(this)->JSTypedArrayVerify(isolate);
345 break;
346 case JS_DATA_VIEW_TYPE:
347 JSDataView::cast(this)->JSDataViewVerify(isolate);
348 break;
349 case SMALL_ORDERED_HASH_SET_TYPE:
350 SmallOrderedHashSet::cast(this)->SmallOrderedHashTableVerify(isolate);
351 break;
352 case SMALL_ORDERED_HASH_MAP_TYPE:
353 SmallOrderedHashMap::cast(this)->SmallOrderedHashTableVerify(isolate);
354 break;
355 case CODE_DATA_CONTAINER_TYPE:
356 CodeDataContainer::cast(this)->CodeDataContainerVerify(isolate);
357 break;
358 #ifdef V8_INTL_SUPPORT
359 case JS_INTL_COLLATOR_TYPE:
360 JSCollator::cast(this)->JSCollatorVerify(isolate);
361 break;
362 case JS_INTL_LIST_FORMAT_TYPE:
363 JSListFormat::cast(this)->JSListFormatVerify(isolate);
364 break;
365 case JS_INTL_LOCALE_TYPE:
366 JSLocale::cast(this)->JSLocaleVerify(isolate);
367 break;
368 case JS_INTL_PLURAL_RULES_TYPE:
369 JSPluralRules::cast(this)->JSPluralRulesVerify(isolate);
370 break;
371 case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
372 JSRelativeTimeFormat::cast(this)->JSRelativeTimeFormatVerify(isolate);
373 break;
374 #endif // V8_INTL_SUPPORT
375
376 #define MAKE_STRUCT_CASE(NAME, Name, name) \
377 case NAME##_TYPE: \
378 Name::cast(this)->Name##Verify(isolate); \
379 break;
380 STRUCT_LIST(MAKE_STRUCT_CASE)
381 #undef MAKE_STRUCT_CASE
382
383 case ALLOCATION_SITE_TYPE:
384 AllocationSite::cast(this)->AllocationSiteVerify(isolate);
385 break;
386
387 case LOAD_HANDLER_TYPE:
388 LoadHandler::cast(this)->LoadHandlerVerify(isolate);
389 break;
390
391 case STORE_HANDLER_TYPE:
392 StoreHandler::cast(this)->StoreHandlerVerify(isolate);
393 break;
394 }
395 }
396
VerifyHeapPointer(Isolate * isolate,Object * p)397 void HeapObject::VerifyHeapPointer(Isolate* isolate, Object* p) {
398 CHECK(p->IsHeapObject());
399 HeapObject* ho = HeapObject::cast(p);
400 CHECK(isolate->heap()->Contains(ho));
401 }
402
SymbolVerify(Isolate * isolate)403 void Symbol::SymbolVerify(Isolate* isolate) {
404 CHECK(IsSymbol());
405 CHECK(HasHashCode());
406 CHECK_GT(Hash(), 0);
407 CHECK(name()->IsUndefined(isolate) || name()->IsString());
408 CHECK_IMPLIES(IsPrivateField(), IsPrivate());
409 }
410
ByteArrayVerify(Isolate * isolate)411 void ByteArray::ByteArrayVerify(Isolate* isolate) { CHECK(IsByteArray()); }
412
BytecodeArrayVerify(Isolate * isolate)413 void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) {
414 // TODO(oth): Walk bytecodes and immediate values to validate sanity.
415 // - All bytecodes are known and well formed.
416 // - Jumps must go to new instructions starts.
417 // - No Illegal bytecodes.
418 // - No consecutive sequences of prefix Wide / ExtraWide.
419 CHECK(IsBytecodeArray());
420 CHECK(constant_pool()->IsFixedArray());
421 VerifyHeapPointer(isolate, constant_pool());
422 }
423
FreeSpaceVerify(Isolate * isolate)424 void FreeSpace::FreeSpaceVerify(Isolate* isolate) { CHECK(IsFreeSpace()); }
425
FeedbackCellVerify(Isolate * isolate)426 void FeedbackCell::FeedbackCellVerify(Isolate* isolate) {
427 CHECK(IsFeedbackCell());
428
429 VerifyHeapPointer(isolate, value());
430 CHECK(value()->IsUndefined(isolate) || value()->IsFeedbackVector());
431 }
432
FeedbackVectorVerify(Isolate * isolate)433 void FeedbackVector::FeedbackVectorVerify(Isolate* isolate) {
434 CHECK(IsFeedbackVector());
435 MaybeObject* code = optimized_code_weak_or_smi();
436 MaybeObject::VerifyMaybeObjectPointer(isolate, code);
437 CHECK(code->IsSmi() || code->IsClearedWeakHeapObject() ||
438 code->IsWeakHeapObject());
439 }
440
441 template <class Traits>
FixedTypedArrayVerify(Isolate * isolate)442 void FixedTypedArray<Traits>::FixedTypedArrayVerify(Isolate* isolate) {
443 CHECK(IsHeapObject() &&
444 HeapObject::cast(this)->map()->instance_type() ==
445 Traits::kInstanceType);
446 if (base_pointer() == this) {
447 CHECK(reinterpret_cast<Address>(external_pointer()) ==
448 ExternalReference::fixed_typed_array_base_data_offset().address());
449 } else {
450 CHECK_NULL(base_pointer());
451 }
452 }
453
ElementsAreSafeToExamine() const454 bool JSObject::ElementsAreSafeToExamine() const {
455 // If a GC was caused while constructing this object, the elements
456 // pointer may point to a one pointer filler map.
457 return reinterpret_cast<Map*>(elements()) !=
458 GetReadOnlyRoots().one_pointer_filler_map();
459 }
460
461 namespace {
VerifyJSObjectElements(Isolate * isolate,JSObject * object)462 void VerifyJSObjectElements(Isolate* isolate, JSObject* object) {
463 // Only TypedArrays can have these specialized elements.
464 if (object->IsJSTypedArray()) {
465 // TODO(cbruni): Fix CreateTypedArray to either not instantiate the object
466 // or propertly initialize it on errors during construction.
467 /* CHECK(object->HasFixedTypedArrayElements()); */
468 /* CHECK(object->elements()->IsFixedTypedArrayBase()); */
469 return;
470 }
471 CHECK(!object->HasFixedTypedArrayElements());
472 CHECK(!object->elements()->IsFixedTypedArrayBase());
473
474 if (object->HasDoubleElements()) {
475 if (object->elements()->length() > 0) {
476 CHECK(object->elements()->IsFixedDoubleArray());
477 }
478 return;
479 }
480
481 FixedArray* elements = FixedArray::cast(object->elements());
482 if (object->HasSmiElements()) {
483 // We might have a partially initialized backing store, in which case we
484 // allow the hole + smi values.
485 for (int i = 0; i < elements->length(); i++) {
486 Object* value = elements->get(i);
487 CHECK(value->IsSmi() || value->IsTheHole(isolate));
488 }
489 } else if (object->HasObjectElements()) {
490 for (int i = 0; i < elements->length(); i++) {
491 Object* element = elements->get(i);
492 CHECK_IMPLIES(!element->IsSmi(), !HasWeakHeapObjectTag(element));
493 }
494 }
495 }
496 } // namespace
497
JSObjectVerify(Isolate * isolate)498 void JSObject::JSObjectVerify(Isolate* isolate) {
499 VerifyPointer(isolate, raw_properties_or_hash());
500 VerifyHeapPointer(isolate, elements());
501
502 CHECK_IMPLIES(HasSloppyArgumentsElements(), IsJSArgumentsObject());
503 if (HasFastProperties()) {
504 int actual_unused_property_fields = map()->GetInObjectProperties() +
505 property_array()->length() -
506 map()->NextFreePropertyIndex();
507 if (map()->UnusedPropertyFields() != actual_unused_property_fields) {
508 // There are two reasons why this can happen:
509 // - in the middle of StoreTransitionStub when the new extended backing
510 // store is already set into the object and the allocation of the
511 // MutableHeapNumber triggers GC while the map isn't updated yet.
512 // - deletion of the last property can leave additional backing store
513 // capacity behind.
514 CHECK_GT(actual_unused_property_fields, map()->UnusedPropertyFields());
515 int delta = actual_unused_property_fields - map()->UnusedPropertyFields();
516 CHECK_EQ(0, delta % JSObject::kFieldsAdded);
517 }
518 DescriptorArray* descriptors = map()->instance_descriptors();
519 bool is_transitionable_fast_elements_kind =
520 IsTransitionableFastElementsKind(map()->elements_kind());
521
522 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
523 PropertyDetails details = descriptors->GetDetails(i);
524 if (details.location() == kField) {
525 DCHECK_EQ(kData, details.kind());
526 Representation r = details.representation();
527 FieldIndex index = FieldIndex::ForDescriptor(map(), i);
528 if (IsUnboxedDoubleField(index)) {
529 DCHECK(r.IsDouble());
530 continue;
531 }
532 Object* value = RawFastPropertyAt(index);
533 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
534 if (value->IsUninitialized(isolate)) continue;
535 if (r.IsSmi()) DCHECK(value->IsSmi());
536 if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
537 FieldType* field_type = descriptors->GetFieldType(i);
538 bool type_is_none = field_type->IsNone();
539 bool type_is_any = field_type->IsAny();
540 if (r.IsNone()) {
541 CHECK(type_is_none);
542 } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
543 CHECK(!field_type->NowStable() || field_type->NowContains(value));
544 }
545 CHECK_IMPLIES(is_transitionable_fast_elements_kind,
546 !Map::IsInplaceGeneralizableField(details.constness(), r,
547 field_type));
548 }
549 }
550
551 if (map()->EnumLength() != kInvalidEnumCacheSentinel) {
552 EnumCache* enum_cache = descriptors->GetEnumCache();
553 FixedArray* keys = enum_cache->keys();
554 FixedArray* indices = enum_cache->indices();
555 CHECK_LE(map()->EnumLength(), keys->length());
556 CHECK_IMPLIES(indices != ReadOnlyRoots(isolate).empty_fixed_array(),
557 keys->length() == indices->length());
558 }
559 }
560
561 // If a GC was caused while constructing this object, the elements
562 // pointer may point to a one pointer filler map.
563 if (ElementsAreSafeToExamine()) {
564 CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
565 (elements() == GetReadOnlyRoots().empty_fixed_array()) ||
566 HasFastStringWrapperElements()),
567 (elements()->map() == GetReadOnlyRoots().fixed_array_map() ||
568 elements()->map() == GetReadOnlyRoots().fixed_cow_array_map()));
569 CHECK_EQ(map()->has_fast_object_elements(), HasObjectElements());
570 VerifyJSObjectElements(isolate, this);
571 }
572 }
573
MapVerify(Isolate * isolate)574 void Map::MapVerify(Isolate* isolate) {
575 Heap* heap = isolate->heap();
576 CHECK(!Heap::InNewSpace(this));
577 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
578 CHECK(instance_size() == kVariableSizeSentinel ||
579 (kPointerSize <= instance_size() &&
580 static_cast<size_t>(instance_size()) < heap->Capacity()));
581 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) ||
582 !Map::cast(GetBackPointer())->is_stable());
583 VerifyHeapPointer(isolate, prototype());
584 VerifyHeapPointer(isolate, instance_descriptors());
585 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
586 DisallowHeapAllocation no_gc;
587 SLOW_DCHECK(
588 TransitionsAccessor(isolate, this, &no_gc).IsSortedNoDuplicates());
589 SLOW_DCHECK(TransitionsAccessor(isolate, this, &no_gc)
590 .IsConsistentWithBackPointers());
591 SLOW_DCHECK(!FLAG_unbox_double_fields ||
592 layout_descriptor()->IsConsistentWithMap(this));
593 if (!may_have_interesting_symbols()) {
594 CHECK(!has_named_interceptor());
595 CHECK(!is_dictionary_map());
596 CHECK(!is_access_check_needed());
597 DescriptorArray* const descriptors = instance_descriptors();
598 for (int i = 0; i < NumberOfOwnDescriptors(); ++i) {
599 CHECK(!descriptors->GetKey(i)->IsInterestingSymbol());
600 }
601 }
602 CHECK_IMPLIES(has_named_interceptor(), may_have_interesting_symbols());
603 CHECK_IMPLIES(is_dictionary_map(), may_have_interesting_symbols());
604 CHECK_IMPLIES(is_access_check_needed(), may_have_interesting_symbols());
605 CHECK_IMPLIES(IsJSObjectMap() && !CanHaveFastTransitionableElementsKind(),
606 IsDictionaryElementsKind(elements_kind()) ||
607 IsTerminalElementsKind(elements_kind()));
608 if (is_prototype_map()) {
609 DCHECK(prototype_info() == Smi::kZero ||
610 prototype_info()->IsPrototypeInfo());
611 }
612 CHECK(prototype_validity_cell()->IsSmi() ||
613 prototype_validity_cell()->IsCell());
614 }
615
DictionaryMapVerify(Isolate * isolate)616 void Map::DictionaryMapVerify(Isolate* isolate) {
617 MapVerify(isolate);
618 CHECK(is_dictionary_map());
619 CHECK_EQ(kInvalidEnumCacheSentinel, EnumLength());
620 CHECK_EQ(ReadOnlyRoots(isolate).empty_descriptor_array(),
621 instance_descriptors());
622 CHECK_EQ(0, UnusedPropertyFields());
623 CHECK_EQ(Map::GetVisitorId(this), visitor_id());
624 }
625
AliasedArgumentsEntryVerify(Isolate * isolate)626 void AliasedArgumentsEntry::AliasedArgumentsEntryVerify(Isolate* isolate) {
627 VerifySmiField(kAliasedContextSlot);
628 }
629
FixedArrayVerify(Isolate * isolate)630 void FixedArray::FixedArrayVerify(Isolate* isolate) {
631 for (int i = 0; i < length(); i++) {
632 Object* e = get(i);
633 VerifyPointer(isolate, e);
634 }
635 }
636
WeakFixedArrayVerify(Isolate * isolate)637 void WeakFixedArray::WeakFixedArrayVerify(Isolate* isolate) {
638 for (int i = 0; i < length(); i++) {
639 MaybeObject::VerifyMaybeObjectPointer(isolate, Get(i));
640 }
641 }
642
WeakArrayListVerify(Isolate * isolate)643 void WeakArrayList::WeakArrayListVerify(Isolate* isolate) {
644 for (int i = 0; i < length(); i++) {
645 MaybeObject::VerifyMaybeObjectPointer(isolate, Get(i));
646 }
647 }
648
PropertyArrayVerify(Isolate * isolate)649 void PropertyArray::PropertyArrayVerify(Isolate* isolate) {
650 if (length() == 0) {
651 CHECK_EQ(this, ReadOnlyRoots(isolate).empty_property_array());
652 return;
653 }
654 // There are no empty PropertyArrays.
655 CHECK_LT(0, length());
656 for (int i = 0; i < length(); i++) {
657 Object* e = get(i);
658 VerifyPointer(isolate, e);
659 }
660 }
661
FixedDoubleArrayVerify(Isolate * isolate)662 void FixedDoubleArray::FixedDoubleArrayVerify(Isolate* isolate) {
663 for (int i = 0; i < length(); i++) {
664 if (!is_the_hole(i)) {
665 uint64_t value = get_representation(i);
666 uint64_t unexpected =
667 bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()) &
668 uint64_t{0x7FF8000000000000};
669 // Create implementation specific sNaN by inverting relevant bit.
670 unexpected ^= uint64_t{0x0008000000000000};
671 CHECK((value & uint64_t{0x7FF8000000000000}) != unexpected ||
672 (value & uint64_t{0x0007FFFFFFFFFFFF}) == uint64_t{0});
673 }
674 }
675 }
676
FeedbackMetadataVerify(Isolate * isolate)677 void FeedbackMetadata::FeedbackMetadataVerify(Isolate* isolate) {
678 if (slot_count() == 0) {
679 CHECK_EQ(ReadOnlyRoots(isolate).empty_feedback_metadata(), this);
680 } else {
681 FeedbackMetadataIterator iter(this);
682 while (iter.HasNext()) {
683 iter.Next();
684 FeedbackSlotKind kind = iter.kind();
685 CHECK_NE(FeedbackSlotKind::kInvalid, kind);
686 CHECK_GT(FeedbackSlotKind::kKindsNumber, kind);
687 }
688 }
689 }
690
DescriptorArrayVerify(Isolate * isolate)691 void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) {
692 WeakFixedArrayVerify(isolate);
693 int nof_descriptors = number_of_descriptors();
694 if (number_of_descriptors_storage() == 0) {
695 Heap* heap = isolate->heap();
696 CHECK_EQ(ReadOnlyRoots(heap).empty_descriptor_array(), this);
697 CHECK_EQ(2, length());
698 CHECK_EQ(0, nof_descriptors);
699 CHECK_EQ(ReadOnlyRoots(heap).empty_enum_cache(), GetEnumCache());
700 } else {
701 CHECK_LT(2, length());
702 CHECK_LE(LengthFor(nof_descriptors), length());
703
704 // Check that properties with private symbols names are non-enumerable.
705 for (int descriptor = 0; descriptor < nof_descriptors; descriptor++) {
706 Object* key = get(ToKeyIndex(descriptor))->ToObject();
707 // number_of_descriptors() may be out of sync with the actual descriptors
708 // written during descriptor array construction.
709 if (key->IsUndefined(isolate)) continue;
710 PropertyDetails details = GetDetails(descriptor);
711 if (Name::cast(key)->IsPrivate()) {
712 CHECK_NE(details.attributes() & DONT_ENUM, 0);
713 }
714 MaybeObject* value = get(ToValueIndex(descriptor));
715 HeapObject* heap_object;
716 if (details.location() == kField) {
717 CHECK(value == MaybeObject::FromObject(FieldType::None()) ||
718 value == MaybeObject::FromObject(FieldType::Any()) ||
719 value->IsClearedWeakHeapObject() ||
720 (value->ToWeakHeapObject(&heap_object) && heap_object->IsMap()));
721 } else {
722 CHECK(!value->IsWeakOrClearedHeapObject());
723 CHECK(!value->ToObject()->IsMap());
724 }
725 }
726 }
727 }
728
TransitionArrayVerify(Isolate * isolate)729 void TransitionArray::TransitionArrayVerify(Isolate* isolate) {
730 WeakFixedArrayVerify(isolate);
731 CHECK_LE(LengthFor(number_of_transitions()), length());
732 }
733
JSArgumentsObjectVerify(Isolate * isolate)734 void JSArgumentsObject::JSArgumentsObjectVerify(Isolate* isolate) {
735 if (IsSloppyArgumentsElementsKind(GetElementsKind())) {
736 SloppyArgumentsElements::cast(elements())
737 ->SloppyArgumentsElementsVerify(isolate, this);
738 }
739 if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) ||
740 isolate->IsInAnyContext(map(),
741 Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) ||
742 isolate->IsInAnyContext(map(),
743 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) {
744 VerifyObjectField(isolate, JSSloppyArgumentsObject::kLengthOffset);
745 VerifyObjectField(isolate, JSSloppyArgumentsObject::kCalleeOffset);
746 } else if (isolate->IsInAnyContext(map(),
747 Context::STRICT_ARGUMENTS_MAP_INDEX)) {
748 VerifyObjectField(isolate, JSStrictArgumentsObject::kLengthOffset);
749 }
750 JSObjectVerify(isolate);
751 }
752
SloppyArgumentsElementsVerify(Isolate * isolate,JSObject * holder)753 void SloppyArgumentsElements::SloppyArgumentsElementsVerify(Isolate* isolate,
754 JSObject* holder) {
755 FixedArrayVerify(isolate);
756 // Abort verification if only partially initialized (can't use arguments()
757 // getter because it does FixedArray::cast()).
758 if (get(kArgumentsIndex)->IsUndefined(isolate)) return;
759
760 ElementsKind kind = holder->GetElementsKind();
761 bool is_fast = kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
762 CHECK(IsFixedArray());
763 CHECK_GE(length(), 2);
764 CHECK_EQ(map(), ReadOnlyRoots(isolate).sloppy_arguments_elements_map());
765 Context* context_object = Context::cast(context());
766 FixedArray* arg_elements = FixedArray::cast(arguments());
767 if (arg_elements->length() == 0) {
768 CHECK(arg_elements == ReadOnlyRoots(isolate).empty_fixed_array());
769 return;
770 }
771 ElementsAccessor* accessor;
772 if (is_fast) {
773 accessor = ElementsAccessor::ForKind(HOLEY_ELEMENTS);
774 } else {
775 accessor = ElementsAccessor::ForKind(DICTIONARY_ELEMENTS);
776 }
777 int nofMappedParameters = 0;
778 int maxMappedIndex = 0;
779 for (int i = 0; i < nofMappedParameters; i++) {
780 // Verify that each context-mapped argument is either the hole or a valid
781 // Smi within context length range.
782 Object* mapped = get_mapped_entry(i);
783 if (mapped->IsTheHole(isolate)) {
784 // Slow sloppy arguments can be holey.
785 if (!is_fast) continue;
786 // Fast sloppy arguments elements are never holey. Either the element is
787 // context-mapped or present in the arguments elements.
788 CHECK(accessor->HasElement(holder, i, arg_elements));
789 continue;
790 }
791 int mappedIndex = Smi::ToInt(mapped);
792 nofMappedParameters++;
793 CHECK_LE(maxMappedIndex, mappedIndex);
794 maxMappedIndex = mappedIndex;
795 Object* value = context_object->get(mappedIndex);
796 CHECK(value->IsObject());
797 // None of the context-mapped entries should exist in the arguments
798 // elements.
799 CHECK(!accessor->HasElement(holder, i, arg_elements));
800 }
801 CHECK_LE(nofMappedParameters, context_object->length());
802 CHECK_LE(nofMappedParameters, arg_elements->length());
803 CHECK_LE(maxMappedIndex, context_object->length());
804 CHECK_LE(maxMappedIndex, arg_elements->length());
805 }
806
JSGeneratorObjectVerify(Isolate * isolate)807 void JSGeneratorObject::JSGeneratorObjectVerify(Isolate* isolate) {
808 // In an expression like "new g()", there can be a point where a generator
809 // object is allocated but its fields are all undefined, as it hasn't yet been
810 // initialized by the generator. Hence these weak checks.
811 VerifyObjectField(isolate, kFunctionOffset);
812 VerifyObjectField(isolate, kContextOffset);
813 VerifyObjectField(isolate, kReceiverOffset);
814 VerifyObjectField(isolate, kParametersAndRegistersOffset);
815 VerifyObjectField(isolate, kContinuationOffset);
816 }
817
JSAsyncGeneratorObjectVerify(Isolate * isolate)818 void JSAsyncGeneratorObject::JSAsyncGeneratorObjectVerify(Isolate* isolate) {
819 // Check inherited fields
820 JSGeneratorObjectVerify(isolate);
821 VerifyObjectField(isolate, kQueueOffset);
822 queue()->HeapObjectVerify(isolate);
823 }
824
JSValueVerify(Isolate * isolate)825 void JSValue::JSValueVerify(Isolate* isolate) {
826 Object* v = value();
827 if (v->IsHeapObject()) {
828 VerifyHeapPointer(isolate, v);
829 }
830 }
831
JSDateVerify(Isolate * isolate)832 void JSDate::JSDateVerify(Isolate* isolate) {
833 if (value()->IsHeapObject()) {
834 VerifyHeapPointer(isolate, value());
835 }
836 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
837 value()->IsHeapNumber());
838 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
839 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
840 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
841 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
842 weekday()->IsNaN());
843 CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN());
844 CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN());
845 CHECK(sec()->IsUndefined(isolate) || sec()->IsSmi() || sec()->IsNaN());
846 CHECK(cache_stamp()->IsUndefined(isolate) || cache_stamp()->IsSmi() ||
847 cache_stamp()->IsNaN());
848
849 if (month()->IsSmi()) {
850 int month = Smi::ToInt(this->month());
851 CHECK(0 <= month && month <= 11);
852 }
853 if (day()->IsSmi()) {
854 int day = Smi::ToInt(this->day());
855 CHECK(1 <= day && day <= 31);
856 }
857 if (hour()->IsSmi()) {
858 int hour = Smi::ToInt(this->hour());
859 CHECK(0 <= hour && hour <= 23);
860 }
861 if (min()->IsSmi()) {
862 int min = Smi::ToInt(this->min());
863 CHECK(0 <= min && min <= 59);
864 }
865 if (sec()->IsSmi()) {
866 int sec = Smi::ToInt(this->sec());
867 CHECK(0 <= sec && sec <= 59);
868 }
869 if (weekday()->IsSmi()) {
870 int weekday = Smi::ToInt(this->weekday());
871 CHECK(0 <= weekday && weekday <= 6);
872 }
873 if (cache_stamp()->IsSmi()) {
874 CHECK(Smi::ToInt(cache_stamp()) <=
875 Smi::ToInt(isolate->date_cache()->stamp()));
876 }
877 }
878
JSMessageObjectVerify(Isolate * isolate)879 void JSMessageObject::JSMessageObjectVerify(Isolate* isolate) {
880 CHECK(IsJSMessageObject());
881 VerifyObjectField(isolate, kStartPositionOffset);
882 VerifyObjectField(isolate, kEndPositionOffset);
883 VerifyObjectField(isolate, kArgumentsOffset);
884 VerifyObjectField(isolate, kScriptOffset);
885 VerifyObjectField(isolate, kStackFramesOffset);
886 }
887
StringVerify(Isolate * isolate)888 void String::StringVerify(Isolate* isolate) {
889 CHECK(IsString());
890 CHECK(length() >= 0 && length() <= Smi::kMaxValue);
891 CHECK_IMPLIES(length() == 0, this == ReadOnlyRoots(isolate).empty_string());
892 if (IsInternalizedString()) {
893 CHECK(!Heap::InNewSpace(this));
894 }
895 if (IsConsString()) {
896 ConsString::cast(this)->ConsStringVerify(isolate);
897 } else if (IsSlicedString()) {
898 SlicedString::cast(this)->SlicedStringVerify(isolate);
899 } else if (IsThinString()) {
900 ThinString::cast(this)->ThinStringVerify(isolate);
901 }
902 }
903
ConsStringVerify(Isolate * isolate)904 void ConsString::ConsStringVerify(Isolate* isolate) {
905 CHECK(this->first()->IsString());
906 CHECK(this->second() == ReadOnlyRoots(isolate).empty_string() ||
907 this->second()->IsString());
908 CHECK_GE(this->length(), ConsString::kMinLength);
909 CHECK(this->length() == this->first()->length() + this->second()->length());
910 if (this->IsFlat()) {
911 // A flat cons can only be created by String::SlowFlatten.
912 // Afterwards, the first part may be externalized or internalized.
913 CHECK(this->first()->IsSeqString() || this->first()->IsExternalString() ||
914 this->first()->IsThinString());
915 }
916 }
917
ThinStringVerify(Isolate * isolate)918 void ThinString::ThinStringVerify(Isolate* isolate) {
919 CHECK(this->actual()->IsInternalizedString());
920 CHECK(this->actual()->IsSeqString() || this->actual()->IsExternalString());
921 }
922
SlicedStringVerify(Isolate * isolate)923 void SlicedString::SlicedStringVerify(Isolate* isolate) {
924 CHECK(!this->parent()->IsConsString());
925 CHECK(!this->parent()->IsSlicedString());
926 CHECK_GE(this->length(), SlicedString::kMinLength);
927 }
928
JSBoundFunctionVerify(Isolate * isolate)929 void JSBoundFunction::JSBoundFunctionVerify(Isolate* isolate) {
930 CHECK(IsJSBoundFunction());
931 JSObjectVerify(isolate);
932 VerifyObjectField(isolate, kBoundThisOffset);
933 VerifyObjectField(isolate, kBoundTargetFunctionOffset);
934 VerifyObjectField(isolate, kBoundArgumentsOffset);
935 CHECK(IsCallable());
936
937 if (!raw_bound_target_function()->IsUndefined(isolate)) {
938 CHECK(bound_target_function()->IsCallable());
939 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
940 }
941 }
942
JSFunctionVerify(Isolate * isolate)943 void JSFunction::JSFunctionVerify(Isolate* isolate) {
944 CHECK(IsJSFunction());
945 JSObjectVerify(isolate);
946 VerifyHeapPointer(isolate, feedback_cell());
947 CHECK(feedback_cell()->IsFeedbackCell());
948 CHECK(code()->IsCode());
949 CHECK(map()->is_callable());
950 Handle<JSFunction> function(this, isolate);
951 LookupIterator it(isolate, function, isolate->factory()->prototype_string(),
952 LookupIterator::OWN_SKIP_INTERCEPTOR);
953 if (has_prototype_slot()) {
954 VerifyObjectField(isolate, kPrototypeOrInitialMapOffset);
955 }
956
957 if (has_prototype_property()) {
958 CHECK(it.IsFound());
959 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
960 CHECK(it.GetAccessors()->IsAccessorInfo());
961 } else {
962 CHECK(!it.IsFound() || it.state() != LookupIterator::ACCESSOR ||
963 !it.GetAccessors()->IsAccessorInfo());
964 }
965 }
966
SharedFunctionInfoVerify(Isolate * isolate)967 void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) {
968 CHECK(IsSharedFunctionInfo());
969
970 VerifyObjectField(isolate, kFunctionDataOffset);
971 VerifyObjectField(isolate, kOuterScopeInfoOrFeedbackMetadataOffset);
972 VerifyObjectField(isolate, kScriptOrDebugInfoOffset);
973 VerifyObjectField(isolate, kNameOrScopeInfoOffset);
974
975 Object* value = name_or_scope_info();
976 CHECK(value == kNoSharedNameSentinel || value->IsString() ||
977 value->IsScopeInfo());
978 if (value->IsScopeInfo()) {
979 CHECK_LT(0, ScopeInfo::cast(value)->length());
980 CHECK_NE(value, ReadOnlyRoots(isolate).empty_scope_info());
981 }
982
983 CHECK(HasWasmExportedFunctionData() || IsApiFunction() ||
984 HasBytecodeArray() || HasAsmWasmData() || HasBuiltinId() ||
985 HasUncompiledDataWithPreParsedScope() ||
986 HasUncompiledDataWithoutPreParsedScope());
987
988 CHECK(script_or_debug_info()->IsUndefined(isolate) ||
989 script_or_debug_info()->IsScript() || HasDebugInfo());
990
991 if (!is_compiled()) {
992 CHECK(!HasFeedbackMetadata());
993 CHECK(outer_scope_info()->IsScopeInfo() ||
994 outer_scope_info()->IsTheHole(isolate));
995 } else if (HasBytecodeArray()) {
996 CHECK(HasFeedbackMetadata());
997 CHECK(feedback_metadata()->IsFeedbackMetadata());
998 }
999
1000 int expected_map_index = Context::FunctionMapIndex(
1001 language_mode(), kind(), true, HasSharedName(), needs_home_object());
1002 CHECK_EQ(expected_map_index, function_map_index());
1003
1004 if (scope_info()->length() > 0) {
1005 ScopeInfo* info = scope_info();
1006 CHECK(kind() == info->function_kind());
1007 CHECK_EQ(kind() == kModule, info->scope_type() == MODULE_SCOPE);
1008 }
1009
1010 if (IsApiFunction()) {
1011 CHECK(construct_as_builtin());
1012 } else if (!HasBuiltinId()) {
1013 CHECK(!construct_as_builtin());
1014 } else {
1015 int id = builtin_id();
1016 if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
1017 CHECK(construct_as_builtin());
1018 } else {
1019 CHECK(!construct_as_builtin());
1020 }
1021 }
1022 }
1023
JSGlobalProxyVerify(Isolate * isolate)1024 void JSGlobalProxy::JSGlobalProxyVerify(Isolate* isolate) {
1025 CHECK(IsJSGlobalProxy());
1026 JSObjectVerify(isolate);
1027 VerifyObjectField(isolate, JSGlobalProxy::kNativeContextOffset);
1028 CHECK(map()->is_access_check_needed());
1029 // Make sure that this object has no properties, elements.
1030 CHECK_EQ(0, FixedArray::cast(elements())->length());
1031 }
1032
JSGlobalObjectVerify(Isolate * isolate)1033 void JSGlobalObject::JSGlobalObjectVerify(Isolate* isolate) {
1034 CHECK(IsJSGlobalObject());
1035 // Do not check the dummy global object for the builtins.
1036 if (global_dictionary()->NumberOfElements() == 0 &&
1037 elements()->length() == 0) {
1038 return;
1039 }
1040 JSObjectVerify(isolate);
1041 }
1042
OddballVerify(Isolate * isolate)1043 void Oddball::OddballVerify(Isolate* isolate) {
1044 CHECK(IsOddball());
1045 Heap* heap = isolate->heap();
1046 VerifyHeapPointer(isolate, to_string());
1047 Object* number = to_number();
1048 if (number->IsHeapObject()) {
1049 CHECK(number == ReadOnlyRoots(heap).nan_value() ||
1050 number == ReadOnlyRoots(heap).hole_nan_value());
1051 } else {
1052 CHECK(number->IsSmi());
1053 int value = Smi::ToInt(number);
1054 // Hidden oddballs have negative smis.
1055 const int kLeastHiddenOddballNumber = -7;
1056 CHECK_LE(value, 1);
1057 CHECK_GE(value, kLeastHiddenOddballNumber);
1058 }
1059
1060 ReadOnlyRoots roots(heap);
1061 if (map() == roots.undefined_map()) {
1062 CHECK(this == roots.undefined_value());
1063 } else if (map() == roots.the_hole_map()) {
1064 CHECK(this == roots.the_hole_value());
1065 } else if (map() == roots.null_map()) {
1066 CHECK(this == roots.null_value());
1067 } else if (map() == roots.boolean_map()) {
1068 CHECK(this == roots.true_value() || this == roots.false_value());
1069 } else if (map() == roots.uninitialized_map()) {
1070 CHECK(this == roots.uninitialized_value());
1071 } else if (map() == roots.arguments_marker_map()) {
1072 CHECK(this == roots.arguments_marker());
1073 } else if (map() == roots.termination_exception_map()) {
1074 CHECK(this == roots.termination_exception());
1075 } else if (map() == roots.exception_map()) {
1076 CHECK(this == roots.exception());
1077 } else if (map() == roots.optimized_out_map()) {
1078 CHECK(this == roots.optimized_out());
1079 } else if (map() == roots.stale_register_map()) {
1080 CHECK(this == roots.stale_register());
1081 } else if (map() == roots.self_reference_marker_map()) {
1082 // Multiple instances of this oddball may exist at once.
1083 CHECK_EQ(kind(), Oddball::kSelfReferenceMarker);
1084 } else {
1085 UNREACHABLE();
1086 }
1087 }
1088
CellVerify(Isolate * isolate)1089 void Cell::CellVerify(Isolate* isolate) {
1090 CHECK(IsCell());
1091 VerifyObjectField(isolate, kValueOffset);
1092 }
1093
PropertyCellVerify(Isolate * isolate)1094 void PropertyCell::PropertyCellVerify(Isolate* isolate) {
1095 CHECK(IsPropertyCell());
1096 VerifyObjectField(isolate, kValueOffset);
1097 }
1098
CodeDataContainerVerify(Isolate * isolate)1099 void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) {
1100 CHECK(IsCodeDataContainer());
1101 VerifyObjectField(isolate, kNextCodeLinkOffset);
1102 CHECK(next_code_link()->IsCode() || next_code_link()->IsUndefined(isolate));
1103 }
1104
CodeVerify(Isolate * isolate)1105 void Code::CodeVerify(Isolate* isolate) {
1106 CHECK_LE(constant_pool_offset(), InstructionSize());
1107 CHECK(IsAligned(InstructionStart(), kCodeAlignment));
1108 relocation_info()->ObjectVerify(isolate);
1109 Address last_gc_pc = kNullAddress;
1110
1111 for (RelocIterator it(this); !it.done(); it.next()) {
1112 it.rinfo()->Verify(isolate);
1113 // Ensure that GC will not iterate twice over the same pointer.
1114 if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
1115 CHECK(it.rinfo()->pc() != last_gc_pc);
1116 last_gc_pc = it.rinfo()->pc();
1117 }
1118 }
1119 }
1120
JSArrayVerify(Isolate * isolate)1121 void JSArray::JSArrayVerify(Isolate* isolate) {
1122 JSObjectVerify(isolate);
1123 CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
1124 // If a GC was caused while constructing this array, the elements
1125 // pointer may point to a one pointer filler map.
1126 if (!ElementsAreSafeToExamine()) return;
1127 if (elements()->IsUndefined(isolate)) return;
1128 CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
1129 if (elements()->length() == 0) {
1130 CHECK_EQ(elements(), ReadOnlyRoots(isolate).empty_fixed_array());
1131 }
1132 if (!length()->IsNumber()) return;
1133 // Verify that the length and the elements backing store are in sync.
1134 if (length()->IsSmi() && HasFastElements()) {
1135 if (elements()->length() > 0) {
1136 CHECK_IMPLIES(HasDoubleElements(), elements()->IsFixedDoubleArray());
1137 }
1138 int size = Smi::ToInt(length());
1139 // Holey / Packed backing stores might have slack or might have not been
1140 // properly initialized yet.
1141 CHECK(size <= elements()->length() ||
1142 elements() == ReadOnlyRoots(isolate).empty_fixed_array());
1143 } else {
1144 CHECK(HasDictionaryElements());
1145 uint32_t array_length;
1146 CHECK(length()->ToArrayLength(&array_length));
1147 if (array_length == 0xFFFFFFFF) {
1148 CHECK(length()->ToArrayLength(&array_length));
1149 }
1150 if (array_length != 0) {
1151 NumberDictionary* dict = NumberDictionary::cast(elements());
1152 // The dictionary can never have more elements than the array length + 1.
1153 // If the backing store grows the verification might be triggered with
1154 // the old length in place.
1155 uint32_t nof_elements = static_cast<uint32_t>(dict->NumberOfElements());
1156 if (nof_elements != 0) nof_elements--;
1157 CHECK_LE(nof_elements, array_length);
1158 }
1159 }
1160 }
1161
JSSetVerify(Isolate * isolate)1162 void JSSet::JSSetVerify(Isolate* isolate) {
1163 CHECK(IsJSSet());
1164 JSObjectVerify(isolate);
1165 VerifyHeapPointer(isolate, table());
1166 CHECK(table()->IsOrderedHashSet() || table()->IsUndefined(isolate));
1167 // TODO(arv): Verify OrderedHashTable too.
1168 }
1169
JSMapVerify(Isolate * isolate)1170 void JSMap::JSMapVerify(Isolate* isolate) {
1171 CHECK(IsJSMap());
1172 JSObjectVerify(isolate);
1173 VerifyHeapPointer(isolate, table());
1174 CHECK(table()->IsOrderedHashMap() || table()->IsUndefined(isolate));
1175 // TODO(arv): Verify OrderedHashTable too.
1176 }
1177
JSSetIteratorVerify(Isolate * isolate)1178 void JSSetIterator::JSSetIteratorVerify(Isolate* isolate) {
1179 CHECK(IsJSSetIterator());
1180 JSObjectVerify(isolate);
1181 VerifyHeapPointer(isolate, table());
1182 CHECK(table()->IsOrderedHashSet());
1183 CHECK(index()->IsSmi());
1184 }
1185
JSMapIteratorVerify(Isolate * isolate)1186 void JSMapIterator::JSMapIteratorVerify(Isolate* isolate) {
1187 CHECK(IsJSMapIterator());
1188 JSObjectVerify(isolate);
1189 VerifyHeapPointer(isolate, table());
1190 CHECK(table()->IsOrderedHashMap());
1191 CHECK(index()->IsSmi());
1192 }
1193
JSWeakMapVerify(Isolate * isolate)1194 void JSWeakMap::JSWeakMapVerify(Isolate* isolate) {
1195 CHECK(IsJSWeakMap());
1196 JSObjectVerify(isolate);
1197 VerifyHeapPointer(isolate, table());
1198 CHECK(table()->IsEphemeronHashTable() || table()->IsUndefined(isolate));
1199 }
1200
JSArrayIteratorVerify(Isolate * isolate)1201 void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) {
1202 CHECK(IsJSArrayIterator());
1203 JSObjectVerify(isolate);
1204 CHECK(iterated_object()->IsJSReceiver());
1205
1206 CHECK_GE(next_index()->Number(), 0);
1207 CHECK_LE(next_index()->Number(), kMaxSafeInteger);
1208
1209 if (iterated_object()->IsJSTypedArray()) {
1210 // JSTypedArray::length is limited to Smi range.
1211 CHECK(next_index()->IsSmi());
1212 CHECK_LE(next_index()->Number(), Smi::kMaxValue);
1213 } else if (iterated_object()->IsJSArray()) {
1214 // JSArray::length is limited to Uint32 range.
1215 CHECK_LE(next_index()->Number(), kMaxUInt32);
1216 }
1217 }
1218
JSStringIteratorVerify(Isolate * isolate)1219 void JSStringIterator::JSStringIteratorVerify(Isolate* isolate) {
1220 CHECK(IsJSStringIterator());
1221 JSObjectVerify(isolate);
1222 CHECK(string()->IsString());
1223
1224 CHECK_GE(index(), 0);
1225 CHECK_LE(index(), String::kMaxLength);
1226 }
1227
JSAsyncFromSyncIteratorVerify(Isolate * isolate)1228 void JSAsyncFromSyncIterator::JSAsyncFromSyncIteratorVerify(Isolate* isolate) {
1229 CHECK(IsJSAsyncFromSyncIterator());
1230 JSObjectVerify(isolate);
1231 VerifyHeapPointer(isolate, sync_iterator());
1232 }
1233
JSWeakSetVerify(Isolate * isolate)1234 void JSWeakSet::JSWeakSetVerify(Isolate* isolate) {
1235 CHECK(IsJSWeakSet());
1236 JSObjectVerify(isolate);
1237 VerifyHeapPointer(isolate, table());
1238 CHECK(table()->IsEphemeronHashTable() || table()->IsUndefined(isolate));
1239 }
1240
MicrotaskVerify(Isolate * isolate)1241 void Microtask::MicrotaskVerify(Isolate* isolate) { CHECK(IsMicrotask()); }
1242
CallableTaskVerify(Isolate * isolate)1243 void CallableTask::CallableTaskVerify(Isolate* isolate) {
1244 CHECK(IsCallableTask());
1245 MicrotaskVerify(isolate);
1246 VerifyHeapPointer(isolate, callable());
1247 CHECK(callable()->IsCallable());
1248 VerifyHeapPointer(isolate, context());
1249 CHECK(context()->IsContext());
1250 }
1251
CallbackTaskVerify(Isolate * isolate)1252 void CallbackTask::CallbackTaskVerify(Isolate* isolate) {
1253 CHECK(IsCallbackTask());
1254 MicrotaskVerify(isolate);
1255 VerifyHeapPointer(isolate, callback());
1256 VerifyHeapPointer(isolate, data());
1257 }
1258
PromiseReactionJobTaskVerify(Isolate * isolate)1259 void PromiseReactionJobTask::PromiseReactionJobTaskVerify(Isolate* isolate) {
1260 CHECK(IsPromiseReactionJobTask());
1261 MicrotaskVerify(isolate);
1262 VerifyPointer(isolate, argument());
1263 VerifyHeapPointer(isolate, context());
1264 CHECK(context()->IsContext());
1265 VerifyHeapPointer(isolate, handler());
1266 CHECK(handler()->IsUndefined(isolate) || handler()->IsCallable());
1267 VerifyHeapPointer(isolate, promise_or_capability());
1268 CHECK(promise_or_capability()->IsJSPromise() ||
1269 promise_or_capability()->IsPromiseCapability());
1270 }
1271
PromiseFulfillReactionJobTaskVerify(Isolate * isolate)1272 void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskVerify(
1273 Isolate* isolate) {
1274 CHECK(IsPromiseFulfillReactionJobTask());
1275 PromiseReactionJobTaskVerify(isolate);
1276 }
1277
PromiseRejectReactionJobTaskVerify(Isolate * isolate)1278 void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskVerify(
1279 Isolate* isolate) {
1280 CHECK(IsPromiseRejectReactionJobTask());
1281 PromiseReactionJobTaskVerify(isolate);
1282 }
1283
PromiseResolveThenableJobTaskVerify(Isolate * isolate)1284 void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskVerify(
1285 Isolate* isolate) {
1286 CHECK(IsPromiseResolveThenableJobTask());
1287 MicrotaskVerify(isolate);
1288 VerifyHeapPointer(isolate, context());
1289 CHECK(context()->IsContext());
1290 VerifyHeapPointer(isolate, promise_to_resolve());
1291 CHECK(promise_to_resolve()->IsJSPromise());
1292 VerifyHeapPointer(isolate, then());
1293 CHECK(then()->IsCallable());
1294 CHECK(then()->IsJSReceiver());
1295 VerifyHeapPointer(isolate, thenable());
1296 CHECK(thenable()->IsJSReceiver());
1297 }
1298
PromiseCapabilityVerify(Isolate * isolate)1299 void PromiseCapability::PromiseCapabilityVerify(Isolate* isolate) {
1300 CHECK(IsPromiseCapability());
1301
1302 VerifyHeapPointer(isolate, promise());
1303 CHECK(promise()->IsJSReceiver() || promise()->IsUndefined(isolate));
1304 VerifyPointer(isolate, resolve());
1305 VerifyPointer(isolate, reject());
1306 }
1307
PromiseReactionVerify(Isolate * isolate)1308 void PromiseReaction::PromiseReactionVerify(Isolate* isolate) {
1309 CHECK(IsPromiseReaction());
1310
1311 VerifyPointer(isolate, next());
1312 CHECK(next()->IsSmi() || next()->IsPromiseReaction());
1313 VerifyHeapPointer(isolate, reject_handler());
1314 CHECK(reject_handler()->IsUndefined(isolate) ||
1315 reject_handler()->IsCallable());
1316 VerifyHeapPointer(isolate, fulfill_handler());
1317 CHECK(fulfill_handler()->IsUndefined(isolate) ||
1318 fulfill_handler()->IsCallable());
1319 VerifyHeapPointer(isolate, promise_or_capability());
1320 CHECK(promise_or_capability()->IsJSPromise() ||
1321 promise_or_capability()->IsPromiseCapability());
1322 }
1323
JSPromiseVerify(Isolate * isolate)1324 void JSPromise::JSPromiseVerify(Isolate* isolate) {
1325 CHECK(IsJSPromise());
1326 JSObjectVerify(isolate);
1327 VerifyPointer(isolate, reactions_or_result());
1328 VerifySmiField(kFlagsOffset);
1329 if (status() == Promise::kPending) {
1330 CHECK(reactions()->IsSmi() || reactions()->IsPromiseReaction());
1331 }
1332 }
1333
1334 template <typename Derived>
SmallOrderedHashTableVerify(Isolate * isolate)1335 void SmallOrderedHashTable<Derived>::SmallOrderedHashTableVerify(
1336 Isolate* isolate) {
1337 CHECK(IsSmallOrderedHashTable());
1338
1339 int capacity = Capacity();
1340 CHECK_GE(capacity, kMinCapacity);
1341 CHECK_LE(capacity, kMaxCapacity);
1342
1343 for (int entry = 0; entry < NumberOfBuckets(); entry++) {
1344 int bucket = GetFirstEntry(entry);
1345 if (bucket == kNotFound) continue;
1346 CHECK_GE(bucket, 0);
1347 CHECK_LE(bucket, capacity);
1348 }
1349
1350 for (int entry = 0; entry < NumberOfElements(); entry++) {
1351 int chain = GetNextEntry(entry);
1352 if (chain == kNotFound) continue;
1353 CHECK_GE(chain, 0);
1354 CHECK_LE(chain, capacity);
1355 }
1356
1357 for (int entry = 0; entry < NumberOfElements(); entry++) {
1358 for (int offset = 0; offset < Derived::kEntrySize; offset++) {
1359 Object* val = GetDataEntry(entry, offset);
1360 VerifyPointer(isolate, val);
1361 }
1362 }
1363
1364 for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
1365 entry++) {
1366 for (int offset = 0; offset < Derived::kEntrySize; offset++) {
1367 Object* val = GetDataEntry(entry, offset);
1368 CHECK(val->IsTheHole(isolate));
1369 }
1370 }
1371
1372 for (int entry = NumberOfElements() + NumberOfDeletedElements();
1373 entry < Capacity(); entry++) {
1374 for (int offset = 0; offset < Derived::kEntrySize; offset++) {
1375 Object* val = GetDataEntry(entry, offset);
1376 CHECK(val->IsTheHole(isolate));
1377 }
1378 }
1379 }
1380
1381 template void SmallOrderedHashTable<
1382 SmallOrderedHashMap>::SmallOrderedHashTableVerify(Isolate* isolate);
1383 template void SmallOrderedHashTable<
1384 SmallOrderedHashSet>::SmallOrderedHashTableVerify(Isolate* isolate);
1385
JSRegExpVerify(Isolate * isolate)1386 void JSRegExp::JSRegExpVerify(Isolate* isolate) {
1387 JSObjectVerify(isolate);
1388 CHECK(data()->IsUndefined(isolate) || data()->IsFixedArray());
1389 switch (TypeTag()) {
1390 case JSRegExp::ATOM: {
1391 FixedArray* arr = FixedArray::cast(data());
1392 CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
1393 break;
1394 }
1395 case JSRegExp::IRREGEXP: {
1396 bool is_native = RegExpImpl::UsesNativeRegExp();
1397
1398 FixedArray* arr = FixedArray::cast(data());
1399 Object* one_byte_data = arr->get(JSRegExp::kIrregexpLatin1CodeIndex);
1400 // Smi : Not compiled yet (-1).
1401 // Code/ByteArray: Compiled code.
1402 CHECK(
1403 (one_byte_data->IsSmi() &&
1404 Smi::ToInt(one_byte_data) == JSRegExp::kUninitializedValue) ||
1405 (is_native ? one_byte_data->IsCode() : one_byte_data->IsByteArray()));
1406 Object* uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
1407 CHECK((uc16_data->IsSmi() &&
1408 Smi::ToInt(uc16_data) == JSRegExp::kUninitializedValue) ||
1409 (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
1410
1411 CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
1412 CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
1413 break;
1414 }
1415 default:
1416 CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
1417 CHECK(data()->IsUndefined(isolate));
1418 break;
1419 }
1420 }
1421
JSRegExpStringIteratorVerify(Isolate * isolate)1422 void JSRegExpStringIterator::JSRegExpStringIteratorVerify(Isolate* isolate) {
1423 CHECK(IsJSRegExpStringIterator());
1424 JSObjectVerify(isolate);
1425 CHECK(iterating_string()->IsString());
1426 CHECK(iterating_regexp()->IsObject());
1427 VerifySmiField(kFlagsOffset);
1428 }
1429
JSProxyVerify(Isolate * isolate)1430 void JSProxy::JSProxyVerify(Isolate* isolate) {
1431 CHECK(IsJSProxy());
1432 CHECK(map()->GetConstructor()->IsJSFunction());
1433 VerifyPointer(isolate, target());
1434 VerifyPointer(isolate, handler());
1435 if (!IsRevoked()) {
1436 CHECK_EQ(target()->IsCallable(), map()->is_callable());
1437 CHECK_EQ(target()->IsConstructor(), map()->is_constructor());
1438 }
1439 CHECK(map()->prototype()->IsNull(isolate));
1440 // There should be no properties on a Proxy.
1441 CHECK_EQ(0, map()->NumberOfOwnDescriptors());
1442 }
1443
JSArrayBufferVerify(Isolate * isolate)1444 void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) {
1445 CHECK(IsJSArrayBuffer());
1446 JSObjectVerify(isolate);
1447 VerifyPointer(isolate, byte_length());
1448 CHECK(byte_length()->IsSmi() || byte_length()->IsHeapNumber() ||
1449 byte_length()->IsUndefined(isolate));
1450 }
1451
JSArrayBufferViewVerify(Isolate * isolate)1452 void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) {
1453 CHECK(IsJSArrayBufferView());
1454 JSObjectVerify(isolate);
1455 VerifyPointer(isolate, buffer());
1456 CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined(isolate) ||
1457 buffer() == Smi::kZero);
1458
1459 VerifyPointer(isolate, raw_byte_offset());
1460 CHECK(raw_byte_offset()->IsSmi() || raw_byte_offset()->IsHeapNumber() ||
1461 raw_byte_offset()->IsUndefined(isolate));
1462
1463 VerifyPointer(isolate, raw_byte_length());
1464 CHECK(raw_byte_length()->IsSmi() || raw_byte_length()->IsHeapNumber() ||
1465 raw_byte_length()->IsUndefined(isolate));
1466 }
1467
JSTypedArrayVerify(Isolate * isolate)1468 void JSTypedArray::JSTypedArrayVerify(Isolate* isolate) {
1469 CHECK(IsJSTypedArray());
1470 JSArrayBufferViewVerify(isolate);
1471 VerifyPointer(isolate, raw_length());
1472 CHECK(raw_length()->IsSmi() || raw_length()->IsUndefined(isolate));
1473 VerifyPointer(isolate, elements());
1474 }
1475
JSDataViewVerify(Isolate * isolate)1476 void JSDataView::JSDataViewVerify(Isolate* isolate) {
1477 CHECK(IsJSDataView());
1478 JSArrayBufferViewVerify(isolate);
1479 }
1480
ForeignVerify(Isolate * isolate)1481 void Foreign::ForeignVerify(Isolate* isolate) { CHECK(IsForeign()); }
1482
AsyncGeneratorRequestVerify(Isolate * isolate)1483 void AsyncGeneratorRequest::AsyncGeneratorRequestVerify(Isolate* isolate) {
1484 CHECK(IsAsyncGeneratorRequest());
1485 VerifySmiField(kResumeModeOffset);
1486 CHECK_GE(resume_mode(), JSGeneratorObject::kNext);
1487 CHECK_LE(resume_mode(), JSGeneratorObject::kThrow);
1488 CHECK(promise()->IsJSPromise());
1489 VerifyPointer(isolate, value());
1490 VerifyPointer(isolate, next());
1491 next()->ObjectVerify(isolate);
1492 }
1493
BigIntVerify(Isolate * isolate)1494 void BigInt::BigIntVerify(Isolate* isolate) {
1495 CHECK(IsBigInt());
1496 CHECK_GE(length(), 0);
1497 CHECK_IMPLIES(is_zero(), !sign()); // There is no -0n.
1498 }
1499
JSModuleNamespaceVerify(Isolate * isolate)1500 void JSModuleNamespace::JSModuleNamespaceVerify(Isolate* isolate) {
1501 CHECK(IsJSModuleNamespace());
1502 VerifyPointer(isolate, module());
1503 }
1504
ModuleInfoEntryVerify(Isolate * isolate)1505 void ModuleInfoEntry::ModuleInfoEntryVerify(Isolate* isolate) {
1506 CHECK(IsModuleInfoEntry());
1507
1508 CHECK(export_name()->IsUndefined(isolate) || export_name()->IsString());
1509 CHECK(local_name()->IsUndefined(isolate) || local_name()->IsString());
1510 CHECK(import_name()->IsUndefined(isolate) || import_name()->IsString());
1511
1512 VerifySmiField(kModuleRequestOffset);
1513 VerifySmiField(kCellIndexOffset);
1514 VerifySmiField(kBegPosOffset);
1515 VerifySmiField(kEndPosOffset);
1516
1517 CHECK_IMPLIES(import_name()->IsString(), module_request() >= 0);
1518 CHECK_IMPLIES(export_name()->IsString() && import_name()->IsString(),
1519 local_name()->IsUndefined(isolate));
1520 }
1521
ModuleVerify(Isolate * isolate)1522 void Module::ModuleVerify(Isolate* isolate) {
1523 CHECK(IsModule());
1524
1525 VerifyPointer(isolate, code());
1526 VerifyPointer(isolate, exports());
1527 VerifyPointer(isolate, module_namespace());
1528 VerifyPointer(isolate, requested_modules());
1529 VerifyPointer(isolate, script());
1530 VerifyPointer(isolate, import_meta());
1531 VerifyPointer(isolate, exception());
1532 VerifySmiField(kHashOffset);
1533 VerifySmiField(kStatusOffset);
1534
1535 CHECK((status() >= kEvaluating && code()->IsModuleInfo()) ||
1536 (status() == kInstantiated && code()->IsJSGeneratorObject()) ||
1537 (status() == kInstantiating && code()->IsJSFunction()) ||
1538 (code()->IsSharedFunctionInfo()));
1539
1540 CHECK_EQ(status() == kErrored, !exception()->IsTheHole(isolate));
1541
1542 CHECK(module_namespace()->IsUndefined(isolate) ||
1543 module_namespace()->IsJSModuleNamespace());
1544 if (module_namespace()->IsJSModuleNamespace()) {
1545 CHECK_LE(kInstantiating, status());
1546 CHECK_EQ(JSModuleNamespace::cast(module_namespace())->module(), this);
1547 }
1548
1549 CHECK_EQ(requested_modules()->length(), info()->module_requests()->length());
1550
1551 CHECK(import_meta()->IsTheHole(isolate) || import_meta()->IsJSObject());
1552
1553 CHECK_NE(hash(), 0);
1554 }
1555
PrototypeInfoVerify(Isolate * isolate)1556 void PrototypeInfo::PrototypeInfoVerify(Isolate* isolate) {
1557 CHECK(IsPrototypeInfo());
1558 Object* module_ns = module_namespace();
1559 CHECK(module_ns->IsJSModuleNamespace() || module_ns->IsUndefined(isolate));
1560 if (prototype_users()->IsWeakArrayList()) {
1561 PrototypeUsers::Verify(WeakArrayList::cast(prototype_users()));
1562 } else {
1563 CHECK(prototype_users()->IsSmi());
1564 }
1565 }
1566
Verify(WeakArrayList * array)1567 void PrototypeUsers::Verify(WeakArrayList* array) {
1568 if (array->length() == 0) {
1569 // Allow empty & uninitialized lists.
1570 return;
1571 }
1572 // Verify empty slot chain.
1573 int empty_slot = Smi::ToInt(empty_slot_index(array));
1574 int empty_slots_count = 0;
1575 while (empty_slot != kNoEmptySlotsMarker) {
1576 CHECK_GT(empty_slot, 0);
1577 CHECK_LT(empty_slot, array->length());
1578 empty_slot = Smi::ToInt(array->Get(empty_slot)->ToSmi());
1579 ++empty_slots_count;
1580 }
1581
1582 // Verify that all elements are either weak pointers or SMIs marking empty
1583 // slots.
1584 int weak_maps_count = 0;
1585 for (int i = kFirstIndex; i < array->length(); ++i) {
1586 HeapObject* heap_object;
1587 MaybeObject* object = array->Get(i);
1588 if ((object->ToWeakHeapObject(&heap_object) && heap_object->IsMap()) ||
1589 object->IsClearedWeakHeapObject()) {
1590 ++weak_maps_count;
1591 } else {
1592 CHECK(object->IsSmi());
1593 }
1594 }
1595
1596 CHECK_EQ(weak_maps_count + empty_slots_count + 1, array->length());
1597 }
1598
Tuple2Verify(Isolate * isolate)1599 void Tuple2::Tuple2Verify(Isolate* isolate) {
1600 CHECK(IsTuple2());
1601 Heap* heap = isolate->heap();
1602 if (this == ReadOnlyRoots(heap).empty_enum_cache()) {
1603 CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(),
1604 EnumCache::cast(this)->keys());
1605 CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(),
1606 EnumCache::cast(this)->indices());
1607 } else {
1608 VerifyObjectField(isolate, kValue1Offset);
1609 VerifyObjectField(isolate, kValue2Offset);
1610 }
1611 }
1612
Tuple3Verify(Isolate * isolate)1613 void Tuple3::Tuple3Verify(Isolate* isolate) {
1614 CHECK(IsTuple3());
1615 VerifyObjectField(isolate, kValue1Offset);
1616 VerifyObjectField(isolate, kValue2Offset);
1617 VerifyObjectField(isolate, kValue3Offset);
1618 }
1619
ObjectBoilerplateDescriptionVerify(Isolate * isolate)1620 void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionVerify(
1621 Isolate* isolate) {
1622 CHECK(IsObjectBoilerplateDescription());
1623 CHECK_GE(this->length(),
1624 ObjectBoilerplateDescription::kDescriptionStartIndex);
1625 this->FixedArrayVerify(isolate);
1626 }
1627
ArrayBoilerplateDescriptionVerify(Isolate * isolate)1628 void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionVerify(
1629 Isolate* isolate) {
1630 CHECK(IsArrayBoilerplateDescription());
1631 CHECK(constant_elements()->IsFixedArrayBase());
1632 VerifyObjectField(isolate, kConstantElementsOffset);
1633 }
1634
WasmDebugInfoVerify(Isolate * isolate)1635 void WasmDebugInfo::WasmDebugInfoVerify(Isolate* isolate) {
1636 CHECK(IsWasmDebugInfo());
1637 VerifyObjectField(isolate, kInstanceOffset);
1638 CHECK(wasm_instance()->IsWasmInstanceObject());
1639 VerifyObjectField(isolate, kInterpreterHandleOffset);
1640 CHECK(interpreter_handle()->IsUndefined(isolate) ||
1641 interpreter_handle()->IsForeign());
1642 VerifyObjectField(isolate, kInterpretedFunctionsOffset);
1643 VerifyObjectField(isolate, kLocalsNamesOffset);
1644 VerifyObjectField(isolate, kCWasmEntriesOffset);
1645 VerifyObjectField(isolate, kCWasmEntryMapOffset);
1646 }
1647
WasmInstanceObjectVerify(Isolate * isolate)1648 void WasmInstanceObject::WasmInstanceObjectVerify(Isolate* isolate) {
1649 JSObjectVerify(isolate);
1650 CHECK(IsWasmInstanceObject());
1651
1652 // Just generically check all tagged fields. Don't check the untagged fields,
1653 // as some of them might still contain the "undefined" value if the
1654 // WasmInstanceObject is not fully set up yet.
1655 for (int offset = kHeaderSize; offset < kFirstUntaggedOffset;
1656 offset += kPointerSize) {
1657 VerifyObjectField(isolate, offset);
1658 }
1659 }
1660
WasmExportedFunctionDataVerify(Isolate * isolate)1661 void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
1662 Isolate* isolate) {
1663 CHECK(IsWasmExportedFunctionData());
1664 VerifyObjectField(isolate, kWrapperCodeOffset);
1665 CHECK(wrapper_code()->kind() == Code::JS_TO_WASM_FUNCTION ||
1666 wrapper_code()->kind() == Code::C_WASM_ENTRY);
1667 VerifyObjectField(isolate, kInstanceOffset);
1668 VerifySmiField(kJumpTableOffsetOffset);
1669 VerifySmiField(kFunctionIndexOffset);
1670 }
1671
WasmModuleObjectVerify(Isolate * isolate)1672 void WasmModuleObject::WasmModuleObjectVerify(Isolate* isolate) {
1673 CHECK(IsWasmModuleObject());
1674 VerifyObjectField(isolate, kNativeModuleOffset);
1675 CHECK(managed_native_module()->IsForeign());
1676 VerifyObjectField(isolate, kExportWrappersOffset);
1677 CHECK(export_wrappers()->IsFixedArray());
1678 VerifyObjectField(isolate, kScriptOffset);
1679 VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
1680 VerifyObjectField(isolate, kBreakPointInfosOffset);
1681 }
1682
DataHandlerVerify(Isolate * isolate)1683 void DataHandler::DataHandlerVerify(Isolate* isolate) {
1684 CHECK(IsDataHandler());
1685 CHECK_IMPLIES(!smi_handler()->IsSmi(),
1686 smi_handler()->IsCode() && IsStoreHandler());
1687 CHECK(validity_cell()->IsSmi() || validity_cell()->IsCell());
1688 int data_count = data_field_count();
1689 if (data_count >= 1) {
1690 VerifyMaybeObjectField(isolate, kData1Offset);
1691 }
1692 if (data_count >= 2) {
1693 VerifyMaybeObjectField(isolate, kData2Offset);
1694 }
1695 if (data_count >= 3) {
1696 VerifyMaybeObjectField(isolate, kData3Offset);
1697 }
1698 }
1699
LoadHandlerVerify(Isolate * isolate)1700 void LoadHandler::LoadHandlerVerify(Isolate* isolate) {
1701 DataHandler::DataHandlerVerify(isolate);
1702 // TODO(ishell): check handler integrity
1703 }
1704
StoreHandlerVerify(Isolate * isolate)1705 void StoreHandler::StoreHandlerVerify(Isolate* isolate) {
1706 DataHandler::DataHandlerVerify(isolate);
1707 // TODO(ishell): check handler integrity
1708 }
1709
AccessorInfoVerify(Isolate * isolate)1710 void AccessorInfo::AccessorInfoVerify(Isolate* isolate) {
1711 CHECK(IsAccessorInfo());
1712 VerifyPointer(isolate, name());
1713 VerifyPointer(isolate, expected_receiver_type());
1714 VerifyForeignPointer(isolate, this, getter());
1715 VerifyForeignPointer(isolate, this, setter());
1716 VerifyForeignPointer(isolate, this, js_getter());
1717 VerifyPointer(isolate, data());
1718 }
1719
AccessorPairVerify(Isolate * isolate)1720 void AccessorPair::AccessorPairVerify(Isolate* isolate) {
1721 CHECK(IsAccessorPair());
1722 VerifyPointer(isolate, getter());
1723 VerifyPointer(isolate, setter());
1724 }
1725
AccessCheckInfoVerify(Isolate * isolate)1726 void AccessCheckInfo::AccessCheckInfoVerify(Isolate* isolate) {
1727 CHECK(IsAccessCheckInfo());
1728 VerifyPointer(isolate, callback());
1729 VerifyPointer(isolate, named_interceptor());
1730 VerifyPointer(isolate, indexed_interceptor());
1731 VerifyPointer(isolate, data());
1732 }
1733
CallHandlerInfoVerify(Isolate * isolate)1734 void CallHandlerInfo::CallHandlerInfoVerify(Isolate* isolate) {
1735 CHECK(IsCallHandlerInfo());
1736 CHECK(map() == ReadOnlyRoots(isolate).side_effect_call_handler_info_map() ||
1737 map() ==
1738 ReadOnlyRoots(isolate).side_effect_free_call_handler_info_map() ||
1739 map() == ReadOnlyRoots(isolate)
1740 .next_call_side_effect_free_call_handler_info_map());
1741 VerifyPointer(isolate, callback());
1742 VerifyPointer(isolate, js_callback());
1743 VerifyPointer(isolate, data());
1744 }
1745
InterceptorInfoVerify(Isolate * isolate)1746 void InterceptorInfo::InterceptorInfoVerify(Isolate* isolate) {
1747 CHECK(IsInterceptorInfo());
1748 VerifyForeignPointer(isolate, this, getter());
1749 VerifyForeignPointer(isolate, this, setter());
1750 VerifyForeignPointer(isolate, this, query());
1751 VerifyForeignPointer(isolate, this, deleter());
1752 VerifyForeignPointer(isolate, this, enumerator());
1753 VerifyPointer(isolate, data());
1754 VerifySmiField(kFlagsOffset);
1755 }
1756
TemplateInfoVerify(Isolate * isolate)1757 void TemplateInfo::TemplateInfoVerify(Isolate* isolate) {
1758 VerifyPointer(isolate, tag());
1759 VerifyPointer(isolate, property_list());
1760 VerifyPointer(isolate, property_accessors());
1761 }
1762
FunctionTemplateInfoVerify(Isolate * isolate)1763 void FunctionTemplateInfo::FunctionTemplateInfoVerify(Isolate* isolate) {
1764 CHECK(IsFunctionTemplateInfo());
1765 TemplateInfoVerify(isolate);
1766 VerifyPointer(isolate, serial_number());
1767 VerifyPointer(isolate, call_code());
1768 VerifyPointer(isolate, prototype_template());
1769 VerifyPointer(isolate, parent_template());
1770 VerifyPointer(isolate, named_property_handler());
1771 VerifyPointer(isolate, indexed_property_handler());
1772 VerifyPointer(isolate, instance_template());
1773 VerifyPointer(isolate, signature());
1774 VerifyPointer(isolate, access_check_info());
1775 VerifyPointer(isolate, cached_property_name());
1776 }
1777
ObjectTemplateInfoVerify(Isolate * isolate)1778 void ObjectTemplateInfo::ObjectTemplateInfoVerify(Isolate* isolate) {
1779 CHECK(IsObjectTemplateInfo());
1780 TemplateInfoVerify(isolate);
1781 VerifyPointer(isolate, constructor());
1782 VerifyPointer(isolate, data());
1783 }
1784
AllocationSiteVerify(Isolate * isolate)1785 void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
1786 CHECK(IsAllocationSite());
1787 }
1788
AllocationMementoVerify(Isolate * isolate)1789 void AllocationMemento::AllocationMementoVerify(Isolate* isolate) {
1790 CHECK(IsAllocationMemento());
1791 VerifyHeapPointer(isolate, allocation_site());
1792 CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
1793 }
1794
ScriptVerify(Isolate * isolate)1795 void Script::ScriptVerify(Isolate* isolate) {
1796 CHECK(IsScript());
1797 VerifyPointer(isolate, source());
1798 VerifyPointer(isolate, name());
1799 VerifyPointer(isolate, line_ends());
1800 for (int i = 0; i < shared_function_infos()->length(); ++i) {
1801 MaybeObject* maybe_object = shared_function_infos()->Get(i);
1802 HeapObject* heap_object;
1803 CHECK(maybe_object->IsWeakHeapObject() ||
1804 maybe_object->IsClearedWeakHeapObject() ||
1805 (maybe_object->ToStrongHeapObject(&heap_object) &&
1806 heap_object->IsUndefined(isolate)));
1807 }
1808 }
1809
NormalizedMapCacheVerify(Isolate * isolate)1810 void NormalizedMapCache::NormalizedMapCacheVerify(Isolate* isolate) {
1811 WeakFixedArray::cast(this)->WeakFixedArrayVerify(isolate);
1812 if (FLAG_enable_slow_asserts) {
1813 for (int i = 0; i < length(); i++) {
1814 MaybeObject* e = WeakFixedArray::Get(i);
1815 HeapObject* heap_object;
1816 if (e->ToWeakHeapObject(&heap_object)) {
1817 Map::cast(heap_object)->DictionaryMapVerify(isolate);
1818 } else {
1819 CHECK(e->IsClearedWeakHeapObject() ||
1820 (e->ToStrongHeapObject(&heap_object) &&
1821 heap_object->IsUndefined(isolate)));
1822 }
1823 }
1824 }
1825 }
1826
DebugInfoVerify(Isolate * isolate)1827 void DebugInfo::DebugInfoVerify(Isolate* isolate) {
1828 CHECK(IsDebugInfo());
1829 VerifyPointer(isolate, shared());
1830 VerifyPointer(isolate, script());
1831 VerifyPointer(isolate, original_bytecode_array());
1832 VerifyPointer(isolate, break_points());
1833 }
1834
StackFrameInfoVerify(Isolate * isolate)1835 void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) {
1836 CHECK(IsStackFrameInfo());
1837 VerifyPointer(isolate, script_name());
1838 VerifyPointer(isolate, script_name_or_source_url());
1839 VerifyPointer(isolate, function_name());
1840 }
1841
PreParsedScopeDataVerify(Isolate * isolate)1842 void PreParsedScopeData::PreParsedScopeDataVerify(Isolate* isolate) {
1843 CHECK(IsPreParsedScopeData());
1844 CHECK(scope_data()->IsByteArray());
1845 CHECK_GE(length(), 0);
1846
1847 for (int i = 0; i < length(); ++i) {
1848 Object* child = child_data(i);
1849 CHECK(child->IsPreParsedScopeData() || child->IsNull());
1850 VerifyPointer(isolate, child);
1851 }
1852 }
1853
UncompiledDataWithPreParsedScopeVerify(Isolate * isolate)1854 void UncompiledDataWithPreParsedScope::UncompiledDataWithPreParsedScopeVerify(
1855 Isolate* isolate) {
1856 CHECK(IsUncompiledDataWithPreParsedScope());
1857 VerifyPointer(isolate, inferred_name());
1858 VerifyPointer(isolate, pre_parsed_scope_data());
1859 }
1860
1861 void UncompiledDataWithoutPreParsedScope::
UncompiledDataWithoutPreParsedScopeVerify(Isolate * isolate)1862 UncompiledDataWithoutPreParsedScopeVerify(Isolate* isolate) {
1863 CHECK(IsUncompiledDataWithoutPreParsedScope());
1864 VerifyPointer(isolate, inferred_name());
1865 }
1866
InterpreterDataVerify(Isolate * isolate)1867 void InterpreterData::InterpreterDataVerify(Isolate* isolate) {
1868 CHECK(IsInterpreterData());
1869 CHECK(bytecode_array()->IsBytecodeArray());
1870 CHECK(interpreter_trampoline()->IsCode());
1871 }
1872
1873 #ifdef V8_INTL_SUPPORT
JSCollatorVerify(Isolate * isolate)1874 void JSCollator::JSCollatorVerify(Isolate* isolate) {
1875 CHECK(IsJSCollator());
1876 JSObjectVerify(isolate);
1877 VerifyObjectField(isolate, kICUCollatorOffset);
1878 VerifyObjectField(isolate, kFlagsOffset);
1879 VerifyObjectField(isolate, kBoundCompareOffset);
1880 }
1881
JSListFormatVerify(Isolate * isolate)1882 void JSListFormat::JSListFormatVerify(Isolate* isolate) {
1883 JSObjectVerify(isolate);
1884 VerifyObjectField(isolate, kLocaleOffset);
1885 VerifyObjectField(isolate, kFormatterOffset);
1886 VerifyObjectField(isolate, kFlagsOffset);
1887 }
1888
JSLocaleVerify(Isolate * isolate)1889 void JSLocale::JSLocaleVerify(Isolate* isolate) {
1890 JSObjectVerify(isolate);
1891 VerifyObjectField(isolate, kLanguageOffset);
1892 VerifyObjectField(isolate, kScriptOffset);
1893 VerifyObjectField(isolate, kRegionOffset);
1894 VerifyObjectField(isolate, kBaseNameOffset);
1895 VerifyObjectField(isolate, kLocaleOffset);
1896 // Unicode extension fields.
1897 VerifyObjectField(isolate, kCalendarOffset);
1898 VerifyObjectField(isolate, kCaseFirstOffset);
1899 VerifyObjectField(isolate, kCollationOffset);
1900 VerifyObjectField(isolate, kHourCycleOffset);
1901 VerifyObjectField(isolate, kNumericOffset);
1902 VerifyObjectField(isolate, kNumberingSystemOffset);
1903 }
1904
JSPluralRulesVerify(Isolate * isolate)1905 void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
1906 CHECK(IsJSPluralRules());
1907 JSObjectVerify(isolate);
1908 VerifyObjectField(isolate, kLocaleOffset);
1909 VerifyObjectField(isolate, kTypeOffset);
1910 VerifyObjectField(isolate, kICUPluralRulesOffset);
1911 VerifyObjectField(isolate, kICUDecimalFormatOffset);
1912 }
1913
JSRelativeTimeFormatVerify(Isolate * isolate)1914 void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
1915 JSObjectVerify(isolate);
1916 VerifyObjectField(isolate, kLocaleOffset);
1917 VerifyObjectField(isolate, kFormatterOffset);
1918 VerifyObjectField(isolate, kFlagsOffset);
1919 }
1920 #endif // V8_INTL_SUPPORT
1921
1922 #endif // VERIFY_HEAP
1923
1924 #ifdef DEBUG
1925
IncrementSpillStatistics(Isolate * isolate,SpillInformation * info)1926 void JSObject::IncrementSpillStatistics(Isolate* isolate,
1927 SpillInformation* info) {
1928 info->number_of_objects_++;
1929 // Named properties
1930 if (HasFastProperties()) {
1931 info->number_of_objects_with_fast_properties_++;
1932 info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
1933 info->number_of_fast_unused_fields_ += map()->UnusedPropertyFields();
1934 } else if (IsJSGlobalObject()) {
1935 GlobalDictionary* dict = JSGlobalObject::cast(this)->global_dictionary();
1936 info->number_of_slow_used_properties_ += dict->NumberOfElements();
1937 info->number_of_slow_unused_properties_ +=
1938 dict->Capacity() - dict->NumberOfElements();
1939 } else {
1940 NameDictionary* dict = property_dictionary();
1941 info->number_of_slow_used_properties_ += dict->NumberOfElements();
1942 info->number_of_slow_unused_properties_ +=
1943 dict->Capacity() - dict->NumberOfElements();
1944 }
1945 // Indexed properties
1946 switch (GetElementsKind()) {
1947 case HOLEY_SMI_ELEMENTS:
1948 case PACKED_SMI_ELEMENTS:
1949 case HOLEY_DOUBLE_ELEMENTS:
1950 case PACKED_DOUBLE_ELEMENTS:
1951 case HOLEY_ELEMENTS:
1952 case PACKED_ELEMENTS:
1953 case FAST_STRING_WRAPPER_ELEMENTS: {
1954 info->number_of_objects_with_fast_elements_++;
1955 int holes = 0;
1956 FixedArray* e = FixedArray::cast(elements());
1957 int len = e->length();
1958 for (int i = 0; i < len; i++) {
1959 if (e->get(i)->IsTheHole(isolate)) holes++;
1960 }
1961 info->number_of_fast_used_elements_ += len - holes;
1962 info->number_of_fast_unused_elements_ += holes;
1963 break;
1964 }
1965
1966 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
1967
1968 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1969 #undef TYPED_ARRAY_CASE
1970 {
1971 info->number_of_objects_with_fast_elements_++;
1972 FixedArrayBase* e = FixedArrayBase::cast(elements());
1973 info->number_of_fast_used_elements_ += e->length();
1974 break;
1975 }
1976 case DICTIONARY_ELEMENTS:
1977 case SLOW_STRING_WRAPPER_ELEMENTS: {
1978 NumberDictionary* dict = element_dictionary();
1979 info->number_of_slow_used_elements_ += dict->NumberOfElements();
1980 info->number_of_slow_unused_elements_ +=
1981 dict->Capacity() - dict->NumberOfElements();
1982 break;
1983 }
1984 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1985 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1986 case NO_ELEMENTS:
1987 break;
1988 }
1989 }
1990
1991
Clear()1992 void JSObject::SpillInformation::Clear() {
1993 number_of_objects_ = 0;
1994 number_of_objects_with_fast_properties_ = 0;
1995 number_of_objects_with_fast_elements_ = 0;
1996 number_of_fast_used_fields_ = 0;
1997 number_of_fast_unused_fields_ = 0;
1998 number_of_slow_used_properties_ = 0;
1999 number_of_slow_unused_properties_ = 0;
2000 number_of_fast_used_elements_ = 0;
2001 number_of_fast_unused_elements_ = 0;
2002 number_of_slow_used_elements_ = 0;
2003 number_of_slow_unused_elements_ = 0;
2004 }
2005
2006
Print()2007 void JSObject::SpillInformation::Print() {
2008 PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
2009
2010 PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
2011 number_of_objects_with_fast_properties_,
2012 number_of_fast_used_fields_, number_of_fast_unused_fields_);
2013
2014 PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
2015 number_of_objects_ - number_of_objects_with_fast_properties_,
2016 number_of_slow_used_properties_, number_of_slow_unused_properties_);
2017
2018 PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
2019 number_of_objects_with_fast_elements_,
2020 number_of_fast_used_elements_, number_of_fast_unused_elements_);
2021
2022 PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
2023 number_of_objects_ - number_of_objects_with_fast_elements_,
2024 number_of_slow_used_elements_, number_of_slow_unused_elements_);
2025
2026 PrintF("\n");
2027 }
2028
IsSortedNoDuplicates(int valid_entries)2029 bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
2030 if (valid_entries == -1) valid_entries = number_of_descriptors();
2031 Name* current_key = nullptr;
2032 uint32_t current = 0;
2033 for (int i = 0; i < number_of_descriptors(); i++) {
2034 Name* key = GetSortedKey(i);
2035 if (key == current_key) {
2036 Print();
2037 return false;
2038 }
2039 current_key = key;
2040 uint32_t hash = GetSortedKey(i)->Hash();
2041 if (hash < current) {
2042 Print();
2043 return false;
2044 }
2045 current = hash;
2046 }
2047 return true;
2048 }
2049
IsSortedNoDuplicates(int valid_entries)2050 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
2051 DCHECK_EQ(valid_entries, -1);
2052 Name* prev_key = nullptr;
2053 PropertyKind prev_kind = kData;
2054 PropertyAttributes prev_attributes = NONE;
2055 uint32_t prev_hash = 0;
2056
2057 for (int i = 0; i < number_of_transitions(); i++) {
2058 Name* key = GetSortedKey(i);
2059 uint32_t hash = key->Hash();
2060 PropertyKind kind = kData;
2061 PropertyAttributes attributes = NONE;
2062 if (!TransitionsAccessor::IsSpecialTransition(key->GetReadOnlyRoots(),
2063 key)) {
2064 Map* target = GetTarget(i);
2065 PropertyDetails details =
2066 TransitionsAccessor::GetTargetDetails(key, target);
2067 kind = details.kind();
2068 attributes = details.attributes();
2069 } else {
2070 // Duplicate entries are not allowed for non-property transitions.
2071 DCHECK_NE(prev_key, key);
2072 }
2073
2074 int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
2075 hash, kind, attributes);
2076 if (cmp >= 0) {
2077 Print();
2078 return false;
2079 }
2080 prev_key = key;
2081 prev_hash = hash;
2082 prev_attributes = attributes;
2083 prev_kind = kind;
2084 }
2085 return true;
2086 }
2087
IsSortedNoDuplicates()2088 bool TransitionsAccessor::IsSortedNoDuplicates() {
2089 // Simple and non-existent transitions are always sorted.
2090 if (encoding() != kFullTransitionArray) return true;
2091 return transitions()->IsSortedNoDuplicates();
2092 }
2093
2094
CheckOneBackPointer(Map * current_map,Object * target)2095 static bool CheckOneBackPointer(Map* current_map, Object* target) {
2096 return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
2097 }
2098
IsConsistentWithBackPointers()2099 bool TransitionsAccessor::IsConsistentWithBackPointers() {
2100 int num_transitions = NumberOfTransitions();
2101 for (int i = 0; i < num_transitions; i++) {
2102 Map* target = GetTarget(i);
2103 if (!CheckOneBackPointer(map_, target)) return false;
2104 }
2105 return true;
2106 }
2107
2108 // Estimates if there is a path from the object to a context.
2109 // This function is not precise, and can return false even if
2110 // there is a path to a context.
CanLeak(Object * obj,Heap * heap)2111 bool CanLeak(Object* obj, Heap* heap) {
2112 if (!obj->IsHeapObject()) return false;
2113 if (obj->IsCell()) {
2114 return CanLeak(Cell::cast(obj)->value(), heap);
2115 }
2116 if (obj->IsPropertyCell()) {
2117 return CanLeak(PropertyCell::cast(obj)->value(), heap);
2118 }
2119 if (obj->IsContext()) return true;
2120 if (obj->IsMap()) {
2121 Map* map = Map::cast(obj);
2122 for (int i = 0; i < Heap::kStrongRootListLength; i++) {
2123 Heap::RootListIndex root_index = static_cast<Heap::RootListIndex>(i);
2124 if (map == heap->root(root_index)) return false;
2125 }
2126 return true;
2127 }
2128 return CanLeak(HeapObject::cast(obj)->map(), heap);
2129 }
2130
VerifyEmbeddedObjects(Isolate * isolate,VerifyMode mode)2131 void Code::VerifyEmbeddedObjects(Isolate* isolate, VerifyMode mode) {
2132 if (kind() == OPTIMIZED_FUNCTION) return;
2133 Heap* heap = isolate->heap();
2134 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
2135 for (RelocIterator it(this, mask); !it.done(); it.next()) {
2136 Object* target = it.rinfo()->target_object();
2137 DCHECK(!CanLeak(target, heap));
2138 }
2139 }
2140
2141 #endif // DEBUG
2142
2143 } // namespace internal
2144 } // namespace v8
2145