objects-debug.cc 82.1 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// 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 18
#include "src/layout-descriptor.h"
#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 35
#include "src/objects/js-collator-inl.h"
#endif  // V8_INTL_SUPPORT
36
#include "src/objects/js-collection-inl.h"
37 38 39
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-date-time-format-inl.h"
#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 45
#include "src/objects/js-number-format-inl.h"
#include "src/objects/js-plural-rules-inl.h"
46
#endif  // V8_INTL_SUPPORT
47 48
#include "src/objects/js-regexp-inl.h"
#include "src/objects/js-regexp-string-iterator-inl.h"
49 50
#ifdef V8_INTL_SUPPORT
#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 69
namespace v8 {
namespace internal {
70

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
// Heap Verification Overview
// --------------------------
// - Each InstanceType has a separate XXXVerify method which checks an object's
//   integrity in isolation.
// - --verify-heap will iterate over all gc spaces and call ObjectVerify() on
//   every encountered tagged pointer.
// - Verification should be pushed down to the specific instance type if its
//   integrity is independent of an outer object.
// - In cases where the InstanceType is too genernic (e.g. FixedArray) the
//   XXXVerify of the outer method has to do recursive verification.
// - If the corresponding objects have inheritence the parent's Verify method
//   is called as well.
// - For any field containing pointes VerifyPointer(...) should be called.
//
// Caveats
// -------
// - Assume that any of the verify methods is incomplete!
// - Some integrity checks are only partially done due to objects being in
//   partially initialized states when a gc happens, for instance when outer
//   objects are allocted before inner ones.
//

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 142
    STRING_TYPE_LIST(STRING_TYPE_CASE)
#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 151
      break;
    case HEAP_NUMBER_TYPE:
152 153
      CHECK(IsHeapNumber());
      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 166
          ->ObjectBoilerplateDescriptionVerify(isolate);
      break;
167
    case EMBEDDER_DATA_ARRAY_TYPE:
168
      EmbedderDataArray::cast(*this)->EmbedderDataArrayVerify(isolate);
169
      break;
170
    // FixedArray types
171
    case HASH_TABLE_TYPE:
172 173
    case ORDERED_HASH_MAP_TYPE:
    case ORDERED_HASH_SET_TYPE:
174
    case ORDERED_NAME_DICTIONARY_TYPE:
175 176 177 178 179
    case NAME_DICTIONARY_TYPE:
    case GLOBAL_DICTIONARY_TYPE:
    case NUMBER_DICTIONARY_TYPE:
    case SIMPLE_NUMBER_DICTIONARY_TYPE:
    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 188 189 190 191 192 193 194
    case BLOCK_CONTEXT_TYPE:
    case CATCH_CONTEXT_TYPE:
    case DEBUG_EVALUATE_CONTEXT_TYPE:
    case EVAL_CONTEXT_TYPE:
    case FUNCTION_CONTEXT_TYPE:
    case MODULE_CONTEXT_TYPE:
    case SCRIPT_CONTEXT_TYPE:
    case WITH_CONTEXT_TYPE:
195
      Context::cast(*this)->ContextVerify(isolate);
196 197
      break;
    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 238 239
#define VERIFY_TYPED_ARRAY(Type, type, TYPE, ctype)                  \
  case FIXED_##TYPE##_ARRAY_TYPE:                                    \
    Fixed##Type##Array::cast(*this)->FixedTypedArrayVerify(isolate); \
240
    break;
241

242
      TYPED_ARRAYS(VERIFY_TYPED_ARRAY)
243 244
#undef VERIFY_TYPED_ARRAY

245
    case CODE_TYPE:
246
      Code::cast(*this)->CodeVerify(isolate);
247 248
      break;
    case ODDBALL_TYPE:
249
      Oddball::cast(*this)->OddballVerify(isolate);
250 251
      break;
    case JS_OBJECT_TYPE:
252
    case JS_ERROR_TYPE:
253
    case JS_API_OBJECT_TYPE:
254
    case JS_SPECIAL_API_OBJECT_TYPE:
ager@chromium.org's avatar
ager@chromium.org committed
255
    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
256
    case WASM_EXCEPTION_TYPE:
257
    case WASM_GLOBAL_TYPE:
258 259
    case WASM_MEMORY_TYPE:
    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 279
      JSAsyncGeneratorObject::cast(*this)->JSAsyncGeneratorObjectVerify(
          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 302
      break;
    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 314
      break;
    case JS_MAP_TYPE:
315
      JSMap::cast(*this)->JSMapVerify(isolate);
316
      break;
317 318
    case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    case JS_SET_VALUE_ITERATOR_TYPE:
319
      JSSetIterator::cast(*this)->JSSetIteratorVerify(isolate);
320
      break;
321 322 323
    case JS_MAP_KEY_ITERATOR_TYPE:
    case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    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 337
    case WEAK_CELL_TYPE:
      WeakCell::cast(*this)->WeakCellVerify(isolate);
338
      break;
339
    case JS_WEAK_REF_TYPE:
340
      JSWeakRef::cast(*this)->JSWeakRefVerify(isolate);
341
      break;
342 343
    case JS_FINALIZATION_GROUP_TYPE:
      JSFinalizationGroup::cast(*this)->JSFinalizationGroupVerify(isolate);
344
      break;
345 346 347
    case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
      JSFinalizationGroupCleanupIterator::cast(*this)
          ->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 363
      JSRegExpStringIterator::cast(*this)->JSRegExpStringIteratorVerify(
          isolate);
364
      break;
365 366
    case FILLER_TYPE:
      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 378
      UncompiledDataWithoutPreparseData::cast(*this)
          ->UncompiledDataWithoutPreparseDataVerify(isolate);
379
      break;
380
    case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
381 382
      UncompiledDataWithPreparseData::cast(*this)
          ->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 402
      break;
    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 408
          isolate);
      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 446 447
#define MAKE_STRUCT_CASE(TYPE, Name, name)    \
  case TYPE:                                  \
    Name::cast(*this)->Name##Verify(isolate); \
448
    break;
449
      STRUCT_LIST(MAKE_STRUCT_CASE)
450 451
#undef MAKE_STRUCT_CASE

452
    case ALLOCATION_SITE_TYPE:
453
      AllocationSite::cast(*this)->AllocationSiteVerify(isolate);
454 455
      break;

456
    case LOAD_HANDLER_TYPE:
457
      LoadHandler::cast(*this)->LoadHandlerVerify(isolate);
458 459 460
      break;

    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 474
  CHECK(IsSymbol());
  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 485 486 487
  // - All bytecodes are known and well formed.
  // - Jumps must go to new instructions starts.
  // - No Illegal bytecodes.
  // - 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 500 501
  CHECK(value()->IsUndefined(isolate) || value()->IsFeedbackVector());
}

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 512
  CHECK(IsHeapObject() && map()->instance_type() == Traits::kInstanceType);
  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 522
  // If a GC was caused while constructing this object, the elements
  // 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 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
  // Only TypedArrays can have these specialized elements.
  if (object->IsJSTypedArray()) {
    // TODO(cbruni): Fix CreateTypedArray to either not instantiate the object
    // or propertly initialize it on errors during construction.
    /* CHECK(object->HasFixedTypedArrayElements()); */
    /* CHECK(object->elements()->IsFixedTypedArrayBase()); */
    return;
  }
  CHECK(!object->HasFixedTypedArrayElements());
  CHECK(!object->elements()->IsFixedTypedArrayBase());

  if (object->HasDoubleElements()) {
    if (object->elements()->length() > 0) {
      CHECK(object->elements()->IsFixedDoubleArray());
    }
    return;
  }

546
  FixedArray elements = FixedArray::cast(object->elements());
547 548 549 550
  if (object->HasSmiElements()) {
    // We might have a partially initialized backing store, in which case we
    // allow the hole + smi values.
    for (int i = 0; i < elements->length(); i++) {
551
      Object value = elements->get(i);
552 553 554 555
      CHECK(value->IsSmi() || value->IsTheHole(isolate));
    }
  } else if (object->HasObjectElements()) {
    for (int i = 0; i < elements->length(); i++) {
556
      Object element = elements->get(i);
557 558 559 560 561
      CHECK_IMPLIES(!element->IsSmi(), !HasWeakHeapObjectTag(element));
    }
  }
}
}  // namespace
562

563
void JSObject::JSObjectVerify(Isolate* isolate) {
564 565
  VerifyPointer(isolate, raw_properties_or_hash());
  VerifyHeapPointer(isolate, elements());
566

567
  CHECK_IMPLIES(HasSloppyArgumentsElements(), IsJSArgumentsObject());
568 569
  if (HasFastProperties()) {
    int actual_unused_property_fields = map()->GetInObjectProperties() +
570
                                        property_array()->length() -
571
                                        map()->NextFreePropertyIndex();
572
    if (map()->UnusedPropertyFields() != actual_unused_property_fields) {
573 574 575 576 577 578
      // There are two reasons why this can happen:
      // - in the middle of StoreTransitionStub when the new extended backing
      //   store is already set into the object and the allocation of the
      //   MutableHeapNumber triggers GC while the map isn't updated yet.
      // - deletion of the last property can leave additional backing store
      //   capacity behind.
579 580
      CHECK_GT(actual_unused_property_fields, map()->UnusedPropertyFields());
      int delta = actual_unused_property_fields - map()->UnusedPropertyFields();
581
      CHECK_EQ(0, delta % JSObject::kFieldsAdded);
582
    }
583
    DescriptorArray descriptors = map()->instance_descriptors();
584 585 586
    bool is_transitionable_fast_elements_kind =
        IsTransitionableFastElementsKind(map()->elements_kind());

587
    for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
588 589 590
      PropertyDetails details = descriptors->GetDetails(i);
      if (details.location() == kField) {
        DCHECK_EQ(kData, details.kind());
591
        Representation r = details.representation();
592 593 594 595 596
        FieldIndex index = FieldIndex::ForDescriptor(map(), i);
        if (IsUnboxedDoubleField(index)) {
          DCHECK(r.IsDouble());
          continue;
        }
597 598 599
        if (COMPRESS_POINTERS_BOOL && index.is_inobject()) {
          VerifyObjectField(isolate, index.offset());
        }
600
        Object value = RawFastPropertyAt(index);
601 602 603 604
        if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
        if (value->IsUninitialized(isolate)) continue;
        if (r.IsSmi()) DCHECK(value->IsSmi());
        if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
605
        FieldType field_type = descriptors->GetFieldType(i);
606 607 608 609 610
        bool type_is_none = field_type->IsNone();
        bool type_is_any = field_type->IsAny();
        if (r.IsNone()) {
          CHECK(type_is_none);
        } 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 621
      FixedArray keys = enum_cache->keys();
      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 629 630 631
  // If a GC was caused while constructing this object, the elements
  // pointer may point to a one pointer filler map.
  if (ElementsAreSafeToExamine()) {
    CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
632
              (elements() == GetReadOnlyRoots().empty_fixed_array()) ||
633
              HasFastStringWrapperElements()),
634 635
             (elements()->map() == GetReadOnlyRoots().fixed_array_map() ||
              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 651
  HeapObject::VerifyHeapPointer(isolate, prototype());
  HeapObject::VerifyHeapPointer(isolate, instance_descriptors());
652
  SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
653
  DisallowHeapAllocation no_gc;
654
  SLOW_DCHECK(
655 656
      TransitionsAccessor(isolate, *this, &no_gc).IsSortedNoDuplicates());
  SLOW_DCHECK(TransitionsAccessor(isolate, *this, &no_gc)
657
                  .IsConsistentWithBackPointers());
658
  SLOW_DCHECK(!FLAG_unbox_double_fields ||
659
              layout_descriptor()->IsConsistentWithMap(*this));
660 661 662 663
  if (!may_have_interesting_symbols()) {
    CHECK(!has_named_interceptor());
    CHECK(!is_dictionary_map());
    CHECK(!is_access_check_needed());
664
    DescriptorArray const descriptors = instance_descriptors();
665 666 667 668 669 670 671
    for (int i = 0; i < NumberOfOwnDescriptors(); ++i) {
      CHECK(!descriptors->GetKey(i)->IsInterestingSymbol());
    }
  }
  CHECK_IMPLIES(has_named_interceptor(), may_have_interesting_symbols());
  CHECK_IMPLIES(is_dictionary_map(), may_have_interesting_symbols());
  CHECK_IMPLIES(is_access_check_needed(), may_have_interesting_symbols());
672 673 674
  CHECK_IMPLIES(IsJSObjectMap() && !CanHaveFastTransitionableElementsKind(),
                IsDictionaryElementsKind(elements_kind()) ||
                    IsTerminalElementsKind(elements_kind()));
675
  CHECK_IMPLIES(is_deprecated(), !is_stable());
676 677 678 679
  if (is_prototype_map()) {
    DCHECK(prototype_info() == Smi::kZero ||
           prototype_info()->IsPrototypeInfo());
  }
680 681
  CHECK(prototype_validity_cell()->IsSmi() ||
        prototype_validity_cell()->IsCell());
682 683
}

684 685
void Map::DictionaryMapVerify(Isolate* isolate) {
  MapVerify(isolate);
686
  CHECK(is_dictionary_map());
687
  CHECK_EQ(kInvalidEnumCacheSentinel, EnumLength());
688 689
  CHECK_EQ(ReadOnlyRoots(isolate).empty_descriptor_array(),
           instance_descriptors());
690
  CHECK_EQ(0, UnusedPropertyFields());
691
  CHECK_EQ(Map::GetVisitorId(*this), visitor_id());
692 693
}

694
void AliasedArgumentsEntry::AliasedArgumentsEntryVerify(Isolate* isolate) {
695 696 697
  VerifySmiField(kAliasedContextSlot);
}

698
void EmbedderDataArray::EmbedderDataArrayVerify(Isolate* isolate) {
699 700 701
  EmbedderDataSlot start(*this, 0);
  EmbedderDataSlot end(*this, length());
  for (EmbedderDataSlot slot = start; slot < end; ++slot) {
702
    Object e = slot.load_tagged();
703 704 705 706
    Object::VerifyPointer(isolate, e);
  }
}

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 730 731 732
    return;
  }
  // There are no empty PropertyArrays.
  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 741
  for (int i = 0; i < length(); i++) {
    if (!is_the_hole(i)) {
742
      uint64_t value = get_representation(i);
743 744
      uint64_t unexpected =
          bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()) &
745
          uint64_t{0x7FF8000000000000};
746
      // Create implementation specific sNaN by inverting relevant bit.
747 748 749
      unexpected ^= uint64_t{0x0008000000000000};
      CHECK((value & uint64_t{0x7FF8000000000000}) != unexpected ||
            (value & uint64_t{0x0007FFFFFFFFFFFF}) == uint64_t{0});
750 751 752 753
    }
  }
}

754 755 756 757 758 759 760 761 762 763
void Context::ContextVerify(Isolate* isolate) {
  VerifySmiField(kLengthOffset);
  VerifyObjectField(isolate, kScopeInfoOffset);
  VerifyObjectField(isolate, kPreviousOffset);
  VerifyObjectField(isolate, kExtensionOffset);
  VerifyObjectField(isolate, kNativeContextOffset);
  for (int i = 0; i < length(); i++) {
    VerifyObjectField(isolate, OffsetOfElementAt(i));
  }
}
764 765

void NativeContext::NativeContextVerify(Isolate* isolate) {
766
  ContextVerify(isolate);
767 768 769 770
  CHECK_EQ(length(), NativeContext::NATIVE_CONTEXT_SLOTS);
  CHECK_EQ(kSize, map()->instance_size());
}

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 777 778 779 780 781 782 783 784
    while (iter.HasNext()) {
      iter.Next();
      FeedbackSlotKind kind = iter.kind();
      CHECK_NE(FeedbackSlotKind::kInvalid, kind);
      CHECK_GT(FeedbackSlotKind::kKindsNumber, kind);
    }
  }
}

785
void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) {
786 787 788 789 790 791
  for (int i = 0; i < number_of_all_descriptors(); i++) {
    MaybeObject::VerifyMaybeObjectPointer(isolate, get(ToKeyIndex(i)));
    MaybeObject::VerifyMaybeObjectPointer(isolate, get(ToDetailsIndex(i)));
    MaybeObject::VerifyMaybeObjectPointer(isolate, get(ToValueIndex(i)));
  }
  if (number_of_all_descriptors() == 0) {
792
    Heap* heap = isolate->heap();
793
    CHECK_EQ(ReadOnlyRoots(heap).empty_descriptor_array(), *this);
794 795 796
    CHECK_EQ(0, number_of_all_descriptors());
    CHECK_EQ(0, number_of_descriptors());
    CHECK_EQ(ReadOnlyRoots(heap).empty_enum_cache(), enum_cache());
797
  } else {
798 799
    CHECK_LT(0, number_of_all_descriptors());
    CHECK_LE(number_of_descriptors(), number_of_all_descriptors());
800 801

    // Check that properties with private symbols names are non-enumerable.
802 803
    for (int descriptor = 0; descriptor < number_of_descriptors();
         descriptor++) {
804
      Object key = get(ToKeyIndex(descriptor))->cast<Object>();
805 806 807
      // number_of_descriptors() may be out of sync with the actual descriptors
      // written during descriptor array construction.
      if (key->IsUndefined(isolate)) continue;
808
      PropertyDetails details = GetDetails(descriptor);
809 810 811
      if (Name::cast(key)->IsPrivate()) {
        CHECK_NE(details.attributes() & DONT_ENUM, 0);
      }
812
      MaybeObject value = get(ToValueIndex(descriptor));
813
      HeapObject heap_object;
814
      if (details.location() == kField) {
815 816 817 818 819
        CHECK(
            value == MaybeObject::FromObject(FieldType::None()) ||
            value == MaybeObject::FromObject(FieldType::Any()) ||
            value->IsCleared() ||
            (value->GetHeapObjectIfWeak(&heap_object) && heap_object->IsMap()));
820
      } else {
821 822
        CHECK(!value->IsWeakOrCleared());
        CHECK(!value->cast<Object>()->IsMap());
823
      }
824
    }
825 826
  }
}
827

828 829
void TransitionArray::TransitionArrayVerify(Isolate* isolate) {
  WeakFixedArrayVerify(isolate);
830 831 832
  CHECK_LE(LengthFor(number_of_transitions()), length());
}

833
void JSArgumentsObject::JSArgumentsObjectVerify(Isolate* isolate) {
834
  if (IsSloppyArgumentsElementsKind(GetElementsKind())) {
835
    SloppyArgumentsElements::cast(elements())
836
        ->SloppyArgumentsElementsVerify(isolate, *this);
837 838 839 840 841 842
  }
  if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) ||
      isolate->IsInAnyContext(map(),
                              Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) ||
      isolate->IsInAnyContext(map(),
                              Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) {
843 844
    VerifyObjectField(isolate, JSSloppyArgumentsObject::kLengthOffset);
    VerifyObjectField(isolate, JSSloppyArgumentsObject::kCalleeOffset);
845 846
  } else if (isolate->IsInAnyContext(map(),
                                     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 856 857
  // Abort verification if only partially initialized (can't use arguments()
  // getter because it does FixedArray::cast()).
  if (get(kArgumentsIndex)->IsUndefined(isolate)) return;
858 859

  ElementsKind kind = holder->GetElementsKind();
860
  bool is_fast = kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
861 862
  CHECK(IsFixedArray());
  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 869 870
    return;
  }
  ElementsAccessor* accessor;
871
  if (is_fast) {
872
    accessor = ElementsAccessor::ForKind(HOLEY_ELEMENTS);
873 874 875
  } else {
    accessor = ElementsAccessor::ForKind(DICTIONARY_ELEMENTS);
  }
876 877
  int nofMappedParameters = 0;
  int maxMappedIndex = 0;
878 879 880
  for (int i = 0; i < nofMappedParameters; i++) {
    // Verify that each context-mapped argument is either the hole or a valid
    // Smi within context length range.
881
    Object mapped = get_mapped_entry(i);
882 883 884 885 886 887 888 889
    if (mapped->IsTheHole(isolate)) {
      // Slow sloppy arguments can be holey.
      if (!is_fast) continue;
      // Fast sloppy arguments elements are never holey. Either the element is
      // context-mapped or present in the arguments elements.
      CHECK(accessor->HasElement(holder, i, arg_elements));
      continue;
    }
jgruber's avatar
jgruber committed
890
    int mappedIndex = Smi::ToInt(mapped);
891 892 893
    nofMappedParameters++;
    CHECK_LE(maxMappedIndex, mappedIndex);
    maxMappedIndex = mappedIndex;
894
    Object value = context_object->get(mappedIndex);
895 896
    CHECK(value->IsObject());
    // None of the context-mapped entries should exist in the arguments
897
    // elements.
898 899
    CHECK(!accessor->HasElement(holder, i, arg_elements));
  }
900 901 902 903
  CHECK_LE(nofMappedParameters, context_object->length());
  CHECK_LE(nofMappedParameters, arg_elements->length());
  CHECK_LE(maxMappedIndex, context_object->length());
  CHECK_LE(maxMappedIndex, arg_elements->length());
904
}
905

906
void JSGeneratorObject::JSGeneratorObjectVerify(Isolate* isolate) {
907 908 909
  // In an expression like "new g()", there can be a point where a generator
  // object is allocated but its fields are all undefined, as it hasn't yet been
  // initialized by the generator.  Hence these weak checks.
910 911 912 913 914
  VerifyObjectField(isolate, kFunctionOffset);
  VerifyObjectField(isolate, kContextOffset);
  VerifyObjectField(isolate, kReceiverOffset);
  VerifyObjectField(isolate, kParametersAndRegistersOffset);
  VerifyObjectField(isolate, kContinuationOffset);
915 916
}

917 918 919 920 921 922 923
void JSAsyncFunctionObject::JSAsyncFunctionObjectVerify(Isolate* isolate) {
  // Check inherited fields
  JSGeneratorObjectVerify(isolate);
  VerifyObjectField(isolate, kPromiseOffset);
  promise()->HeapObjectVerify(isolate);
}

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 943 944 945 946 947 948 949 950 951 952
  CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
        value()->IsHeapNumber());
  CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
  CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
  CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
  CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
        weekday()->IsNaN());
  CHECK(hour()->IsUndefined(isolate) || hour()->IsSmi() || hour()->IsNaN());
  CHECK(min()->IsUndefined(isolate) || min()->IsSmi() || min()->IsNaN());
  CHECK(sec()->IsUndefined(isolate) || sec()->IsSmi() || sec()->IsNaN());
  CHECK(cache_stamp()->IsUndefined(isolate) || cache_stamp()->IsSmi() ||
953 954
        cache_stamp()->IsNaN());

955
  if (month()->IsSmi()) {
jgruber's avatar
jgruber committed
956
    int month = Smi::ToInt(this->month());
957 958 959
    CHECK(0 <= month && month <= 11);
  }
  if (day()->IsSmi()) {
jgruber's avatar
jgruber committed
960
    int day = Smi::ToInt(this->day());
961 962 963
    CHECK(1 <= day && day <= 31);
  }
  if (hour()->IsSmi()) {
jgruber's avatar
jgruber committed
964
    int hour = Smi::ToInt(this->hour());
965 966 967
    CHECK(0 <= hour && hour <= 23);
  }
  if (min()->IsSmi()) {
jgruber's avatar
jgruber committed
968
    int min = Smi::ToInt(this->min());
969 970 971
    CHECK(0 <= min && min <= 59);
  }
  if (sec()->IsSmi()) {
jgruber's avatar
jgruber committed
972
    int sec = Smi::ToInt(this->sec());
973 974 975
    CHECK(0 <= sec && sec <= 59);
  }
  if (weekday()->IsSmi()) {
jgruber's avatar
jgruber committed
976
    int weekday = Smi::ToInt(this->weekday());
977
    CHECK(0 <= weekday && weekday <= 6);
978
  }
979
  if (cache_stamp()->IsSmi()) {
jgruber's avatar
jgruber committed
980 981
    CHECK(Smi::ToInt(cache_stamp()) <=
          Smi::ToInt(isolate->date_cache()->stamp()));
982
  }
983 984
}

985
void JSMessageObject::JSMessageObjectVerify(Isolate* isolate) {
986
  CHECK(IsJSMessageObject());
987 988 989 990 991
  VerifyObjectField(isolate, kStartPositionOffset);
  VerifyObjectField(isolate, kEndPositionOffset);
  VerifyObjectField(isolate, kArgumentsOffset);
  VerifyObjectField(isolate, kScriptOffset);
  VerifyObjectField(isolate, kStackFramesOffset);
992 993
}

994
void String::StringVerify(Isolate* isolate) {
995 996
  CHECK(IsString());
  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 1018 1019 1020
    // A flat cons can only be created by String::SlowFlatten.
    // Afterwards, the first part may be externalized or internalized.
    CHECK(this->first()->IsSeqString() || this->first()->IsExternalString() ||
          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 1031
  CHECK(!this->parent()->IsConsString());
  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 1039 1040
  VerifyObjectField(isolate, kBoundThisOffset);
  VerifyObjectField(isolate, kBoundTargetFunctionOffset);
  VerifyObjectField(isolate, kBoundArgumentsOffset);
1041 1042
  CHECK(IsCallable());

1043 1044 1045 1046 1047
  if (!raw_bound_target_function()->IsUndefined(isolate)) {
    CHECK(bound_target_function()->IsCallable());
    CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
  }
}
1048

1049
void JSFunction::JSFunctionVerify(Isolate* isolate) {
1050
  CHECK(IsJSFunction());
1051
  JSObjectVerify(isolate);
1052 1053
  VerifyHeapPointer(isolate, raw_feedback_cell());
  CHECK(raw_feedback_cell()->IsFeedbackCell());
1054
  CHECK(code()->IsCode());
1055
  CHECK(map()->is_callable());
1056
  Handle<JSFunction> function(*this, isolate);
1057 1058
  LookupIterator it(isolate, function, isolate->factory()->prototype_string(),
                    LookupIterator::OWN_SKIP_INTERCEPTOR);
1059
  if (has_prototype_slot()) {
1060
    VerifyObjectField(isolate, kPrototypeOrInitialMapOffset);
1061
  }
1062 1063 1064 1065 1066 1067 1068 1069 1070

  if (has_prototype_property()) {
    CHECK(it.IsFound());
    CHECK_EQ(LookupIterator::ACCESSOR, it.state());
    CHECK(it.GetAccessors()->IsAccessorInfo());
  } else {
    CHECK(!it.IsFound() || it.state() != LookupIterator::ACCESSOR ||
          !it.GetAccessors()->IsAccessorInfo());
  }
1071 1072
}

1073
void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) {
1074
  CHECK(IsSharedFunctionInfo());
1075

1076 1077
  VerifyObjectField(isolate, kFunctionDataOffset);
  VerifyObjectField(isolate, kOuterScopeInfoOrFeedbackMetadataOffset);
1078
  VerifyObjectField(isolate, kScriptOrDebugInfoOffset);
1079
  VerifyObjectField(isolate, kNameOrScopeInfoOffset);
1080

1081
  Object value = name_or_scope_info();
1082 1083 1084 1085
  CHECK(value == kNoSharedNameSentinel || value->IsString() ||
        value->IsScopeInfo());
  if (value->IsScopeInfo()) {
    CHECK_LT(0, ScopeInfo::cast(value)->length());
1086
    CHECK_NE(value, ReadOnlyRoots(isolate).empty_scope_info());
1087
  }
1088

1089 1090
  CHECK(HasWasmExportedFunctionData() || IsApiFunction() ||
        HasBytecodeArray() || HasAsmWasmData() || HasBuiltinId() ||
1091 1092
        HasUncompiledDataWithPreparseData() ||
        HasUncompiledDataWithoutPreparseData());
1093

1094 1095
  CHECK(script_or_debug_info()->IsUndefined(isolate) ||
        script_or_debug_info()->IsScript() || HasDebugInfo());
1096

1097 1098 1099 1100
  if (!is_compiled()) {
    CHECK(!HasFeedbackMetadata());
    CHECK(outer_scope_info()->IsScopeInfo() ||
          outer_scope_info()->IsTheHole(isolate));
1101
  } else if (HasBytecodeArray() && HasFeedbackMetadata()) {
1102 1103 1104
    CHECK(feedback_metadata()->IsFeedbackMetadata());
  }

1105
  int expected_map_index = Context::FunctionMapIndex(
1106
      language_mode(), kind(), HasSharedName(), needs_home_object());
1107 1108
  CHECK_EQ(expected_map_index, function_map_index());

1109
  if (scope_info()->length() > 0) {
1110
    ScopeInfo info = scope_info();
1111 1112
    CHECK(kind() == info->function_kind());
    CHECK_EQ(kind() == kModule, info->scope_type() == MODULE_SCOPE);
1113
  }
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126

  if (IsApiFunction()) {
    CHECK(construct_as_builtin());
  } else if (!HasBuiltinId()) {
    CHECK(!construct_as_builtin());
  } else {
    int id = builtin_id();
    if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
      CHECK(construct_as_builtin());
    } else {
      CHECK(!construct_as_builtin());
    }
  }
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());
yangguo's avatar
yangguo committed
1140
  // Do not check the dummy global object for the builtins.
1141
  if (global_dictionary()->NumberOfElements() == 0 &&
yangguo's avatar
yangguo committed
1142 1143
      elements()->length() == 0) {
    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 1155
    CHECK(number == ReadOnlyRoots(heap).nan_value() ||
          number == ReadOnlyRoots(heap).hole_nan_value());
1156
  } else {
1157
    CHECK(number->IsSmi());
jgruber's avatar
jgruber committed
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 1166

  ReadOnlyRoots roots(heap);
  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 1188
    // Multiple instances of this oddball may exist at once.
    CHECK_EQ(kind(), Oddball::kSelfReferenceMarker);
1189 1190 1191
  } else {
    UNREACHABLE();
  }
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
}
ulan@chromium.org's avatar
ulan@chromium.org committed
1209

1210
void Code::CodeVerify(Isolate* isolate) {
1211 1212 1213 1214
  CHECK_IMPLIES(
      has_safepoint_table(),
      IsAligned(safepoint_table_offset(), static_cast<unsigned>(kIntSize)));
  CHECK_LE(safepoint_table_offset(), handler_table_offset());
1215
  CHECK_LE(handler_table_offset(), constant_pool_offset());
1216 1217
  CHECK_LE(constant_pool_offset(), code_comments_offset());
  CHECK_LE(code_comments_offset(), InstructionSize());
1218
  CHECK(IsAligned(raw_instruction_start(), kCodeAlignment));
1219
  relocation_info()->ObjectVerify(isolate);
1220 1221
  CHECK(Code::SizeFor(body_size()) <= kMaxRegularHeapObjectSize ||
        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 1229 1230
      CHECK(it.rinfo()->pc() != last_gc_pc);
      last_gc_pc = it.rinfo()->pc();
    }
1231 1232 1233
  }
}

1234 1235
void JSArray::JSArrayVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
1236
  CHECK(length()->IsNumber() || length()->IsUndefined(isolate));
1237 1238
  // If a GC was caused while constructing this array, the elements
  // pointer may point to a one pointer filler map.
1239 1240 1241
  if (!ElementsAreSafeToExamine()) return;
  if (elements()->IsUndefined(isolate)) return;
  CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
1242
  if (elements()->length() == 0) {
1243
    CHECK_EQ(elements(), ReadOnlyRoots(isolate).empty_fixed_array());
1244
  }
1245 1246 1247
  if (!length()->IsNumber()) return;
  // Verify that the length and the elements backing store are in sync.
  if (length()->IsSmi() && HasFastElements()) {
1248 1249
    if (elements()->length() > 0) {
      CHECK_IMPLIES(HasDoubleElements(), elements()->IsFixedDoubleArray());
1250
      CHECK_IMPLIES(HasSmiOrObjectElements(), elements()->IsFixedArray());
1251
    }
jgruber's avatar
jgruber committed
1252
    int size = Smi::ToInt(length());
1253 1254 1255
    // Holey / Packed backing stores might have slack or might have not been
    // properly initialized yet.
    CHECK(size <= elements()->length() ||
1256
          elements() == ReadOnlyRoots(isolate).empty_fixed_array());
1257 1258
  } else {
    CHECK(HasDictionaryElements());
1259 1260
    uint32_t array_length;
    CHECK(length()->ToArrayLength(&array_length));
1261
    if (array_length == 0xFFFFFFFF) {
1262 1263 1264
      CHECK(length()->ToArrayLength(&array_length));
    }
    if (array_length != 0) {
1265
      NumberDictionary dict = NumberDictionary::cast(elements());
1266 1267 1268 1269 1270 1271
      // The dictionary can never have more elements than the array length + 1.
      // If the backing store grows the verification might be triggered with
      // the old length in place.
      uint32_t nof_elements = static_cast<uint32_t>(dict->NumberOfElements());
      if (nof_elements != 0) nof_elements--;
      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 1290 1291
  // TODO(arv): Verify OrderedHashTable too.
}

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 1309
void WeakCell::WeakCellVerify(Isolate* isolate) {
  CHECK(IsWeakCell());
1310

1311
  CHECK(target()->IsJSReceiver() || target()->IsUndefined(isolate));
1312 1313 1314 1315 1316 1317

  CHECK(prev()->IsWeakCell() || prev()->IsUndefined(isolate));
  if (prev()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(prev())->next(), *this);
  }

1318 1319 1320
  CHECK(next()->IsWeakCell() || next()->IsUndefined(isolate));
  if (next()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(next())->prev(), *this);
1321
  }
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335

  CHECK_IMPLIES(key()->IsUndefined(isolate),
                key_list_prev()->IsUndefined(isolate));
  CHECK_IMPLIES(key()->IsUndefined(isolate),
                key_list_next()->IsUndefined(isolate));

  CHECK(key_list_prev()->IsWeakCell() || key_list_prev()->IsUndefined(isolate));
  if (key_list_prev()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(key_list_prev())->key_list_next(), *this);
  }

  CHECK(key_list_next()->IsWeakCell() || key_list_next()->IsUndefined(isolate));
  if (key_list_next()->IsWeakCell()) {
    CHECK_EQ(WeakCell::cast(key_list_next())->key_list_prev(), *this);
1336 1337
  }

1338 1339
  CHECK(finalization_group()->IsUndefined(isolate) ||
        finalization_group()->IsJSFinalizationGroup());
1340 1341
}

1342 1343 1344 1345 1346 1347
void JSWeakRef::JSWeakRefVerify(Isolate* isolate) {
  CHECK(IsJSWeakRef());
  JSObjectVerify(isolate);
  CHECK(target()->IsUndefined(isolate) || target()->IsJSReceiver());
}

1348 1349
void JSFinalizationGroup::JSFinalizationGroupVerify(Isolate* isolate) {
  CHECK(IsJSFinalizationGroup());
1350 1351
  JSObjectVerify(isolate);
  VerifyHeapPointer(isolate, cleanup());
1352 1353 1354
  CHECK(active_cells()->IsUndefined(isolate) || active_cells()->IsWeakCell());
  if (active_cells()->IsWeakCell()) {
    CHECK(WeakCell::cast(active_cells())->prev()->IsUndefined(isolate));
1355
  }
1356 1357 1358
  CHECK(cleared_cells()->IsUndefined(isolate) || cleared_cells()->IsWeakCell());
  if (cleared_cells()->IsWeakCell()) {
    CHECK(WeakCell::cast(cleared_cells())->prev()->IsUndefined(isolate));
1359 1360 1361
  }
}

1362 1363 1364
void JSFinalizationGroupCleanupIterator::
    JSFinalizationGroupCleanupIteratorVerify(Isolate* isolate) {
  CHECK(IsJSFinalizationGroupCleanupIterator());
1365
  JSObjectVerify(isolate);
1366
  VerifyHeapPointer(isolate, finalization_group());
1367 1368
}

1369
void FinalizationGroupCleanupJobTask::FinalizationGroupCleanupJobTaskVerify(
1370
    Isolate* isolate) {
1371 1372
  CHECK(IsFinalizationGroupCleanupJobTask());
  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 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397

  CHECK_GE(next_index()->Number(), 0);
  CHECK_LE(next_index()->Number(), kMaxSafeInteger);

  if (iterated_object()->IsJSTypedArray()) {
    // JSTypedArray::length is limited to Smi range.
    CHECK(next_index()->IsSmi());
    CHECK_LE(next_index()->Number(), Smi::kMaxValue);
  } else if (iterated_object()->IsJSArray()) {
    // JSArray::length is limited to Uint32 range.
    CHECK_LE(next_index()->Number(), kMaxUInt32);
  }
1398 1399
}

1400
void JSStringIterator::JSStringIteratorVerify(Isolate* isolate) {
1401
  CHECK(IsJSStringIterator());
1402
  JSObjectVerify(isolate);
1403
  CHECK(string()->IsString());
1404

1405 1406 1407
  CHECK_GE(index(), 0);
  CHECK_LE(index(), String::kMaxLength);
}
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 1431 1432
  CHECK(context()->IsContext());
}

1433
void CallbackTask::CallbackTaskVerify(Isolate* isolate) {
1434
  CHECK(IsCallbackTask());
1435
  MicrotaskVerify(isolate);
1436 1437
  VerifyHeapPointer(isolate, callback());
  VerifyHeapPointer(isolate, data());
1438 1439
}

1440
void PromiseReactionJobTask::PromiseReactionJobTaskVerify(Isolate* isolate) {
1441
  CHECK(IsPromiseReactionJobTask());
1442
  MicrotaskVerify(isolate);
1443 1444
  VerifyPointer(isolate, argument());
  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 1451
        promise_or_capability()->IsPromiseCapability() ||
        promise_or_capability()->IsUndefined(isolate));
1452 1453
}

1454 1455
void PromiseFulfillReactionJobTask::PromiseFulfillReactionJobTaskVerify(
    Isolate* isolate) {
1456
  CHECK(IsPromiseFulfillReactionJobTask());
1457
  PromiseReactionJobTaskVerify(isolate);
1458 1459
}

1460 1461
void PromiseRejectReactionJobTask::PromiseRejectReactionJobTaskVerify(
    Isolate* isolate) {
1462
  CHECK(IsPromiseRejectReactionJobTask());
1463
  PromiseReactionJobTaskVerify(isolate);
1464 1465
}

1466 1467
void PromiseResolveThenableJobTask::PromiseResolveThenableJobTaskVerify(
    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 1476
  CHECK(then()->IsCallable());
  CHECK(then()->IsJSReceiver());
1477
  VerifyHeapPointer(isolate, thenable());
1478 1479 1480
  CHECK(thenable()->IsJSReceiver());
}

1481
void PromiseCapability::PromiseCapabilityVerify(Isolate* isolate) {
1482
  CHECK(IsPromiseCapability());
1483

1484
  VerifyHeapPointer(isolate, promise());
1485
  CHECK(promise()->IsJSReceiver() || promise()->IsUndefined(isolate));
1486 1487
  VerifyPointer(isolate, resolve());
  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 1497
  CHECK(reject_handler()->IsUndefined(isolate) ||
        reject_handler()->IsCallable());
1498
  VerifyHeapPointer(isolate, fulfill_handler());
1499 1500
  CHECK(fulfill_handler()->IsUndefined(isolate) ||
        fulfill_handler()->IsCallable());
1501
  VerifyHeapPointer(isolate, promise_or_capability());
1502
  CHECK(promise_or_capability()->IsJSPromise() ||
1503 1504
        promise_or_capability()->IsPromiseCapability() ||
        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 1512 1513 1514
  VerifySmiField(kFlagsOffset);
  if (status() == Promise::kPending) {
    CHECK(reactions()->IsSmi() || reactions()->IsPromiseReaction());
  }
1515
}
1516

1517
template <typename Derived>
1518 1519
void SmallOrderedHashTable<Derived>::SmallOrderedHashTableVerify(
    Isolate* isolate) {
1520
  CHECK(IsSmallOrderedHashTable());
1521

1522 1523 1524 1525
  int capacity = Capacity();
  CHECK_GE(capacity, kMinCapacity);
  CHECK_LE(capacity, kMaxCapacity);

1526 1527 1528
  for (int entry = 0; entry < NumberOfBuckets(); entry++) {
    int bucket = GetFirstEntry(entry);
    if (bucket == kNotFound) continue;
1529 1530
    CHECK_GE(bucket, 0);
    CHECK_LE(bucket, capacity);
1531 1532 1533 1534 1535
  }

  for (int entry = 0; entry < NumberOfElements(); entry++) {
    int chain = GetNextEntry(entry);
    if (chain == kNotFound) continue;
1536 1537 1538
    CHECK_GE(chain, 0);
    CHECK_LE(chain, capacity);
  }
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 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
  for (int entry = NumberOfElements() + NumberOfDeletedElements();
       entry < Capacity(); entry++) {
    for (int offset = 0; offset < Derived::kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      CHECK(val->IsTheHole(isolate));
    }
  }
}
void SmallOrderedHashMap::SmallOrderedHashMapVerify(Isolate* isolate) {
  SmallOrderedHashTable<SmallOrderedHashMap>::SmallOrderedHashTableVerify(
      isolate);
1558 1559
  for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
       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 1568 1569 1570 1571 1572
void SmallOrderedHashSet::SmallOrderedHashSetVerify(Isolate* isolate) {
  SmallOrderedHashTable<SmallOrderedHashSet>::SmallOrderedHashTableVerify(
      isolate);
  for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
       entry++) {
    for (int offset = 0; offset < kEntrySize; offset++) {
1573
      Object val = GetDataEntry(entry, offset);
1574 1575
      CHECK(val->IsTheHole(isolate));
    }
1576 1577 1578
  }
}

1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591
void SmallOrderedNameDictionary::SmallOrderedNameDictionaryVerify(
    Isolate* isolate) {
  SmallOrderedHashTable<
      SmallOrderedNameDictionary>::SmallOrderedHashTableVerify(isolate);
  for (int entry = NumberOfElements(); entry < NumberOfDeletedElements();
       entry++) {
    for (int offset = 0; offset < kEntrySize; offset++) {
      Object val = GetDataEntry(entry, offset);
      CHECK(val->IsTheHole(isolate) ||
            (PropertyDetails::Empty().AsSmi() == Smi::cast(val)));
    }
  }
}
1592

1593 1594
void JSRegExp::JSRegExpVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
1595
  CHECK(data()->IsUndefined(isolate) || data()->IsFixedArray());
1596 1597
  switch (TypeTag()) {
    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(
jgruber's avatar
jgruber committed
1610 1611
          (one_byte_data->IsSmi() &&
           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() &&
jgruber's avatar
jgruber committed
1615
             Smi::ToInt(uc16_data) == JSRegExp::kUninitializedValue) ||
1616
            (is_native ? uc16_data->IsCode() : uc16_data->IsByteArray()));
1617

1618 1619
      CHECK(arr->get(JSRegExp::kIrregexpCaptureCountIndex)->IsSmi());
      CHECK(arr->get(JSRegExp::kIrregexpMaxRegisterCountIndex)->IsSmi());
1620 1621 1622
      break;
    }
    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 1633 1634 1635 1636
  CHECK(iterating_string()->IsString());
  CHECK(iterating_regexp()->IsObject());
  VerifySmiField(kFlagsOffset);
}

1637
void JSProxy::JSProxyVerify(Isolate* isolate) {
1638
  CHECK(IsJSProxy());
1639
  CHECK(map()->GetConstructor()->IsJSFunction());
1640 1641
  VerifyPointer(isolate, target());
  VerifyPointer(isolate, handler());
1642 1643 1644 1645
  if (!IsRevoked()) {
    CHECK_EQ(target()->IsCallable(), map()->is_callable());
    CHECK_EQ(target()->IsConstructor(), map()->is_constructor());
  }
1646
  CHECK(map()->prototype()->IsNull(isolate));
1647 1648
  // There should be no properties on a Proxy.
  CHECK_EQ(0, map()->NumberOfOwnDescriptors());
1649 1650
}

1651
void JSArrayBuffer::JSArrayBufferVerify(Isolate* isolate) {
1652
  CHECK(IsJSArrayBuffer());
1653
  if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
1654 1655 1656 1657
    CHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
    CHECK_EQ(0,
             *reinterpret_cast<uint32_t*>(address() + kOptionalPaddingOffset));
  }
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 1668
  CHECK_LE(byte_length(), JSArrayBuffer::kMaxByteLength);
  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 1688 1689 1690 1691
  CHECK(IsAsyncGeneratorRequest());
  VerifySmiField(kResumeModeOffset);
  CHECK_GE(resume_mode(), JSGeneratorObject::kNext);
  CHECK_LE(resume_mode(), JSGeneratorObject::kThrow);
  CHECK(promise()->IsJSPromise());
1692 1693
  VerifyPointer(isolate, value());
  VerifyPointer(isolate, next());
1694
  next()->ObjectVerify(isolate);
1695 1696
}

1697
void BigInt::BigIntVerify(Isolate* isolate) {
1698 1699 1700 1701
  CHECK(IsBigInt());
  CHECK_GE(length(), 0);
  CHECK_IMPLIES(is_zero(), !sign());  // There is no -0n.
}
1702

1703
void JSModuleNamespace::JSModuleNamespaceVerify(Isolate* isolate) {
1704
  CHECK(IsJSModuleNamespace());
1705
  VerifyPointer(isolate, module());
1706 1707
}

1708
void ModuleInfoEntry::ModuleInfoEntryVerify(Isolate* isolate) {
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724
  CHECK(IsModuleInfoEntry());

  CHECK(export_name()->IsUndefined(isolate) || export_name()->IsString());
  CHECK(local_name()->IsUndefined(isolate) || local_name()->IsString());
  CHECK(import_name()->IsUndefined(isolate) || import_name()->IsString());

  VerifySmiField(kModuleRequestOffset);
  VerifySmiField(kCellIndexOffset);
  VerifySmiField(kBegPosOffset);
  VerifySmiField(kEndPosOffset);

  CHECK_IMPLIES(import_name()->IsString(), module_request() >= 0);
  CHECK_IMPLIES(export_name()->IsString() && import_name()->IsString(),
                local_name()->IsUndefined(isolate));
}

1725
void Module::ModuleVerify(Isolate* isolate) {
1726
  CHECK(IsModule());
1727

1728 1729 1730 1731 1732 1733 1734
  VerifyPointer(isolate, code());
  VerifyPointer(isolate, exports());
  VerifyPointer(isolate, module_namespace());
  VerifyPointer(isolate, requested_modules());
  VerifyPointer(isolate, script());
  VerifyPointer(isolate, import_meta());
  VerifyPointer(isolate, exception());
1735
  VerifySmiField(kHashOffset);
1736
  VerifySmiField(kStatusOffset);
1737

1738 1739
  CHECK((status() >= kEvaluating && code()->IsModuleInfo()) ||
        (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 1764
  if (prototype_users()->IsWeakArrayList()) {
    PrototypeUsers::Verify(WeakArrayList::cast(prototype_users()));
1765 1766 1767 1768 1769
  } else {
    CHECK(prototype_users()->IsSmi());
  }
}

1770
void PrototypeUsers::Verify(WeakArrayList array) {
1771 1772 1773 1774 1775 1776 1777 1778 1779 1780
  if (array->length() == 0) {
    // Allow empty & uninitialized lists.
    return;
  }
  // Verify empty slot chain.
  int empty_slot = Smi::ToInt(empty_slot_index(array));
  int empty_slots_count = 0;
  while (empty_slot != kNoEmptySlotsMarker) {
    CHECK_GT(empty_slot, 0);
    CHECK_LT(empty_slot, array->length());
1781
    empty_slot = array->Get(empty_slot).ToSmi().value();
1782 1783 1784 1785 1786 1787 1788
    ++empty_slots_count;
  }

  // Verify that all elements are either weak pointers or SMIs marking empty
  // slots.
  int weak_maps_count = 0;
  for (int i = kFirstIndex; i < array->length(); ++i) {
1789
    HeapObject heap_object;
1790
    MaybeObject object = array->Get(i);
1791 1792
    if ((object->GetHeapObjectIfWeak(&heap_object) && heap_object->IsMap()) ||
        object->IsCleared()) {
1793 1794 1795 1796 1797 1798 1799 1800 1801
      ++weak_maps_count;
    } else {
      CHECK(object->IsSmi());
    }
  }

  CHECK_EQ(weak_maps_count + empty_slots_count + 1, array->length());
}

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 1812
    VerifyObjectField(isolate, kValue1Offset);
    VerifyObjectField(isolate, kValue2Offset);
1813
  }
1814 1815
}

1816
void Tuple3::Tuple3Verify(Isolate* isolate) {
1817
  CHECK(IsTuple3());
1818 1819 1820
  VerifyObjectField(isolate, kValue1Offset);
  VerifyObjectField(isolate, kValue2Offset);
  VerifyObjectField(isolate, kValue3Offset);
1821 1822
}

1823 1824 1825 1826 1827 1828
void ClassPositions::ClassPositionsVerify(Isolate* isolate) {
  CHECK(IsClassPositions());
  VerifySmiField(kStartOffset);
  VerifySmiField(kEndOffset);
}

1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840
void ObjectBoilerplateDescription::ObjectBoilerplateDescriptionVerify(
    Isolate* isolate) {
  CHECK(IsObjectBoilerplateDescription());
  CHECK_GE(this->length(),
           ObjectBoilerplateDescription::kDescriptionStartIndex);
  this->FixedArrayVerify(isolate);
}

void ArrayBoilerplateDescription::ArrayBoilerplateDescriptionVerify(
    Isolate* isolate) {
  CHECK(IsArrayBoilerplateDescription());
  CHECK(constant_elements()->IsFixedArrayBase());
1841
  VerifyObjectField(isolate, kConstantElementsOffset);
1842 1843
}

1844 1845 1846 1847 1848 1849 1850 1851 1852
void AsmWasmData::AsmWasmDataVerify(Isolate* isolate) {
  CHECK(IsAsmWasmData());
  VerifyObjectField(isolate, kManagedNativeModuleOffset);
  VerifyObjectField(isolate, kExportWrappersOffset);
  VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
  CHECK(uses_bitset()->IsHeapNumber());
  VerifyObjectField(isolate, kUsesBitsetOffset);
}

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 1861 1862 1863
  VerifyObjectField(isolate, kInterpretedFunctionsOffset);
  VerifyObjectField(isolate, kLocalsNamesOffset);
  VerifyObjectField(isolate, kCWasmEntriesOffset);
  VerifyObjectField(isolate, kCWasmEntryMapOffset);
1864 1865
}

1866 1867 1868 1869 1870
void WasmExceptionTag::WasmExceptionTagVerify(Isolate* isolate) {
  CHECK(IsWasmExceptionTag());
  VerifySmiField(kIndexOffset);
}

1871 1872
void WasmInstanceObject::WasmInstanceObjectVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
1873 1874 1875 1876 1877
  CHECK(IsWasmInstanceObject());

  // Just generically check all tagged fields. Don't check the untagged fields,
  // as some of them might still contain the "undefined" value if the
  // WasmInstanceObject is not fully set up yet.
1878 1879
  for (int offset = kHeaderSize; offset < kEndOfTaggedFieldsOffset;
       offset += kTaggedSize) {
1880
    VerifyObjectField(isolate, offset);
1881 1882 1883
  }
}

1884 1885
void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
    Isolate* isolate) {
1886
  CHECK(IsWasmExportedFunctionData());
1887
  VerifyObjectField(isolate, kWrapperCodeOffset);
1888 1889
  CHECK(wrapper_code()->kind() == Code::JS_TO_WASM_FUNCTION ||
        wrapper_code()->kind() == Code::C_WASM_ENTRY);
1890
  VerifyObjectField(isolate, kInstanceOffset);
1891
  VerifySmiField(kJumpTableOffsetOffset);
1892 1893 1894
  VerifySmiField(kFunctionIndexOffset);
}

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 1902 1903
  VerifyObjectField(isolate, kScriptOffset);
  VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
  VerifyObjectField(isolate, kBreakPointInfosOffset);
1904 1905
}

1906
void DataHandler::DataHandlerVerify(Isolate* isolate) {
1907 1908 1909 1910
  CHECK(IsDataHandler());
  CHECK_IMPLIES(!smi_handler()->IsSmi(),
                smi_handler()->IsCode() && IsStoreHandler());
  CHECK(validity_cell()->IsSmi() || validity_cell()->IsCell());
1911 1912
  int data_count = data_field_count();
  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 1924
void LoadHandler::LoadHandlerVerify(Isolate* isolate) {
  DataHandler::DataHandlerVerify(isolate);
1925 1926 1927
  // TODO(ishell): check handler integrity
}

1928 1929
void StoreHandler::StoreHandlerVerify(Isolate* isolate) {
  DataHandler::DataHandlerVerify(isolate);
1930 1931 1932
  // TODO(ishell): check handler integrity
}

1933
void AccessorInfo::AccessorInfoVerify(Isolate* isolate) {
1934
  CHECK(IsAccessorInfo());
1935 1936
  VerifyPointer(isolate, name());
  VerifyPointer(isolate, expected_receiver_type());
1937 1938 1939
  VerifyForeignPointer(isolate, *this, getter());
  VerifyForeignPointer(isolate, *this, setter());
  VerifyForeignPointer(isolate, *this, js_getter());
1940
  VerifyPointer(isolate, data());
1941 1942
}

1943
void AccessorPair::AccessorPairVerify(Isolate* isolate) {
1944
  CHECK(IsAccessorPair());
1945 1946
  VerifyPointer(isolate, getter());
  VerifyPointer(isolate, setter());
1947 1948
}

1949
void AccessCheckInfo::AccessCheckInfoVerify(Isolate* isolate) {
1950
  CHECK(IsAccessCheckInfo());
1951 1952 1953 1954
  VerifyPointer(isolate, callback());
  VerifyPointer(isolate, named_interceptor());
  VerifyPointer(isolate, indexed_interceptor());
  VerifyPointer(isolate, data());
1955 1956
}

1957
void CallHandlerInfo::CallHandlerInfoVerify(Isolate* isolate) {
1958
  CHECK(IsCallHandlerInfo());
1959 1960 1961 1962 1963
  CHECK(map() == ReadOnlyRoots(isolate).side_effect_call_handler_info_map() ||
        map() ==
            ReadOnlyRoots(isolate).side_effect_free_call_handler_info_map() ||
        map() == ReadOnlyRoots(isolate)
                     .next_call_side_effect_free_call_handler_info_map());
1964 1965 1966
  VerifyPointer(isolate, callback());
  VerifyPointer(isolate, js_callback());
  VerifyPointer(isolate, data());
1967
}
1968

1969
void InterceptorInfo::InterceptorInfoVerify(Isolate* isolate) {
1970
  CHECK(IsInterceptorInfo());
1971 1972 1973 1974 1975
  VerifyForeignPointer(isolate, *this, getter());
  VerifyForeignPointer(isolate, *this, setter());
  VerifyForeignPointer(isolate, *this, query());
  VerifyForeignPointer(isolate, *this, deleter());
  VerifyForeignPointer(isolate, *this, enumerator());
1976
  VerifyPointer(isolate, data());
1977
  VerifySmiField(kFlagsOffset);
1978
}
1979

1980
void TemplateInfo::TemplateInfoVerify(Isolate* isolate) {
1981 1982 1983
  VerifyPointer(isolate, tag());
  VerifyPointer(isolate, property_list());
  VerifyPointer(isolate, property_accessors());
1984 1985
}

1986
void FunctionTemplateInfo::FunctionTemplateInfoVerify(Isolate* isolate) {
1987
  CHECK(IsFunctionTemplateInfo());
1988
  TemplateInfoVerify(isolate);
1989 1990
  VerifyPointer(isolate, serial_number());
  VerifyPointer(isolate, call_code());
1991 1992 1993 1994 1995 1996 1997 1998
  VerifyPointer(isolate, signature());
  VerifyPointer(isolate, cached_property_name());
  VerifyPointer(isolate, rare_data());
}

void FunctionTemplateRareData::FunctionTemplateRareDataVerify(
    Isolate* isolate) {
  CHECK(IsFunctionTemplateRareData());
1999 2000 2001 2002 2003 2004
  VerifyPointer(isolate, prototype_template());
  VerifyPointer(isolate, parent_template());
  VerifyPointer(isolate, named_property_handler());
  VerifyPointer(isolate, indexed_property_handler());
  VerifyPointer(isolate, instance_template());
  VerifyPointer(isolate, access_check_info());
2005 2006
}

2007
void ObjectTemplateInfo::ObjectTemplateInfoVerify(Isolate* isolate) {
2008
  CHECK(IsObjectTemplateInfo());
2009
  TemplateInfoVerify(isolate);
2010 2011
  VerifyPointer(isolate, constructor());
  VerifyPointer(isolate, data());
2012 2013
}

2014
void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
2015 2016 2017
  CHECK(IsAllocationSite());
}

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 2027 2028
  VerifyPointer(isolate, source());
  VerifyPointer(isolate, name());
  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 2033
    CHECK(maybe_object->IsWeak() || maybe_object->IsCleared() ||
          (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 2041
  if (FLAG_enable_slow_asserts) {
    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 2048
        CHECK(e->IsCleared() || (e->GetHeapObjectIfStrong(&heap_object) &&
                                 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 2059
  VerifyPointer(isolate, original_bytecode_array());
  VerifyPointer(isolate, break_points());
2060 2061
}

2062 2063 2064 2065 2066 2067 2068 2069
void StackTraceFrame::StackTraceFrameVerify(Isolate* isolate) {
  CHECK(IsStackTraceFrame());
  VerifySmiField(kFrameIndexOffset);
  VerifySmiField(kIdOffset);
  VerifyPointer(isolate, frame_array());
  VerifyPointer(isolate, frame_info());
}

2070
void StackFrameInfo::StackFrameInfoVerify(Isolate* isolate) {
2071
  CHECK(IsStackFrameInfo());
2072 2073 2074
  VerifyPointer(isolate, script_name());
  VerifyPointer(isolate, script_name_or_source_url());
  VerifyPointer(isolate, function_name());
2075
}
2076

2077 2078
void PreparseData::PreparseDataVerify(Isolate* isolate) {
  CHECK(IsPreparseData());
2079 2080
  CHECK_LE(0, data_length());
  CHECK_LE(0, children_length());
2081

2082 2083 2084
  for (int i = 0; i < children_length(); ++i) {
    Object child = get_child_raw(i);
    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 2097 2098
void UncompiledDataWithoutPreparseData::UncompiledDataWithoutPreparseDataVerify(
    Isolate* isolate) {
  CHECK(IsUncompiledDataWithoutPreparseData());
2099
  VerifyPointer(isolate, inferred_name());
2100 2101
}

2102
void InterpreterData::InterpreterDataVerify(Isolate* isolate) {
2103 2104 2105 2106 2107
  CHECK(IsInterpreterData());
  CHECK(bytecode_array()->IsBytecodeArray());
  CHECK(interpreter_trampoline()->IsCode());
}

2108
#ifdef V8_INTL_SUPPORT
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121
void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kTypeOffset);
  VerifyObjectField(isolate, kBreakIteratorOffset);
  VerifyObjectField(isolate, kUnicodeStringOffset);
  VerifyObjectField(isolate, kBoundAdoptTextOffset);
  VerifyObjectField(isolate, kBoundFirstOffset);
  VerifyObjectField(isolate, kBoundNextOffset);
  VerifyObjectField(isolate, kBoundCurrentOffset);
  VerifyObjectField(isolate, kBoundBreakTypeOffset);
}

2122 2123 2124 2125
void JSCollator::JSCollatorVerify(Isolate* isolate) {
  CHECK(IsJSCollator());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kICUCollatorOffset);
2126
  VerifyObjectField(isolate, kBoundCompareOffset);
2127 2128
}

2129 2130
void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
2131
  VerifyObjectField(isolate, kICULocaleOffset);
2132 2133
  VerifyObjectField(isolate, kICUSimpleDateFormatOffset);
  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 2150 2151 2152
void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
  CHECK(IsJSNumberFormat());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
2153
  VerifyObjectField(isolate, kICUNumberFormatOffset);
2154 2155 2156 2157
  VerifyObjectField(isolate, kBoundFormatOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

2158 2159 2160 2161
void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
  CHECK(IsJSPluralRules());
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
2162
  VerifyObjectField(isolate, kFlagsOffset);
2163 2164 2165 2166
  VerifyObjectField(isolate, kICUPluralRulesOffset);
  VerifyObjectField(isolate, kICUDecimalFormatOffset);
}

2167
void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
2168
  JSObjectVerify(isolate);
2169
  VerifyObjectField(isolate, kLocaleOffset);
2170
  VerifyObjectField(isolate, kICUFormatterOffset);
2171
  VerifyObjectField(isolate, kFlagsOffset);
2172
}
2173

2174 2175 2176 2177 2178 2179 2180
void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kICUBreakIteratorOffset);
  VerifyObjectField(isolate, kUnicodeStringOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}

2181 2182 2183 2184 2185 2186
void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
  JSObjectVerify(isolate);
  VerifyObjectField(isolate, kLocaleOffset);
  VerifyObjectField(isolate, kICUBreakIteratorOffset);
  VerifyObjectField(isolate, kFlagsOffset);
}
2187 2188
#endif  // V8_INTL_SUPPORT

2189
#endif  // VERIFY_HEAP
2190

2191
#ifdef DEBUG
2192

2193 2194
void JSObject::IncrementSpillStatistics(Isolate* isolate,
                                        SpillInformation* info) {
2195 2196 2197 2198 2199
  info->number_of_objects_++;
  // Named properties
  if (HasFastProperties()) {
    info->number_of_objects_with_fast_properties_++;
    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 2204 2205
    info->number_of_slow_used_properties_ += dict->NumberOfElements();
    info->number_of_slow_unused_properties_ +=
        dict->Capacity() - dict->NumberOfElements();
2206
  } else {
2207
    NameDictionary dict = property_dictionary();
2208 2209 2210 2211 2212
    info->number_of_slow_used_properties_ += dict->NumberOfElements();
    info->number_of_slow_unused_properties_ +=
        dict->Capacity() - dict->NumberOfElements();
  }
  // Indexed properties
2213
  switch (GetElementsKind()) {
2214 2215 2216 2217 2218 2219
    case HOLEY_SMI_ELEMENTS:
    case PACKED_SMI_ELEMENTS:
    case HOLEY_DOUBLE_ELEMENTS:
    case PACKED_DOUBLE_ELEMENTS:
    case HOLEY_ELEMENTS:
    case PACKED_ELEMENTS:
2220
    case FAST_STRING_WRAPPER_ELEMENTS: {
2221 2222
      info->number_of_objects_with_fast_elements_++;
      int holes = 0;
2223
      FixedArray e = FixedArray::cast(elements());
2224 2225
      int len = e->length();
      for (int i = 0; i < len; i++) {
2226
        if (e->get(i)->IsTheHole(isolate)) holes++;
2227 2228 2229 2230
      }
      info->number_of_fast_used_elements_   += len - holes;
      info->number_of_fast_unused_elements_ += holes;
      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 2241 2242
        info->number_of_fast_used_elements_ += e->length();
        break;
      }
2243 2244
    case DICTIONARY_ELEMENTS:
    case SLOW_STRING_WRAPPER_ELEMENTS: {
2245
      NumberDictionary dict = element_dictionary();
2246 2247 2248 2249 2250
      info->number_of_slow_used_elements_ += dict->NumberOfElements();
      info->number_of_slow_unused_elements_ +=
          dict->Capacity() - dict->NumberOfElements();
      break;
    }
2251 2252
    case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
2253
    case NO_ELEMENTS:
2254
      break;
2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272
  }
}


void JSObject::SpillInformation::Clear() {
  number_of_objects_ = 0;
  number_of_objects_with_fast_properties_ = 0;
  number_of_objects_with_fast_elements_ = 0;
  number_of_fast_used_fields_ = 0;
  number_of_fast_unused_fields_ = 0;
  number_of_slow_used_properties_ = 0;
  number_of_slow_unused_properties_ = 0;
  number_of_fast_used_elements_ = 0;
  number_of_fast_unused_elements_ = 0;
  number_of_slow_used_elements_ = 0;
  number_of_slow_unused_elements_ = 0;
}

2273

2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295
void JSObject::SpillInformation::Print() {
  PrintF("\n  JSObject Spill Statistics (#%d):\n", number_of_objects_);

  PrintF("    - fast properties (#%d): %d (used) %d (unused)\n",
         number_of_objects_with_fast_properties_,
         number_of_fast_used_fields_, number_of_fast_unused_fields_);

  PrintF("    - slow properties (#%d): %d (used) %d (unused)\n",
         number_of_objects_ - number_of_objects_with_fast_properties_,
         number_of_slow_used_properties_, number_of_slow_unused_properties_);

  PrintF("    - fast elements (#%d): %d (used) %d (unused)\n",
         number_of_objects_with_fast_elements_,
         number_of_fast_used_elements_, number_of_fast_unused_elements_);

  PrintF("    - slow elements (#%d): %d (used) %d (unused)\n",
         number_of_objects_ - number_of_objects_with_fast_elements_,
         number_of_slow_used_elements_, number_of_slow_unused_elements_);

  PrintF("\n");
}

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 2305 2306
      return false;
    }
    current_key = key;
2307
    uint32_t hash = GetSortedKey(i)->Hash();
2308
    if (hash < current) {
2309
      Print();
2310 2311 2312 2313 2314 2315 2316
      return false;
    }
    current = hash;
  }
  return true;
}

2317
bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
2318
  DCHECK_EQ(valid_entries, -1);
2319
  Name prev_key;
2320
  PropertyKind prev_kind = kData;
2321 2322
  PropertyAttributes prev_attributes = NONE;
  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 2330
    if (!TransitionsAccessor::IsSpecialTransition(key->GetReadOnlyRoots(),
                                                  key)) {
2331
      Map target = GetTarget(i);
2332
      PropertyDetails details =
2333
          TransitionsAccessor::GetTargetDetails(key, target);
2334
      kind = details.kind();
2335 2336 2337
      attributes = details.attributes();
    } else {
      // Duplicate entries are not allowed for non-property transitions.
2338
      DCHECK_NE(prev_key, key);
2339
    }
2340

2341 2342
    int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
                          hash, kind, attributes);
2343
    if (cmp >= 0) {
2344
      Print();
2345 2346
      return false;
    }
2347 2348 2349
    prev_key = key;
    prev_hash = hash;
    prev_attributes = attributes;
2350
    prev_kind = kind;
2351 2352 2353 2354
  }
  return true;
}

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 2363 2364
  return !target->IsMap() || Map::cast(target)->GetBackPointer() == current_map;
}

2365 2366 2367
bool TransitionsAccessor::IsConsistentWithBackPointers() {
  int num_transitions = NumberOfTransitions();
  for (int i = 0; i < num_transitions; i++) {
2368
    Map target = GetTarget(i);
2369
    if (!CheckOneBackPointer(map_, target)) return false;
2370 2371 2372 2373
  }
  return true;
}

2374 2375
#endif  // DEBUG

2376 2377
}  // namespace internal
}  // namespace v8