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