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