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()->is_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 : CHECK_EQ(*this == ReadOnlyRoots(isolate).empty_string(),
1023 : map() == ReadOnlyRoots(isolate).empty_string_map());
1024 : if (IsInternalizedString()) {
1025 : CHECK(!ObjectInYoungGeneration(*this));
1026 : }
1027 : if (IsConsString()) {
1028 : ConsString::cast(*this)->ConsStringVerify(isolate);
1029 : } else if (IsSlicedString()) {
1030 : SlicedString::cast(*this)->SlicedStringVerify(isolate);
1031 : } else if (IsThinString()) {
1032 : ThinString::cast(*this)->ThinStringVerify(isolate);
1033 : }
1034 : }
1035 :
1036 : void ConsString::ConsStringVerify(Isolate* isolate) {
1037 : CHECK(this->first()->IsString());
1038 : CHECK(this->second()->IsString());
1039 : CHECK_GT(this->first()->length(), 0);
1040 : CHECK_GE(this->length(), ConsString::kMinLength);
1041 : CHECK(this->length() == this->first()->length() + this->second()->length());
1042 : if (this->IsFlat()) {
1043 : // A flat cons can only be created by String::SlowFlatten.
1044 : // Afterwards, the first part may be externalized or internalized.
1045 : CHECK(this->first()->IsSeqString() || this->first()->IsExternalString() ||
1046 : this->first()->IsThinString());
1047 : }
1048 : }
1049 :
1050 : void ThinString::ThinStringVerify(Isolate* isolate) {
1051 : CHECK(this->actual()->IsInternalizedString());
1052 : CHECK(this->actual()->IsSeqString() || this->actual()->IsExternalString());
1053 : }
1054 :
1055 : void SlicedString::SlicedStringVerify(Isolate* isolate) {
1056 : CHECK(!this->parent()->IsConsString());
1057 : CHECK(!this->parent()->IsSlicedString());
1058 : CHECK_GE(this->length(), SlicedString::kMinLength);
1059 : }
1060 :
1061 : void JSBoundFunction::JSBoundFunctionVerify(Isolate* isolate) {
1062 : CHECK(IsJSBoundFunction());
1063 : JSObjectVerify(isolate);
1064 : VerifyObjectField(isolate, kBoundThisOffset);
1065 : VerifyObjectField(isolate, kBoundTargetFunctionOffset);
1066 : VerifyObjectField(isolate, kBoundArgumentsOffset);
1067 : CHECK(IsCallable());
1068 :
1069 : if (!raw_bound_target_function()->IsUndefined(isolate)) {
1070 : CHECK(bound_target_function()->IsCallable());
1071 : CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
1072 : }
1073 : }
1074 :
1075 : void JSFunction::JSFunctionVerify(Isolate* isolate) {
1076 : CHECK(IsJSFunction());
1077 : JSObjectVerify(isolate);
1078 : VerifyHeapPointer(isolate, raw_feedback_cell());
1079 : CHECK(raw_feedback_cell()->IsFeedbackCell());
1080 : CHECK(code()->IsCode());
1081 : CHECK(map()->is_callable());
1082 : Handle<JSFunction> function(*this, isolate);
1083 : LookupIterator it(isolate, function, isolate->factory()->prototype_string(),
1084 : LookupIterator::OWN_SKIP_INTERCEPTOR);
1085 : if (has_prototype_slot()) {
1086 : VerifyObjectField(isolate, kPrototypeOrInitialMapOffset);
1087 : }
1088 :
1089 : if (has_prototype_property()) {
1090 : CHECK(it.IsFound());
1091 : CHECK_EQ(LookupIterator::ACCESSOR, it.state());
1092 : CHECK(it.GetAccessors()->IsAccessorInfo());
1093 : } else {
1094 : CHECK(!it.IsFound() || it.state() != LookupIterator::ACCESSOR ||
1095 : !it.GetAccessors()->IsAccessorInfo());
1096 : }
1097 : }
1098 :
1099 : void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) {
1100 : CHECK(IsSharedFunctionInfo());
1101 :
1102 : VerifyObjectField(isolate, kFunctionDataOffset);
1103 : VerifyObjectField(isolate, kOuterScopeInfoOrFeedbackMetadataOffset);
1104 : VerifyObjectField(isolate, kScriptOrDebugInfoOffset);
1105 : VerifyObjectField(isolate, kNameOrScopeInfoOffset);
1106 :
1107 : Object value = name_or_scope_info();
1108 : CHECK(value == kNoSharedNameSentinel || value->IsString() ||
1109 : value->IsScopeInfo());
1110 : if (value->IsScopeInfo()) {
1111 : CHECK_LT(0, ScopeInfo::cast(value)->length());
1112 : CHECK_NE(value, ReadOnlyRoots(isolate).empty_scope_info());
1113 : }
1114 :
1115 : CHECK(HasWasmExportedFunctionData() || IsApiFunction() ||
1116 : HasBytecodeArray() || HasAsmWasmData() || HasBuiltinId() ||
1117 : HasUncompiledDataWithPreparseData() ||
1118 : HasUncompiledDataWithoutPreparseData());
1119 :
1120 : CHECK(script_or_debug_info()->IsUndefined(isolate) ||
1121 : script_or_debug_info()->IsScript() || HasDebugInfo());
1122 :
1123 : if (!is_compiled()) {
1124 : CHECK(!HasFeedbackMetadata());
1125 : CHECK(outer_scope_info()->IsScopeInfo() ||
1126 : outer_scope_info()->IsTheHole(isolate));
1127 : } else if (HasBytecodeArray() && HasFeedbackMetadata()) {
1128 : CHECK(feedback_metadata()->IsFeedbackMetadata());
1129 : }
1130 :
1131 : int expected_map_index = Context::FunctionMapIndex(
1132 : language_mode(), kind(), HasSharedName(), needs_home_object());
1133 : CHECK_EQ(expected_map_index, function_map_index());
1134 :
1135 : if (scope_info()->length() > 0) {
1136 : ScopeInfo info = scope_info();
1137 : CHECK(kind() == info->function_kind());
1138 : CHECK_EQ(kind() == kModule, info->scope_type() == MODULE_SCOPE);
1139 : }
1140 :
1141 : if (IsApiFunction()) {
1142 : CHECK(construct_as_builtin());
1143 : } else if (!HasBuiltinId()) {
1144 : CHECK(!construct_as_builtin());
1145 : } else {
1146 : int id = builtin_id();
1147 : if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
1148 : CHECK(construct_as_builtin());
1149 : } else {
1150 : CHECK(!construct_as_builtin());
1151 : }
1152 : }
1153 :
1154 : // At this point we only support skipping arguments adaptor frames
1155 : // for strict mode functions (see https://crbug.com/v8/8895).
1156 : CHECK_IMPLIES(is_safe_to_skip_arguments_adaptor(),
1157 : language_mode() == LanguageMode::kStrict);
1158 : }
1159 :
1160 : void JSGlobalProxy::JSGlobalProxyVerify(Isolate* isolate) {
1161 : CHECK(IsJSGlobalProxy());
1162 : JSObjectVerify(isolate);
1163 : VerifyObjectField(isolate, JSGlobalProxy::kNativeContextOffset);
1164 : CHECK(map()->is_access_check_needed());
1165 : // Make sure that this object has no properties, elements.
1166 : CHECK_EQ(0, FixedArray::cast(elements())->length());
1167 : }
1168 :
1169 : void JSGlobalObject::JSGlobalObjectVerify(Isolate* isolate) {
1170 : CHECK(IsJSGlobalObject());
1171 : // Do not check the dummy global object for the builtins.
1172 : if (global_dictionary()->NumberOfElements() == 0 &&
1173 : elements()->length() == 0) {
1174 : return;
1175 : }
1176 : JSObjectVerify(isolate);
1177 : }
1178 :
1179 : void Oddball::OddballVerify(Isolate* isolate) {
1180 : CHECK(IsOddball());
1181 : Heap* heap = isolate->heap();
1182 : VerifyHeapPointer(isolate, to_string());
1183 : Object number = to_number();
1184 : if (number->IsHeapObject()) {
1185 : CHECK(number == ReadOnlyRoots(heap).nan_value() ||
1186 : number == ReadOnlyRoots(heap).hole_nan_value());
1187 : } else {
1188 : CHECK(number->IsSmi());
1189 : int value = Smi::ToInt(number);
1190 : // Hidden oddballs have negative smis.
1191 : const int kLeastHiddenOddballNumber = -7;
1192 : CHECK_LE(value, 1);
1193 : CHECK_GE(value, kLeastHiddenOddballNumber);
1194 : }
1195 :
1196 : ReadOnlyRoots roots(heap);
1197 : if (map() == roots.undefined_map()) {
1198 : CHECK(*this == roots.undefined_value());
1199 : } else if (map() == roots.the_hole_map()) {
1200 : CHECK(*this == roots.the_hole_value());
1201 : } else if (map() == roots.null_map()) {
1202 : CHECK(*this == roots.null_value());
1203 : } else if (map() == roots.boolean_map()) {
1204 : CHECK(*this == roots.true_value() || *this == roots.false_value());
1205 : } else if (map() == roots.uninitialized_map()) {
1206 : CHECK(*this == roots.uninitialized_value());
1207 : } else if (map() == roots.arguments_marker_map()) {
1208 : CHECK(*this == roots.arguments_marker());
1209 : } else if (map() == roots.termination_exception_map()) {
1210 : CHECK(*this == roots.termination_exception());
1211 : } else if (map() == roots.exception_map()) {
1212 : CHECK(*this == roots.exception());
1213 : } else if (map() == roots.optimized_out_map()) {
1214 : CHECK(*this == roots.optimized_out());
1215 : } else if (map() == roots.stale_register_map()) {
1216 : CHECK(*this == roots.stale_register());
1217 : } else if (map() == roots.self_reference_marker_map()) {
1218 : // Multiple instances of this oddball may exist at once.
1219 : CHECK_EQ(kind(), Oddball::kSelfReferenceMarker);
1220 : } else {
1221 : UNREACHABLE();
1222 : }
1223 : CHECK(to_string()->IsString());
1224 : CHECK(type_of()->IsString());
1225 : }
1226 :
1227 : void Cell::CellVerify(Isolate* isolate) {
1228 : CHECK(IsCell());
1229 : VerifyObjectField(isolate, kValueOffset);
1230 : }
1231 :
1232 : void PropertyCell::PropertyCellVerify(Isolate* isolate) {
1233 : CHECK(IsPropertyCell());
1234 : VerifyObjectField(isolate, kNameOffset);
1235 : CHECK(name()->IsName());
1236 : VerifySmiField(kPropertyDetailsRawOffset);
1237 : VerifyObjectField(isolate, kValueOffset);
1238 : VerifyObjectField(isolate, kDependentCodeOffset);
1239 : CHECK(dependent_code()->IsDependentCode());
1240 : }
1241 :
1242 : void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) {
1243 : CHECK(IsCodeDataContainer());
1244 : VerifyObjectField(isolate, kNextCodeLinkOffset);
1245 : CHECK(next_code_link()->IsCode() || next_code_link()->IsUndefined(isolate));
1246 : }
1247 :
1248 : void Code::CodeVerify(Isolate* isolate) {
1249 : CHECK_IMPLIES(
1250 : has_safepoint_table(),
1251 : IsAligned(safepoint_table_offset(), static_cast<unsigned>(kIntSize)));
1252 : CHECK_LE(safepoint_table_offset(), handler_table_offset());
1253 : CHECK_LE(handler_table_offset(), constant_pool_offset());
1254 : CHECK_LE(constant_pool_offset(), code_comments_offset());
1255 : CHECK_LE(code_comments_offset(), InstructionSize());
1256 : CHECK(IsAligned(raw_instruction_start(), kCodeAlignment));
1257 : relocation_info()->ObjectVerify(isolate);
1258 : CHECK(Code::SizeFor(body_size()) <= kMaxRegularHeapObjectSize ||
1259 : isolate->heap()->InSpace(*this, CODE_LO_SPACE));
1260 : Address last_gc_pc = kNullAddress;
1261 :
1262 : for (RelocIterator it(*this); !it.done(); it.next()) {
1263 : it.rinfo()->Verify(isolate);
1264 : // Ensure that GC will not iterate twice over the same pointer.
1265 : if (RelocInfo::IsGCRelocMode(it.rinfo()->rmode())) {
1266 : CHECK(it.rinfo()->pc() != last_gc_pc);
1267 : last_gc_pc = it.rinfo()->pc();
1268 : }
1269 : }
1270 : }
1271 :
1272 : void JSArray::JSArrayVerify(Isolate* isolate) {
1273 : JSObjectVerify(isolate);
1274 : CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
1275 : // If a GC was caused while constructing this array, the elements
1276 : // pointer may point to a one pointer filler map.
1277 : if (!ElementsAreSafeToExamine()) return;
1278 : if (elements()->IsUndefined(isolate)) return;
1279 : CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
1280 : if (elements()->length() == 0) {
1281 : CHECK_EQ(elements(), ReadOnlyRoots(isolate).empty_fixed_array());
1282 : }
1283 : if (!length()->IsNumber()) return;
1284 : // Verify that the length and the elements backing store are in sync.
1285 : if (length()->IsSmi() && (HasFastElements() || HasFrozenOrSealedElements())) {
1286 : if (elements()->length() > 0) {
1287 : CHECK_IMPLIES(HasDoubleElements(), elements()->IsFixedDoubleArray());
1288 : CHECK_IMPLIES(HasSmiOrObjectElements() || HasFrozenOrSealedElements(),
1289 : elements()->IsFixedArray());
1290 : }
1291 : int size = Smi::ToInt(length());
1292 : // Holey / Packed backing stores might have slack or might have not been
1293 : // properly initialized yet.
1294 : CHECK(size <= elements()->length() ||
1295 : elements() == ReadOnlyRoots(isolate).empty_fixed_array());
1296 : } else {
1297 : CHECK(HasDictionaryElements());
1298 : uint32_t array_length;
1299 : CHECK(length()->ToArrayLength(&array_length));
1300 : if (array_length == 0xFFFFFFFF) {
1301 : CHECK(length()->ToArrayLength(&array_length));
1302 : }
1303 : if (array_length != 0) {
1304 : NumberDictionary dict = NumberDictionary::cast(elements());
1305 : // The dictionary can never have more elements than the array length + 1.
1306 : // If the backing store grows the verification might be triggered with
1307 : // the old length in place.
1308 : uint32_t nof_elements = static_cast<uint32_t>(dict->NumberOfElements());
1309 : if (nof_elements != 0) nof_elements--;
1310 : CHECK_LE(nof_elements, array_length);
1311 : }
1312 : }
1313 : }
1314 :
1315 : void JSSet::JSSetVerify(Isolate* isolate) {
1316 : CHECK(IsJSSet());
1317 : JSObjectVerify(isolate);
1318 : VerifyHeapPointer(isolate, table());
1319 : CHECK(table()->IsOrderedHashSet() || table()->IsUndefined(isolate));
1320 : // TODO(arv): Verify OrderedHashTable too.
1321 : }
1322 :
1323 : void JSMap::JSMapVerify(Isolate* isolate) {
1324 : CHECK(IsJSMap());
1325 : JSObjectVerify(isolate);
1326 : VerifyHeapPointer(isolate, table());
1327 : CHECK(table()->IsOrderedHashMap() || table()->IsUndefined(isolate));
1328 : // TODO(arv): Verify OrderedHashTable too.
1329 : }
1330 :
1331 : void JSSetIterator::JSSetIteratorVerify(Isolate* isolate) {
1332 : CHECK(IsJSSetIterator());
1333 : JSObjectVerify(isolate);
1334 : VerifyHeapPointer(isolate, table());
1335 : CHECK(table()->IsOrderedHashSet());
1336 : CHECK(index()->IsSmi());
1337 : }
1338 :
1339 : void JSMapIterator::JSMapIteratorVerify(Isolate* isolate) {
1340 : CHECK(IsJSMapIterator());
1341 : JSObjectVerify(isolate);
1342 : VerifyHeapPointer(isolate, table());
1343 : CHECK(table()->IsOrderedHashMap());
1344 : CHECK(index()->IsSmi());
1345 : }
1346 :
1347 : void WeakCell::WeakCellVerify(Isolate* isolate) {
1348 : CHECK(IsWeakCell());
1349 :
1350 : CHECK(target()->IsJSReceiver() || target()->IsUndefined(isolate));
1351 :
1352 : CHECK(prev()->IsWeakCell() || prev()->IsUndefined(isolate));
1353 : if (prev()->IsWeakCell()) {
1354 : CHECK_EQ(WeakCell::cast(prev())->next(), *this);
1355 : }
1356 :
1357 : CHECK(next()->IsWeakCell() || next()->IsUndefined(isolate));
1358 : if (next()->IsWeakCell()) {
1359 : CHECK_EQ(WeakCell::cast(next())->prev(), *this);
1360 : }
1361 :
1362 : CHECK_IMPLIES(key()->IsUndefined(isolate),
1363 : key_list_prev()->IsUndefined(isolate));
1364 : CHECK_IMPLIES(key()->IsUndefined(isolate),
1365 : key_list_next()->IsUndefined(isolate));
1366 :
1367 : CHECK(key_list_prev()->IsWeakCell() || key_list_prev()->IsUndefined(isolate));
1368 : if (key_list_prev()->IsWeakCell()) {
1369 : CHECK_EQ(WeakCell::cast(key_list_prev())->key_list_next(), *this);
1370 : }
1371 :
1372 : CHECK(key_list_next()->IsWeakCell() || key_list_next()->IsUndefined(isolate));
1373 : if (key_list_next()->IsWeakCell()) {
1374 : CHECK_EQ(WeakCell::cast(key_list_next())->key_list_prev(), *this);
1375 : }
1376 :
1377 : CHECK(finalization_group()->IsUndefined(isolate) ||
1378 : finalization_group()->IsJSFinalizationGroup());
1379 : }
1380 :
1381 : void JSWeakRef::JSWeakRefVerify(Isolate* isolate) {
1382 : CHECK(IsJSWeakRef());
1383 : JSObjectVerify(isolate);
1384 : CHECK(target()->IsUndefined(isolate) || target()->IsJSReceiver());
1385 : }
1386 :
1387 : void JSFinalizationGroup::JSFinalizationGroupVerify(Isolate* isolate) {
1388 : CHECK(IsJSFinalizationGroup());
1389 : JSObjectVerify(isolate);
1390 : VerifyHeapPointer(isolate, cleanup());
1391 : CHECK(active_cells()->IsUndefined(isolate) || active_cells()->IsWeakCell());
1392 : if (active_cells()->IsWeakCell()) {
1393 : CHECK(WeakCell::cast(active_cells())->prev()->IsUndefined(isolate));
1394 : }
1395 : CHECK(cleared_cells()->IsUndefined(isolate) || cleared_cells()->IsWeakCell());
1396 : if (cleared_cells()->IsWeakCell()) {
1397 : CHECK(WeakCell::cast(cleared_cells())->prev()->IsUndefined(isolate));
1398 : }
1399 : }
1400 :
1401 : void JSFinalizationGroupCleanupIterator::
1402 : JSFinalizationGroupCleanupIteratorVerify(Isolate* isolate) {
1403 : CHECK(IsJSFinalizationGroupCleanupIterator());
1404 : JSObjectVerify(isolate);
1405 : VerifyHeapPointer(isolate, finalization_group());
1406 : }
1407 :
1408 : void FinalizationGroupCleanupJobTask::FinalizationGroupCleanupJobTaskVerify(
1409 : Isolate* isolate) {
1410 : CHECK(IsFinalizationGroupCleanupJobTask());
1411 : CHECK(finalization_group()->IsJSFinalizationGroup());
1412 : }
1413 :
1414 : void JSWeakMap::JSWeakMapVerify(Isolate* isolate) {
1415 : CHECK(IsJSWeakMap());
1416 : JSObjectVerify(isolate);
1417 : VerifyHeapPointer(isolate, table());
1418 : CHECK(table()->IsEphemeronHashTable() || table()->IsUndefined(isolate));
1419 : }
1420 :
1421 : void JSArrayIterator::JSArrayIteratorVerify(Isolate* isolate) {
1422 : CHECK(IsJSArrayIterator());
1423 : JSObjectVerify(isolate);
1424 : CHECK(iterated_object()->IsJSReceiver());
1425 :
1426 : CHECK_GE(next_index()->Number(), 0);
1427 : CHECK_LE(next_index()->Number(), kMaxSafeInteger);
1428 :
1429 : if (iterated_object()->IsJSTypedArray()) {
1430 : // JSTypedArray::length is limited to Smi range.
1431 : CHECK(next_index()->IsSmi());
1432 : CHECK_LE(next_index()->Number(), Smi::kMaxValue);
1433 : } else if (iterated_object()->IsJSArray()) {
1434 : // JSArray::length is limited to Uint32 range.
1435 : CHECK_LE(next_index()->Number(), kMaxUInt32);
1436 : }
1437 : }
1438 :
1439 : void JSStringIterator::JSStringIteratorVerify(Isolate* isolate) {
1440 : CHECK(IsJSStringIterator());
1441 : JSObjectVerify(isolate);
1442 : CHECK(string()->IsString());
1443 :
1444 : CHECK_GE(index(), 0);
1445 : CHECK_LE(index(), String::kMaxLength);
1446 : }
1447 :
1448 : void JSAsyncFromSyncIterator::JSAsyncFromSyncIteratorVerify(Isolate* isolate) {
1449 : CHECK(IsJSAsyncFromSyncIterator());
1450 : JSObjectVerify(isolate);
1451 : VerifyHeapPointer(isolate, sync_iterator());
1452 : }
1453 :
1454 : void JSWeakSet::JSWeakSetVerify(Isolate* isolate) {
1455 : CHECK(IsJSWeakSet());
1456 : JSObjectVerify(isolate);
1457 : VerifyHeapPointer(isolate, table());
1458 : CHECK(table()->IsEphemeronHashTable() || table()->IsUndefined(isolate));
1459 : }
1460 :
1461 : void Microtask::MicrotaskVerify(Isolate* isolate) { CHECK(IsMicrotask()); }
1462 :
1463 : void CallableTask::CallableTaskVerify(Isolate* isolate) {
1464 : CHECK(IsCallableTask());
1465 : MicrotaskVerify(isolate);
1466 : VerifyHeapPointer(isolate, callable());
1467 : CHECK(callable()->IsCallable());
1468 : VerifyHeapPointer(isolate, context());
1469 : CHECK(context()->IsContext());
1470 : }
1471 :
1472 : void CallbackTask::CallbackTaskVerify(Isolate* isolate) {
1473 : CHECK(IsCallbackTask());
1474 : MicrotaskVerify(isolate);
1475 : VerifyHeapPointer(isolate, callback());
1476 : VerifyHeapPointer(isolate, data());
1477 : }
1478 :
1479 : void PromiseReactionJobTask::PromiseReactionJobTaskVerify(Isolate* isolate) {
1480 : CHECK(IsPromiseReactionJobTask());
1481 : MicrotaskVerify(isolate);
1482 : VerifyPointer(isolate, argument());
1483 : VerifyHeapPointer(isolate, context());
1484 : CHECK(context()->IsContext());
1485 : VerifyHeapPointer(isolate, handler());
1486 : CHECK(handler()->IsUndefined(isolate) || handler()->IsCallable());
1487 : VerifyHeapPointer(isolate, promise_or_capability());
1488 : CHECK(promise_or_capability()->IsJSPromise() ||
1489 : promise_or_capability()->IsPromiseCapability() ||
1490 : promise_or_capability()->IsUndefined(isolate));
1491 : }
1492 :
1493 : void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskVerify(
1494 : Isolate* isolate) {
1495 : CHECK(IsPromiseFulfillReactionJobTask());
1496 : PromiseReactionJobTaskVerify(isolate);
1497 : }
1498 :
1499 : void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskVerify(
1500 : Isolate* isolate) {
1501 : CHECK(IsPromiseRejectReactionJobTask());
1502 : PromiseReactionJobTaskVerify(isolate);
1503 : }
1504 :
1505 : void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskVerify(
1506 : Isolate* isolate) {
1507 : CHECK(IsPromiseResolveThenableJobTask());
1508 : MicrotaskVerify(isolate);
1509 : VerifyHeapPointer(isolate, context());
1510 : CHECK(context()->IsContext());
1511 : VerifyHeapPointer(isolate, promise_to_resolve());
1512 : CHECK(promise_to_resolve()->IsJSPromise());
1513 : VerifyHeapPointer(isolate, then());
1514 : CHECK(then()->IsCallable());
1515 : CHECK(then()->IsJSReceiver());
1516 : VerifyHeapPointer(isolate, thenable());
1517 : CHECK(thenable()->IsJSReceiver());
1518 : }
1519 :
1520 : void PromiseCapability::PromiseCapabilityVerify(Isolate* isolate) {
1521 : CHECK(IsPromiseCapability());
1522 :
1523 : VerifyHeapPointer(isolate, promise());
1524 : CHECK(promise()->IsJSReceiver() || promise()->IsUndefined(isolate));
1525 : VerifyPointer(isolate, resolve());
1526 : VerifyPointer(isolate, reject());
1527 : }
1528 :
1529 : void PromiseReaction::PromiseReactionVerify(Isolate* isolate) {
1530 : CHECK(IsPromiseReaction());
1531 :
1532 : VerifyPointer(isolate, next());
1533 : CHECK(next()->IsSmi() || next()->IsPromiseReaction());
1534 : VerifyHeapPointer(isolate, reject_handler());
1535 : CHECK(reject_handler()->IsUndefined(isolate) ||
1536 : reject_handler()->IsCallable());
1537 : VerifyHeapPointer(isolate, fulfill_handler());
1538 : CHECK(fulfill_handler()->IsUndefined(isolate) ||
1539 : fulfill_handler()->IsCallable());
1540 : VerifyHeapPointer(isolate, promise_or_capability());
1541 : CHECK(promise_or_capability()->IsJSPromise() ||
1542 : promise_or_capability()->IsPromiseCapability() ||
1543 : promise_or_capability()->IsUndefined(isolate));
1544 : }
1545 :
1546 : void JSPromise::JSPromiseVerify(Isolate* isolate) {
1547 : CHECK(IsJSPromise());
1548 : JSObjectVerify(isolate);
1549 : VerifyPointer(isolate, reactions_or_result());
1550 : VerifySmiField(kFlagsOffset);
1551 : if (status() == Promise::kPending) {
1552 : CHECK(reactions()->IsSmi() || reactions()->IsPromiseReaction());
1553 : }
1554 : }
1555 :
1556 : template <typename Derived>
1557 : void SmallOrderedHashTable<Derived>::SmallOrderedHashTableVerify(
1558 : Isolate* isolate) {
1559 : CHECK(IsSmallOrderedHashTable());
1560 :
1561 : int capacity = Capacity();
1562 : CHECK_GE(capacity, kMinCapacity);
1563 : CHECK_LE(capacity, kMaxCapacity);
1564 :
1565 : for (int entry = 0; entry < NumberOfBuckets(); entry++) {
1566 : int bucket = GetFirstEntry(entry);
1567 : if (bucket == kNotFound) continue;
1568 : CHECK_GE(bucket, 0);
1569 : CHECK_LE(bucket, capacity);
1570 : }
1571 :
1572 : for (int entry = 0; entry < NumberOfElements(); entry++) {
1573 : int chain = GetNextEntry(entry);
1574 : if (chain == kNotFound) continue;
1575 : CHECK_GE(chain, 0);
1576 : CHECK_LE(chain, capacity);
1577 : }
1578 :
1579 : for (int entry = 0; entry < NumberOfElements(); entry++) {
1580 : for (int offset = 0; offset < Derived::kEntrySize; offset++) {
1581 : Object val = GetDataEntry(entry, offset);
1582 : VerifyPointer(isolate, val);
1583 : }
1584 : }
1585 :
1586 : for (int entry = NumberOfElements() + NumberOfDeletedElements();
1587 : entry < Capacity(); entry++) {
1588 : for (int offset = 0; offset < Derived::kEntrySize; offset++) {
1589 : Object val = GetDataEntry(entry, offset);
1590 : CHECK(val->IsTheHole(isolate));
1591 : }
1592 : }
1593 : }
1594 : void SmallOrderedHashMap::SmallOrderedHashMapVerify(Isolate* isolate) {
1595 : SmallOrderedHashTable<SmallOrderedHashMap>::SmallOrderedHashTableVerify(
1596 : isolate);
1597 : for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
1598 : entry++) {
1599 : for (int offset = 0; offset < kEntrySize; offset++) {
1600 : Object val = GetDataEntry(entry, offset);
1601 : CHECK(val->IsTheHole(isolate));
1602 : }
1603 : }
1604 : }
1605 :
1606 : void SmallOrderedHashSet::SmallOrderedHashSetVerify(Isolate* isolate) {
1607 : SmallOrderedHashTable<SmallOrderedHashSet>::SmallOrderedHashTableVerify(
1608 : isolate);
1609 : for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
1610 : entry++) {
1611 : for (int offset = 0; offset < kEntrySize; offset++) {
1612 : Object val = GetDataEntry(entry, offset);
1613 : CHECK(val->IsTheHole(isolate));
1614 : }
1615 : }
1616 : }
1617 :
1618 : void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify(
1619 : Isolate* isolate) {
1620 : SmallOrderedHashTable<
1621 : SmallOrderedNameDictionary>::SmallOrderedHashTableVerify(isolate);
1622 : for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
1623 : entry++) {
1624 : for (int offset = 0; offset < kEntrySize; offset++) {
1625 : Object val = GetDataEntry(entry, offset);
1626 : CHECK(val->IsTheHole(isolate) ||
1627 : (PropertyDetails::Empty().AsSmi() == Smi::cast(val)));
1628 : }
1629 : }
1630 : }
1631 :
1632 : void JSRegExp::JSRegExpVerify(Isolate* isolate) {
1633 : JSObjectVerify(isolate);
1634 : CHECK(data()->IsUndefined(isolate) || data()->IsFixedArray());
1635 : CHECK(source()->IsUndefined(isolate) || source()->IsString());
1636 : CHECK(flags()->IsUndefined() || flags()->IsSmi());
1637 : switch (TypeTag()) {
1638 : case JSRegExp::ATOM: {
1639 : FixedArray arr = FixedArray::cast(data());
1640 : CHECK(arr->get(JSRegExp::kAtomPatternIndex)->IsString());
1641 : break;
1642 : }
1643 : case JSRegExp::IRREGEXP: {
1644 : bool is_native = RegExpImpl::UsesNativeRegExp();
1645 :
1646 : FixedArray arr = FixedArray::cast(data());
1647 : Object one_byte_data = arr->get(JSRegExp::kIrregexpLatin1CodeIndex);
1648 : // Smi : Not compiled yet (-1).
1649 : // Code/ByteArray: Compiled code.
1650 : CHECK(
1651 : (one_byte_data->IsSmi() &&
1652 : Smi::ToInt(one_byte_data) == JSRegExp::kUninitializedValue) ||
1653 : (is_native ? one_byte_data->IsCode() : one_byte_data->IsByteArray()));
1654 : Object uc16_data = arr->get(JSRegExp::kIrregexpUC16CodeIndex);
1655 : CHECK((uc16_data->IsSmi() &&
1656 : Smi::ToInt(uc16_data) == JSRegExp::kUninitializedValue) ||
1657 : (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
1658 :
1659 : CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
1660 : CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
1661 : break;
1662 : }
1663 : default:
1664 : CHECK_EQ(JSRegExp::NOT_COMPILED, TypeTag());
1665 : CHECK(data()->IsUndefined(isolate));
1666 : break;
1667 : }
1668 : }
1669 :
1670 : void JSRegExpStringIterator::JSRegExpStringIteratorVerify(Isolate* isolate) {
1671 : CHECK(IsJSRegExpStringIterator());
1672 : JSObjectVerify(isolate);
1673 : CHECK(iterating_string()->IsString());
1674 : CHECK(iterating_regexp()->IsObject());
1675 : VerifySmiField(kFlagsOffset);
1676 : }
1677 :
1678 : void JSProxy::JSProxyVerify(Isolate* isolate) {
1679 : CHECK(IsJSProxy());
1680 : CHECK(map()->GetConstructor()->IsJSFunction());
1681 : VerifyPointer(isolate, target());
1682 : VerifyPointer(isolate, handler());
1683 : if (!IsRevoked()) {
1684 : CHECK_EQ(target()->IsCallable(), map()->is_callable());
1685 : CHECK_EQ(target()->IsConstructor(), map()->is_constructor());
1686 : }
1687 : CHECK(map()->prototype()->IsNull(isolate));
1688 : // There should be no properties on a Proxy.
1689 : CHECK_EQ(0, map()->NumberOfOwnDescriptors());
1690 : }
1691 :
1692 : void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) {
1693 : CHECK(IsJSArrayBuffer());
1694 : if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
1695 : CHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
1696 : CHECK_EQ(0,
1697 : *reinterpret_cast<uint32_t*>(address() + kOptionalPaddingOffset));
1698 : }
1699 : JSObjectVerify(isolate);
1700 : }
1701 :
1702 : void JSArrayBufferView::JSArrayBufferViewVerify(Isolate* isolate) {
1703 : CHECK(IsJSArrayBufferView());
1704 : JSObjectVerify(isolate);
1705 : VerifyPointer(isolate, buffer());
1706 : CHECK(buffer()->IsJSArrayBuffer() || buffer()->IsUndefined(isolate) ||
1707 : buffer() == Smi::kZero);
1708 : CHECK_LE(byte_length(), JSArrayBuffer::kMaxByteLength);
1709 : CHECK_LE(byte_offset(), JSArrayBuffer::kMaxByteLength);
1710 : }
1711 :
1712 : void JSTypedArray::JSTypedArrayVerify(Isolate* isolate) {
1713 : CHECK(IsJSTypedArray());
1714 : JSArrayBufferViewVerify(isolate);
1715 : VerifyPointer(isolate, raw_length());
1716 : CHECK(raw_length()->IsSmi() || raw_length()->IsUndefined(isolate));
1717 : VerifyPointer(isolate, elements());
1718 : }
1719 :
1720 : void JSDataView::JSDataViewVerify(Isolate* isolate) {
1721 : CHECK(IsJSDataView());
1722 : JSArrayBufferViewVerify(isolate);
1723 : }
1724 :
1725 : void Foreign::ForeignVerify(Isolate* isolate) { CHECK(IsForeign()); }
1726 :
1727 : void AsyncGeneratorRequest::AsyncGeneratorRequestVerify(Isolate* isolate) {
1728 : CHECK(IsAsyncGeneratorRequest());
1729 : VerifySmiField(kResumeModeOffset);
1730 : CHECK_GE(resume_mode(), JSGeneratorObject::kNext);
1731 : CHECK_LE(resume_mode(), JSGeneratorObject::kThrow);
1732 : CHECK(promise()->IsJSPromise());
1733 : VerifyPointer(isolate, value());
1734 : VerifyPointer(isolate, next());
1735 : next()->ObjectVerify(isolate);
1736 : }
1737 :
1738 : void BigInt::BigIntVerify(Isolate* isolate) {
1739 : CHECK(IsBigInt());
1740 : CHECK_GE(length(), 0);
1741 : CHECK_IMPLIES(is_zero(), !sign()); // There is no -0n.
1742 : }
1743 :
1744 : void JSModuleNamespace::JSModuleNamespaceVerify(Isolate* isolate) {
1745 : CHECK(IsJSModuleNamespace());
1746 : VerifyPointer(isolate, module());
1747 : }
1748 :
1749 : void ModuleInfoEntry::ModuleInfoEntryVerify(Isolate* isolate) {
1750 : CHECK(IsModuleInfoEntry());
1751 :
1752 : CHECK(export_name()->IsUndefined(isolate) || export_name()->IsString());
1753 : CHECK(local_name()->IsUndefined(isolate) || local_name()->IsString());
1754 : CHECK(import_name()->IsUndefined(isolate) || import_name()->IsString());
1755 :
1756 : VerifySmiField(kModuleRequestOffset);
1757 : VerifySmiField(kCellIndexOffset);
1758 : VerifySmiField(kBegPosOffset);
1759 : VerifySmiField(kEndPosOffset);
1760 :
1761 : CHECK_IMPLIES(import_name()->IsString(), module_request() >= 0);
1762 : CHECK_IMPLIES(export_name()->IsString() && import_name()->IsString(),
1763 : local_name()->IsUndefined(isolate));
1764 : }
1765 :
1766 : void Module::ModuleVerify(Isolate* isolate) {
1767 : CHECK(IsModule());
1768 :
1769 : VerifyPointer(isolate, code());
1770 : VerifyPointer(isolate, exports());
1771 : VerifyPointer(isolate, module_namespace());
1772 : VerifyPointer(isolate, requested_modules());
1773 : VerifyPointer(isolate, script());
1774 : VerifyPointer(isolate, import_meta());
1775 : VerifyPointer(isolate, exception());
1776 : VerifySmiField(kHashOffset);
1777 : VerifySmiField(kStatusOffset);
1778 :
1779 : CHECK((status() >= kEvaluating && code()->IsModuleInfo()) ||
1780 : (status() == kInstantiated && code()->IsJSGeneratorObject()) ||
1781 : (status() == kInstantiating && code()->IsJSFunction()) ||
1782 : (code()->IsSharedFunctionInfo()));
1783 :
1784 : CHECK_EQ(status() == kErrored, !exception()->IsTheHole(isolate));
1785 :
1786 : CHECK(module_namespace()->IsUndefined(isolate) ||
1787 : module_namespace()->IsJSModuleNamespace());
1788 : if (module_namespace()->IsJSModuleNamespace()) {
1789 : CHECK_LE(kInstantiating, status());
1790 : CHECK_EQ(JSModuleNamespace::cast(module_namespace())->module(), *this);
1791 : }
1792 :
1793 : CHECK_EQ(requested_modules()->length(), info()->module_requests()->length());
1794 :
1795 : CHECK(import_meta()->IsTheHole(isolate) || import_meta()->IsJSObject());
1796 :
1797 : CHECK_NE(hash(), 0);
1798 : }
1799 :
1800 : void PrototypeInfo::PrototypeInfoVerify(Isolate* isolate) {
1801 : CHECK(IsPrototypeInfo());
1802 : Object module_ns = module_namespace();
1803 : CHECK(module_ns->IsJSModuleNamespace() || module_ns->IsUndefined(isolate));
1804 : if (prototype_users()->IsWeakArrayList()) {
1805 : PrototypeUsers::Verify(WeakArrayList::cast(prototype_users()));
1806 : } else {
1807 : CHECK(prototype_users()->IsSmi());
1808 : }
1809 : }
1810 :
1811 : void PrototypeUsers::Verify(WeakArrayList array) {
1812 : if (array->length() == 0) {
1813 : // Allow empty & uninitialized lists.
1814 : return;
1815 : }
1816 : // Verify empty slot chain.
1817 : int empty_slot = Smi::ToInt(empty_slot_index(array));
1818 : int empty_slots_count = 0;
1819 : while (empty_slot != kNoEmptySlotsMarker) {
1820 : CHECK_GT(empty_slot, 0);
1821 : CHECK_LT(empty_slot, array->length());
1822 : empty_slot = array->Get(empty_slot).ToSmi().value();
1823 : ++empty_slots_count;
1824 : }
1825 :
1826 : // Verify that all elements are either weak pointers or SMIs marking empty
1827 : // slots.
1828 : int weak_maps_count = 0;
1829 : for (int i = kFirstIndex; i < array->length(); ++i) {
1830 : HeapObject heap_object;
1831 : MaybeObject object = array->Get(i);
1832 : if ((object->GetHeapObjectIfWeak(&heap_object) && heap_object->IsMap()) ||
1833 : object->IsCleared()) {
1834 : ++weak_maps_count;
1835 : } else {
1836 : CHECK(object->IsSmi());
1837 : }
1838 : }
1839 :
1840 : CHECK_EQ(weak_maps_count + empty_slots_count + 1, array->length());
1841 : }
1842 :
1843 : void Tuple2::Tuple2Verify(Isolate* isolate) {
1844 : CHECK(IsTuple2());
1845 : VerifyObjectField(isolate, kValue1Offset);
1846 : VerifyObjectField(isolate, kValue2Offset);
1847 : }
1848 :
1849 : void EnumCache::EnumCacheVerify(Isolate* isolate) {
1850 : CHECK(IsEnumCache());
1851 : Heap* heap = isolate->heap();
1852 : if (*this == ReadOnlyRoots(heap).empty_enum_cache()) {
1853 : CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(), keys());
1854 : CHECK_EQ(ReadOnlyRoots(heap).empty_fixed_array(), indices());
1855 : } else {
1856 : VerifyObjectField(isolate, kKeysOffset);
1857 : VerifyObjectField(isolate, kIndicesOffset);
1858 : CHECK(keys()->IsFixedArray());
1859 : CHECK(indices()->IsFixedArray());
1860 : }
1861 : }
1862 :
1863 : void Tuple3::Tuple3Verify(Isolate* isolate) {
1864 : CHECK(IsTuple3());
1865 : VerifyObjectField(isolate, kValue1Offset);
1866 : VerifyObjectField(isolate, kValue2Offset);
1867 : VerifyObjectField(isolate, kValue3Offset);
1868 : }
1869 :
1870 : void ClassPositions::ClassPositionsVerify(Isolate* isolate) {
1871 : CHECK(IsClassPositions());
1872 : VerifySmiField(kStartOffset);
1873 : VerifySmiField(kEndOffset);
1874 : }
1875 :
1876 : void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionVerify(
1877 : Isolate* isolate) {
1878 : CHECK(IsObjectBoilerplateDescription());
1879 : CHECK_GE(this->length(),
1880 : ObjectBoilerplateDescription::kDescriptionStartIndex);
1881 : this->FixedArrayVerify(isolate);
1882 : }
1883 :
1884 : void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionVerify(
1885 : Isolate* isolate) {
1886 : CHECK(IsArrayBoilerplateDescription());
1887 : CHECK(constant_elements()->IsFixedArrayBase());
1888 : VerifyObjectField(isolate, kConstantElementsOffset);
1889 : }
1890 :
1891 : void AsmWasmData::AsmWasmDataVerify(Isolate* isolate) {
1892 : CHECK(IsAsmWasmData());
1893 : CHECK(managed_native_module()->IsForeign());
1894 : VerifyObjectField(isolate, kManagedNativeModuleOffset);
1895 : CHECK(export_wrappers()->IsFixedArray());
1896 : VerifyObjectField(isolate, kExportWrappersOffset);
1897 : CHECK(asm_js_offset_table()->IsByteArray());
1898 : VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
1899 : CHECK(uses_bitset()->IsHeapNumber());
1900 : VerifyObjectField(isolate, kUsesBitsetOffset);
1901 : }
1902 :
1903 : void WasmDebugInfo::WasmDebugInfoVerify(Isolate* isolate) {
1904 : CHECK(IsWasmDebugInfo());
1905 : VerifyObjectField(isolate, kInstanceOffset);
1906 : CHECK(wasm_instance()->IsWasmInstanceObject());
1907 : VerifyObjectField(isolate, kInterpreterHandleOffset);
1908 : CHECK(interpreter_handle()->IsUndefined(isolate) ||
1909 : interpreter_handle()->IsForeign());
1910 : VerifyObjectField(isolate, kInterpretedFunctionsOffset);
1911 : CHECK(interpreted_functions()->IsFixedArray());
1912 : VerifyObjectField(isolate, kLocalsNamesOffset);
1913 : VerifyObjectField(isolate, kCWasmEntriesOffset);
1914 : VerifyObjectField(isolate, kCWasmEntryMapOffset);
1915 : }
1916 :
1917 : void WasmExceptionTag::WasmExceptionTagVerify(Isolate* isolate) {
1918 : CHECK(IsWasmExceptionTag());
1919 : VerifySmiField(kIndexOffset);
1920 : }
1921 :
1922 : void WasmInstanceObject::WasmInstanceObjectVerify(Isolate* isolate) {
1923 : JSObjectVerify(isolate);
1924 : CHECK(IsWasmInstanceObject());
1925 :
1926 : // Just generically check all tagged fields. Don't check the untagged fields,
1927 : // as some of them might still contain the "undefined" value if the
1928 : // WasmInstanceObject is not fully set up yet.
1929 : for (int offset = kHeaderSize; offset < kEndOfTaggedFieldsOffset;
1930 : offset += kTaggedSize) {
1931 : VerifyObjectField(isolate, offset);
1932 : }
1933 : }
1934 :
1935 : void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
1936 : Isolate* isolate) {
1937 : CHECK(IsWasmExportedFunctionData());
1938 : VerifyObjectField(isolate, kWrapperCodeOffset);
1939 : CHECK(wrapper_code()->kind() == Code::JS_TO_WASM_FUNCTION ||
1940 : wrapper_code()->kind() == Code::C_WASM_ENTRY);
1941 : VerifyObjectField(isolate, kInstanceOffset);
1942 : CHECK(instance()->IsWasmInstanceObject());
1943 : VerifySmiField(kJumpTableOffsetOffset);
1944 : VerifySmiField(kFunctionIndexOffset);
1945 : }
1946 :
1947 : void WasmModuleObject::WasmModuleObjectVerify(Isolate* isolate) {
1948 : CHECK(IsWasmModuleObject());
1949 : VerifyObjectField(isolate, kNativeModuleOffset);
1950 : CHECK(managed_native_module()->IsForeign());
1951 : VerifyObjectField(isolate, kExportWrappersOffset);
1952 : CHECK(export_wrappers()->IsFixedArray());
1953 : VerifyObjectField(isolate, kScriptOffset);
1954 : CHECK(script()->IsScript());
1955 : VerifyObjectField(isolate, kWeakInstanceListOffset);
1956 : VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
1957 : VerifyObjectField(isolate, kBreakPointInfosOffset);
1958 : }
1959 :
1960 : void WasmTableObject::WasmTableObjectVerify(Isolate* isolate) {
1961 : CHECK(IsWasmTableObject());
1962 : VerifyObjectField(isolate, kElementsOffset);
1963 : CHECK(elements()->IsFixedArray());
1964 : VerifyObjectField(isolate, kMaximumLengthOffset);
1965 : CHECK(maximum_length()->IsSmi() || maximum_length()->IsHeapNumber() ||
1966 : maximum_length()->IsUndefined(isolate));
1967 : VerifyObjectField(isolate, kDispatchTablesOffset);
1968 : VerifySmiField(kRawTypeOffset);
1969 : }
1970 :
1971 : void WasmMemoryObject::WasmMemoryObjectVerify(Isolate* isolate) {
1972 : CHECK(IsWasmMemoryObject());
1973 : VerifyObjectField(isolate, kArrayBufferOffset);
1974 : CHECK(array_buffer()->IsJSArrayBuffer());
1975 : VerifySmiField(kMaximumPagesOffset);
1976 : VerifyObjectField(isolate, kInstancesOffset);
1977 : }
1978 :
1979 : void WasmGlobalObject::WasmGlobalObjectVerify(Isolate* isolate) {
1980 : CHECK(IsWasmGlobalObject());
1981 : VerifyObjectField(isolate, kUntaggedBufferOffset);
1982 : VerifyObjectField(isolate, kTaggedBufferOffset);
1983 : VerifyObjectField(isolate, kOffsetOffset);
1984 : VerifyObjectField(isolate, kFlagsOffset);
1985 : }
1986 :
1987 : void WasmExceptionObject::WasmExceptionObjectVerify(Isolate* isolate) {
1988 : CHECK(IsWasmExceptionObject());
1989 : VerifyObjectField(isolate, kSerializedSignatureOffset);
1990 : CHECK(serialized_signature()->IsByteArray());
1991 : VerifyObjectField(isolate, kExceptionTagOffset);
1992 : CHECK(exception_tag()->IsHeapObject());
1993 : }
1994 :
1995 : void DataHandler::DataHandlerVerify(Isolate* isolate) {
1996 : CHECK(IsDataHandler());
1997 : CHECK_IMPLIES(!smi_handler()->IsSmi(),
1998 : smi_handler()->IsCode() && IsStoreHandler());
1999 : CHECK(validity_cell()->IsSmi() || validity_cell()->IsCell());
2000 : int data_count = data_field_count();
2001 : if (data_count >= 1) {
2002 : VerifyMaybeObjectField(isolate, kData1Offset);
2003 : }
2004 : if (data_count >= 2) {
2005 : VerifyMaybeObjectField(isolate, kData2Offset);
2006 : }
2007 : if (data_count >= 3) {
2008 : VerifyMaybeObjectField(isolate, kData3Offset);
2009 : }
2010 : }
2011 :
2012 : void LoadHandler::LoadHandlerVerify(Isolate* isolate) {
2013 : DataHandler::DataHandlerVerify(isolate);
2014 : // TODO(ishell): check handler integrity
2015 : }
2016 :
2017 : void StoreHandler::StoreHandlerVerify(Isolate* isolate) {
2018 : DataHandler::DataHandlerVerify(isolate);
2019 : // TODO(ishell): check handler integrity
2020 : }
2021 :
2022 : void AccessorInfo::AccessorInfoVerify(Isolate* isolate) {
2023 : CHECK(IsAccessorInfo());
2024 : VerifyPointer(isolate, name());
2025 : VerifyPointer(isolate, expected_receiver_type());
2026 : VerifyForeignPointer(isolate, *this, getter());
2027 : VerifyForeignPointer(isolate, *this, setter());
2028 : VerifyForeignPointer(isolate, *this, js_getter());
2029 : VerifyPointer(isolate, data());
2030 : }
2031 :
2032 : void AccessorPair::AccessorPairVerify(Isolate* isolate) {
2033 : CHECK(IsAccessorPair());
2034 : VerifyPointer(isolate, getter());
2035 : VerifyPointer(isolate, setter());
2036 : }
2037 :
2038 : void AccessCheckInfo::AccessCheckInfoVerify(Isolate* isolate) {
2039 : CHECK(IsAccessCheckInfo());
2040 : VerifyPointer(isolate, callback());
2041 : VerifyPointer(isolate, named_interceptor());
2042 : VerifyPointer(isolate, indexed_interceptor());
2043 : VerifyPointer(isolate, data());
2044 : }
2045 :
2046 : void CallHandlerInfo::CallHandlerInfoVerify(Isolate* isolate) {
2047 : CHECK(IsCallHandlerInfo());
2048 : CHECK(map() == ReadOnlyRoots(isolate).side_effect_call_handler_info_map() ||
2049 : map() ==
2050 : ReadOnlyRoots(isolate).side_effect_free_call_handler_info_map() ||
2051 : map() == ReadOnlyRoots(isolate)
2052 : .next_call_side_effect_free_call_handler_info_map());
2053 : VerifyPointer(isolate, callback());
2054 : VerifyPointer(isolate, js_callback());
2055 : VerifyPointer(isolate, data());
2056 : }
2057 :
2058 : void InterceptorInfo::InterceptorInfoVerify(Isolate* isolate) {
2059 : CHECK(IsInterceptorInfo());
2060 : VerifyForeignPointer(isolate, *this, getter());
2061 : VerifyForeignPointer(isolate, *this, setter());
2062 : VerifyForeignPointer(isolate, *this, query());
2063 : VerifyForeignPointer(isolate, *this, deleter());
2064 : VerifyForeignPointer(isolate, *this, enumerator());
2065 : VerifyPointer(isolate, data());
2066 : VerifySmiField(kFlagsOffset);
2067 : }
2068 :
2069 : void TemplateInfo::TemplateInfoVerify(Isolate* isolate) {
2070 : VerifyPointer(isolate, tag());
2071 : VerifyPointer(isolate, property_list());
2072 : VerifyPointer(isolate, property_accessors());
2073 : }
2074 :
2075 : void FunctionTemplateInfo::FunctionTemplateInfoVerify(Isolate* isolate) {
2076 : CHECK(IsFunctionTemplateInfo());
2077 : TemplateInfoVerify(isolate);
2078 : VerifyPointer(isolate, serial_number());
2079 : VerifyPointer(isolate, call_code());
2080 : VerifyPointer(isolate, signature());
2081 : VerifyPointer(isolate, cached_property_name());
2082 : VerifyPointer(isolate, rare_data());
2083 : }
2084 :
2085 : void FunctionTemplateRareData::FunctionTemplateRareDataVerify(
2086 : Isolate* isolate) {
2087 : CHECK(IsFunctionTemplateRareData());
2088 : VerifyPointer(isolate, prototype_template());
2089 : VerifyPointer(isolate, parent_template());
2090 : VerifyPointer(isolate, named_property_handler());
2091 : VerifyPointer(isolate, indexed_property_handler());
2092 : VerifyPointer(isolate, instance_template());
2093 : VerifyPointer(isolate, access_check_info());
2094 : }
2095 :
2096 : void ObjectTemplateInfo::ObjectTemplateInfoVerify(Isolate* isolate) {
2097 : CHECK(IsObjectTemplateInfo());
2098 : TemplateInfoVerify(isolate);
2099 : VerifyPointer(isolate, constructor());
2100 : VerifyPointer(isolate, data());
2101 : }
2102 :
2103 : void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
2104 : CHECK(IsAllocationSite());
2105 : }
2106 :
2107 : void AllocationMemento::AllocationMementoVerify(Isolate* isolate) {
2108 : CHECK(IsAllocationMemento());
2109 : VerifyHeapPointer(isolate, allocation_site());
2110 : CHECK(!IsValid() || GetAllocationSite()->IsAllocationSite());
2111 : }
2112 :
2113 : void Script::ScriptVerify(Isolate* isolate) {
2114 : CHECK(IsScript());
2115 : VerifyPointer(isolate, source());
2116 : VerifyPointer(isolate, name());
2117 : VerifyPointer(isolate, line_ends());
2118 : for (int i = 0; i < shared_function_infos()->length(); ++i) {
2119 : MaybeObject maybe_object = shared_function_infos()->Get(i);
2120 : HeapObject heap_object;
2121 : CHECK(maybe_object->IsWeak() || maybe_object->IsCleared() ||
2122 : (maybe_object->GetHeapObjectIfStrong(&heap_object) &&
2123 : heap_object->IsUndefined(isolate)));
2124 : }
2125 : VerifySmiField(kIdOffset);
2126 : VerifySmiField(kLineOffsetOffset);
2127 : VerifySmiField(kColumnOffsetOffset);
2128 : VerifySmiField(kScriptTypeOffset);
2129 : VerifySmiField(kEvalFromPositionOffset);
2130 : VerifySmiField(kFlagsOffset);
2131 : }
2132 :
2133 : void NormalizedMapCache::NormalizedMapCacheVerify(Isolate* isolate) {
2134 : WeakFixedArray::cast(*this)->WeakFixedArrayVerify(isolate);
2135 : if (FLAG_enable_slow_asserts) {
2136 : for (int i = 0; i < length(); i++) {
2137 : MaybeObject e = WeakFixedArray::Get(i);
2138 : HeapObject heap_object;
2139 : if (e->GetHeapObjectIfWeak(&heap_object)) {
2140 : Map::cast(heap_object)->DictionaryMapVerify(isolate);
2141 : } else {
2142 : CHECK(e->IsCleared() || (e->GetHeapObjectIfStrong(&heap_object) &&
2143 : heap_object->IsUndefined(isolate)));
2144 : }
2145 : }
2146 : }
2147 : }
2148 :
2149 : void DebugInfo::DebugInfoVerify(Isolate* isolate) {
2150 : CHECK(IsDebugInfo());
2151 : VerifyPointer(isolate, shared());
2152 : VerifyPointer(isolate, script());
2153 : VerifyPointer(isolate, original_bytecode_array());
2154 : VerifyPointer(isolate, break_points());
2155 : }
2156 :
2157 : void StackTraceFrame::StackTraceFrameVerify(Isolate* isolate) {
2158 : CHECK(IsStackTraceFrame());
2159 : VerifySmiField(kFrameIndexOffset);
2160 : VerifySmiField(kIdOffset);
2161 : VerifyPointer(isolate, frame_array());
2162 : VerifyPointer(isolate, frame_info());
2163 : }
2164 :
2165 : void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) {
2166 : CHECK(IsStackFrameInfo());
2167 : VerifyPointer(isolate, script_name());
2168 : VerifyPointer(isolate, script_name_or_source_url());
2169 : VerifyPointer(isolate, function_name());
2170 : }
2171 :
2172 : void PreparseData::PreparseDataVerify(Isolate* isolate) {
2173 : CHECK(IsPreparseData());
2174 : CHECK_LE(0, data_length());
2175 : CHECK_LE(0, children_length());
2176 :
2177 : for (int i = 0; i < children_length(); ++i) {
2178 : Object child = get_child_raw(i);
2179 : CHECK(child->IsNull() || child->IsPreparseData());
2180 : VerifyPointer(isolate, child);
2181 : }
2182 : }
2183 :
2184 : void UncompiledDataWithPreparseData::UncompiledDataWithPreparseDataVerify(
2185 : Isolate* isolate) {
2186 : CHECK(IsUncompiledDataWithPreparseData());
2187 : VerifyPointer(isolate, inferred_name());
2188 : VerifyPointer(isolate, preparse_data());
2189 : }
2190 :
2191 : void UncompiledDataWithoutPreparseData::UncompiledDataWithoutPreparseDataVerify(
2192 : Isolate* isolate) {
2193 : CHECK(IsUncompiledDataWithoutPreparseData());
2194 : VerifyPointer(isolate, inferred_name());
2195 : }
2196 :
2197 : void InterpreterData::InterpreterDataVerify(Isolate* isolate) {
2198 : CHECK(IsInterpreterData());
2199 : VerifyObjectField(isolate, kBytecodeArrayOffset);
2200 : CHECK(bytecode_array()->IsBytecodeArray());
2201 : VerifyObjectField(isolate, kInterpreterTrampolineOffset);
2202 : CHECK(interpreter_trampoline()->IsCode());
2203 : }
2204 :
2205 : #ifdef V8_INTL_SUPPORT
2206 : void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
2207 : JSObjectVerify(isolate);
2208 : VerifyObjectField(isolate, kLocaleOffset);
2209 : VerifyObjectField(isolate, kTypeOffset);
2210 : VerifyObjectField(isolate, kBreakIteratorOffset);
2211 : VerifyObjectField(isolate, kUnicodeStringOffset);
2212 : VerifyObjectField(isolate, kBoundAdoptTextOffset);
2213 : VerifyObjectField(isolate, kBoundFirstOffset);
2214 : VerifyObjectField(isolate, kBoundNextOffset);
2215 : VerifyObjectField(isolate, kBoundCurrentOffset);
2216 : VerifyObjectField(isolate, kBoundBreakTypeOffset);
2217 : }
2218 :
2219 : void JSCollator::JSCollatorVerify(Isolate* isolate) {
2220 : CHECK(IsJSCollator());
2221 : JSObjectVerify(isolate);
2222 : VerifyObjectField(isolate, kICUCollatorOffset);
2223 : VerifyObjectField(isolate, kBoundCompareOffset);
2224 : }
2225 :
2226 : void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
2227 : JSObjectVerify(isolate);
2228 : VerifyObjectField(isolate, kICULocaleOffset);
2229 : VerifyObjectField(isolate, kICUSimpleDateFormatOffset);
2230 : VerifyObjectField(isolate, kICUDateIntervalFormatOffset);
2231 : VerifyObjectField(isolate, kBoundFormatOffset);
2232 : VerifyObjectField(isolate, kFlagsOffset);
2233 : }
2234 :
2235 : void JSListFormat::JSListFormatVerify(Isolate* isolate) {
2236 : JSObjectVerify(isolate);
2237 : VerifyObjectField(isolate, kLocaleOffset);
2238 : VerifyObjectField(isolate, kICUFormatterOffset);
2239 : VerifyObjectField(isolate, kFlagsOffset);
2240 : }
2241 :
2242 : void JSLocale::JSLocaleVerify(Isolate* isolate) {
2243 : JSObjectVerify(isolate);
2244 : VerifyObjectField(isolate, kICULocaleOffset);
2245 : }
2246 :
2247 : void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
2248 : CHECK(IsJSNumberFormat());
2249 : JSObjectVerify(isolate);
2250 : VerifyObjectField(isolate, kLocaleOffset);
2251 : VerifyObjectField(isolate, kICUNumberFormatOffset);
2252 : VerifyObjectField(isolate, kBoundFormatOffset);
2253 : VerifyObjectField(isolate, kFlagsOffset);
2254 : }
2255 :
2256 : void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
2257 : CHECK(IsJSPluralRules());
2258 : JSObjectVerify(isolate);
2259 : VerifyObjectField(isolate, kLocaleOffset);
2260 : VerifyObjectField(isolate, kFlagsOffset);
2261 : VerifyObjectField(isolate, kICUPluralRulesOffset);
2262 : VerifyObjectField(isolate, kICUDecimalFormatOffset);
2263 : }
2264 :
2265 : void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
2266 : JSObjectVerify(isolate);
2267 : VerifyObjectField(isolate, kLocaleOffset);
2268 : VerifyObjectField(isolate, kICUFormatterOffset);
2269 : VerifyObjectField(isolate, kFlagsOffset);
2270 : }
2271 :
2272 : void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) {
2273 : JSObjectVerify(isolate);
2274 : VerifyObjectField(isolate, kICUBreakIteratorOffset);
2275 : VerifyObjectField(isolate, kUnicodeStringOffset);
2276 : VerifyObjectField(isolate, kFlagsOffset);
2277 : }
2278 :
2279 : void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
2280 : JSObjectVerify(isolate);
2281 : VerifyObjectField(isolate, kLocaleOffset);
2282 : VerifyObjectField(isolate, kICUBreakIteratorOffset);
2283 : VerifyObjectField(isolate, kFlagsOffset);
2284 : }
2285 : #endif // V8_INTL_SUPPORT
2286 :
2287 : #endif // VERIFY_HEAP
2288 :
2289 : #ifdef DEBUG
2290 :
2291 : void JSObject::IncrementSpillStatistics(Isolate* isolate,
2292 : SpillInformation* info) {
2293 : info->number_of_objects_++;
2294 : // Named properties
2295 : if (HasFastProperties()) {
2296 : info->number_of_objects_with_fast_properties_++;
2297 : info->number_of_fast_used_fields_ += map()->NextFreePropertyIndex();
2298 : info->number_of_fast_unused_fields_ += map()->UnusedPropertyFields();
2299 : } else if (IsJSGlobalObject()) {
2300 : GlobalDictionary dict = JSGlobalObject::cast(*this)->global_dictionary();
2301 : info->number_of_slow_used_properties_ += dict->NumberOfElements();
2302 : info->number_of_slow_unused_properties_ +=
2303 : dict->Capacity() - dict->NumberOfElements();
2304 : } else {
2305 : NameDictionary dict = property_dictionary();
2306 : info->number_of_slow_used_properties_ += dict->NumberOfElements();
2307 : info->number_of_slow_unused_properties_ +=
2308 : dict->Capacity() - dict->NumberOfElements();
2309 : }
2310 : // Indexed properties
2311 : switch (GetElementsKind()) {
2312 : case HOLEY_SMI_ELEMENTS:
2313 : case PACKED_SMI_ELEMENTS:
2314 : case HOLEY_DOUBLE_ELEMENTS:
2315 : case PACKED_DOUBLE_ELEMENTS:
2316 : case HOLEY_ELEMENTS:
2317 : case PACKED_ELEMENTS:
2318 : case PACKED_FROZEN_ELEMENTS:
2319 : case PACKED_SEALED_ELEMENTS:
2320 : case FAST_STRING_WRAPPER_ELEMENTS: {
2321 : info->number_of_objects_with_fast_elements_++;
2322 : int holes = 0;
2323 : FixedArray e = FixedArray::cast(elements());
2324 : int len = e->length();
2325 : for (int i = 0; i < len; i++) {
2326 : if (e->get(i)->IsTheHole(isolate)) holes++;
2327 : }
2328 : info->number_of_fast_used_elements_ += len - holes;
2329 : info->number_of_fast_unused_elements_ += holes;
2330 : break;
2331 : }
2332 :
2333 : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
2334 :
2335 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2336 : #undef TYPED_ARRAY_CASE
2337 : {
2338 : info->number_of_objects_with_fast_elements_++;
2339 : FixedArrayBase e = FixedArrayBase::cast(elements());
2340 : info->number_of_fast_used_elements_ += e->length();
2341 : break;
2342 : }
2343 : case DICTIONARY_ELEMENTS:
2344 : case SLOW_STRING_WRAPPER_ELEMENTS: {
2345 : NumberDictionary dict = element_dictionary();
2346 : info->number_of_slow_used_elements_ += dict->NumberOfElements();
2347 : info->number_of_slow_unused_elements_ +=
2348 : dict->Capacity() - dict->NumberOfElements();
2349 : break;
2350 : }
2351 : case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
2352 : case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
2353 : case NO_ELEMENTS:
2354 : break;
2355 : }
2356 : }
2357 :
2358 :
2359 : void JSObject::SpillInformation::Clear() {
2360 : number_of_objects_ = 0;
2361 : number_of_objects_with_fast_properties_ = 0;
2362 : number_of_objects_with_fast_elements_ = 0;
2363 : number_of_fast_used_fields_ = 0;
2364 : number_of_fast_unused_fields_ = 0;
2365 : number_of_slow_used_properties_ = 0;
2366 : number_of_slow_unused_properties_ = 0;
2367 : number_of_fast_used_elements_ = 0;
2368 : number_of_fast_unused_elements_ = 0;
2369 : number_of_slow_used_elements_ = 0;
2370 : number_of_slow_unused_elements_ = 0;
2371 : }
2372 :
2373 :
2374 : void JSObject::SpillInformation::Print() {
2375 : PrintF("\n JSObject Spill Statistics (#%d):\n", number_of_objects_);
2376 :
2377 : PrintF(" - fast properties (#%d): %d (used) %d (unused)\n",
2378 : number_of_objects_with_fast_properties_,
2379 : number_of_fast_used_fields_, number_of_fast_unused_fields_);
2380 :
2381 : PrintF(" - slow properties (#%d): %d (used) %d (unused)\n",
2382 : number_of_objects_ - number_of_objects_with_fast_properties_,
2383 : number_of_slow_used_properties_, number_of_slow_unused_properties_);
2384 :
2385 : PrintF(" - fast elements (#%d): %d (used) %d (unused)\n",
2386 : number_of_objects_with_fast_elements_,
2387 : number_of_fast_used_elements_, number_of_fast_unused_elements_);
2388 :
2389 : PrintF(" - slow elements (#%d): %d (used) %d (unused)\n",
2390 : number_of_objects_ - number_of_objects_with_fast_elements_,
2391 : number_of_slow_used_elements_, number_of_slow_unused_elements_);
2392 :
2393 : PrintF("\n");
2394 : }
2395 :
2396 : bool DescriptorArray::IsSortedNoDuplicates(int valid_entries) {
2397 : if (valid_entries == -1) valid_entries = number_of_descriptors();
2398 : Name current_key;
2399 : uint32_t current = 0;
2400 : for (int i = 0; i < number_of_descriptors(); i++) {
2401 : Name key = GetSortedKey(i);
2402 : if (key == current_key) {
2403 : Print();
2404 : return false;
2405 : }
2406 : current_key = key;
2407 : uint32_t hash = GetSortedKey(i)->Hash();
2408 : if (hash < current) {
2409 : Print();
2410 : return false;
2411 : }
2412 : current = hash;
2413 : }
2414 : return true;
2415 : }
2416 :
2417 : bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
2418 : DCHECK_EQ(valid_entries, -1);
2419 : Name prev_key;
2420 : PropertyKind prev_kind = kData;
2421 : PropertyAttributes prev_attributes = NONE;
2422 : uint32_t prev_hash = 0;
2423 :
2424 : for (int i = 0; i < number_of_transitions(); i++) {
2425 : Name key = GetSortedKey(i);
2426 : uint32_t hash = key->Hash();
2427 : PropertyKind kind = kData;
2428 : PropertyAttributes attributes = NONE;
2429 : if (!TransitionsAccessor::IsSpecialTransition(key->GetReadOnlyRoots(),
2430 : key)) {
2431 : Map target = GetTarget(i);
2432 : PropertyDetails details =
2433 : TransitionsAccessor::GetTargetDetails(key, target);
2434 : kind = details.kind();
2435 : attributes = details.attributes();
2436 : } else {
2437 : // Duplicate entries are not allowed for non-property transitions.
2438 : DCHECK_NE(prev_key, key);
2439 : }
2440 :
2441 : int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
2442 : hash, kind, attributes);
2443 : if (cmp >= 0) {
2444 : Print();
2445 : return false;
2446 : }
2447 : prev_key = key;
2448 : prev_hash = hash;
2449 : prev_attributes = attributes;
2450 : prev_kind = kind;
2451 : }
2452 : return true;
2453 : }
2454 :
2455 : bool TransitionsAccessor::IsSortedNoDuplicates() {
2456 : // Simple and non-existent transitions are always sorted.
2457 : if (encoding() != kFullTransitionArray) return true;
2458 : return transitions()->IsSortedNoDuplicates();
2459 : }
2460 :
2461 : static bool CheckOneBackPointer(Map current_map, Object target) {
2462 : return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
2463 : }
2464 :
2465 : bool TransitionsAccessor::IsConsistentWithBackPointers() {
2466 : int num_transitions = NumberOfTransitions();
2467 : for (int i = 0; i < num_transitions; i++) {
2468 : Map target = GetTarget(i);
2469 : if (!CheckOneBackPointer(map_, target)) return false;
2470 : }
2471 : return true;
2472 : }
2473 :
2474 : #endif // DEBUG
2475 :
2476 : } // namespace internal
2477 121996 : } // namespace v8
|