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