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