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