Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: src/objects-debug.cc

Issue 2126613002: making heap verification more aggressive (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: adding additional validation Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/disasm.h" 8 #include "src/disasm.h"
9 #include "src/disassembler.h" 9 #include "src/disassembler.h"
10 #include "src/field-type.h" 10 #include "src/field-type.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 #undef VERIFY_TYPED_ARRAY 93 #undef VERIFY_TYPED_ARRAY
94 94
95 case CODE_TYPE: 95 case CODE_TYPE:
96 Code::cast(this)->CodeVerify(); 96 Code::cast(this)->CodeVerify();
97 break; 97 break;
98 case ODDBALL_TYPE: 98 case ODDBALL_TYPE:
99 Oddball::cast(this)->OddballVerify(); 99 Oddball::cast(this)->OddballVerify();
100 break; 100 break;
101 case JS_OBJECT_TYPE: 101 case JS_OBJECT_TYPE:
102 case JS_ERROR_TYPE: 102 case JS_ERROR_TYPE:
103 case JS_ARGUMENTS_TYPE:
104 case JS_API_OBJECT_TYPE: 103 case JS_API_OBJECT_TYPE:
105 case JS_SPECIAL_API_OBJECT_TYPE: 104 case JS_SPECIAL_API_OBJECT_TYPE:
106 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 105 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
107 case JS_PROMISE_TYPE: 106 case JS_PROMISE_TYPE:
108 JSObject::cast(this)->JSObjectVerify(); 107 JSObject::cast(this)->JSObjectVerify();
109 break; 108 break;
109 case JS_ARGUMENTS_TYPE:
110 JSArgumentsObject::cast(this)->JSArgumentsObjectVerify();
111 break;
110 case JS_GENERATOR_OBJECT_TYPE: 112 case JS_GENERATOR_OBJECT_TYPE:
111 JSGeneratorObject::cast(this)->JSGeneratorObjectVerify(); 113 JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
112 break; 114 break;
113 case JS_VALUE_TYPE: 115 case JS_VALUE_TYPE:
114 JSValue::cast(this)->JSValueVerify(); 116 JSValue::cast(this)->JSValueVerify();
115 break; 117 break;
116 case JS_DATE_TYPE: 118 case JS_DATE_TYPE:
117 JSDate::cast(this)->JSDateVerify(); 119 JSDate::cast(this)->JSDateVerify();
118 break; 120 break;
119 case JS_BOUND_FUNCTION_TYPE: 121 case JS_BOUND_FUNCTION_TYPE:
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 241 }
240 242
241 243
242 void FreeSpace::FreeSpaceVerify() { 244 void FreeSpace::FreeSpaceVerify() {
243 CHECK(IsFreeSpace()); 245 CHECK(IsFreeSpace());
244 } 246 }
245 247
246 248
247 template <class Traits> 249 template <class Traits>
248 void FixedTypedArray<Traits>::FixedTypedArrayVerify() { 250 void FixedTypedArray<Traits>::FixedTypedArrayVerify() {
249 CHECK(IsHeapObject() && 251 CHECK(IsHeapObject());
250 HeapObject::cast(this)->map()->instance_type() == 252 CHECK(HeapObject::cast(this)->map()->instance_type() ==
251 Traits::kInstanceType); 253 Traits::kInstanceType);
252 if (base_pointer() == this) { 254 if (base_pointer() == this) {
253 CHECK(external_pointer() == 255 CHECK(external_pointer() ==
254 ExternalReference::fixed_typed_array_base_data_offset().address()); 256 ExternalReference::fixed_typed_array_base_data_offset().address());
255 } else { 257 } else {
256 CHECK(base_pointer() == nullptr); 258 CHECK(base_pointer() == nullptr);
257 } 259 }
258 } 260 }
259 261
260 262
261 bool JSObject::ElementsAreSafeToExamine() { 263 bool JSObject::ElementsAreSafeToExamine() {
262 // If a GC was caused while constructing this object, the elements 264 // If a GC was caused while constructing this object, the elements
263 // pointer may point to a one pointer filler map. 265 // pointer may point to a one pointer filler map.
264 return reinterpret_cast<Map*>(elements()) != 266 return reinterpret_cast<Map*>(elements()) !=
265 GetHeap()->one_pointer_filler_map(); 267 GetHeap()->one_pointer_filler_map();
266 } 268 }
267 269
270 namespace {
268 271
269 void JSObject::JSObjectVerify() { 272 void VerifyFastProperties(JSReceiver* receiver) {
270 VerifyHeapPointer(properties()); 273 // TODO(cbruni): JSProxy support for slow properties
271 VerifyHeapPointer(elements()); 274 if (!receiver->IsJSObject()) return;
275 Isolate* isolate = receiver->GetIsolate();
276 Map* map = receiver->map();
277 CHECK(!map->is_dictionary_map());
278 JSObject* obj = JSObject::cast(receiver);
279 int actual_unused_property_fields = map->GetInObjectProperties() +
280 obj->properties()->length() -
281 map->NextFreePropertyIndex();
282 if (map->unused_property_fields() != actual_unused_property_fields) {
283 // This could actually happen in the middle of StoreTransitionStub
284 // when the new extended backing store is already set into the object and
285 // the allocation of the MutableHeapNumber triggers GC (in this case map
286 // is not updated yet).
287 CHECK_EQ(map->unused_property_fields(),
288 actual_unused_property_fields - JSObject::kFieldsAdded);
289 }
290 DescriptorArray* descriptors = map->instance_descriptors();
291 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
292 if (descriptors->GetDetails(i).type() != DATA) continue;
293 Representation r = descriptors->GetDetails(i).representation();
294 FieldIndex index = FieldIndex::ForDescriptor(map, i);
295 if (obj->IsUnboxedDoubleField(index)) {
296 DCHECK(r.IsDouble());
297 continue;
298 }
299 Object* value = obj->RawFastPropertyAt(index);
300 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
301 if (value->IsUninitialized(isolate)) continue;
302 if (r.IsSmi()) DCHECK(value->IsSmi());
303 if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
304 FieldType* field_type = descriptors->GetFieldType(i);
305 bool type_is_none = field_type->IsNone();
306 bool type_is_any = field_type->IsAny();
307 if (r.IsNone()) {
308 CHECK(type_is_none);
309 } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
310 // If allocation folding is off then GC could happen during inner
311 // object literal creation and we will end up having and undefined
312 // value that does not match the field type.
313 CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
314 (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
315 }
316 }
317 }
272 318
273 if (HasSloppyArgumentsElements()) { 319 template <typename T>
274 CHECK(this->elements()->IsFixedArray()); 320 void VerifyDictionary(T* dict) {
275 CHECK_GE(this->elements()->length(), 2); 321 CHECK(dict->IsFixedArray());
322 CHECK(dict->IsDictionary());
323 int capacity = dict->Capacity();
324 int nof = dict->NumberOfElements();
325 int nod = dict->NumberOfDeletedElements();
326 CHECK_LE(capacity, dict->length());
327 CHECK_LE(nof, capacity);
328 CHECK_LE(0, nof + nod);
329 CHECK_LE(nof + nod, capacity);
330 }
331
332 void VerifySlowProperties(JSReceiver* obj) {
333 Map* map = obj->map();
334 CHECK(map->is_dictionary_map());
335 CHECK_EQ(0, map->NumberOfOwnDescriptors());
336 CHECK_EQ(0, map->unused_property_fields());
337 CHECK_EQ(kInvalidEnumCacheSentinel, map->EnumLength());
338 CHECK(obj->properties()->IsDictionary());
339 // Kept in-object properties for sow-mode object need to be zapped:
340 int nof_in_object_properties = map->GetInObjectProperties();
341 if (nof_in_object_properties > 0) {
342 JSObject* js_object = JSObject::cast(obj);
343 Smi* zap_value = Smi::FromInt(0);
344 for (int i = 0; i < nof_in_object_properties; i++) {
345 FieldIndex index = FieldIndex::ForLoadByFieldIndex(map, i);
346 Object* field = js_object->RawFastPropertyAt(index);
347 CHECK_EQ(field, zap_value);
348 }
276 } 349 }
350 if (obj->IsJSGlobalObject()) {
351 VerifyDictionary(JSObject::cast(obj)->global_dictionary());
352 } else {
353 VerifyDictionary(obj->property_dictionary());
354 }
355 }
277 356
278 if (HasFastProperties()) { 357 void VerifyProperties(JSReceiver* obj) {
279 int actual_unused_property_fields = map()->GetInObjectProperties() + 358 obj->VerifyHeapPointer(obj->properties());
280 properties()->length() - 359 if (obj->HasFastProperties()) {
281 map()->NextFreePropertyIndex(); 360 VerifyFastProperties(obj);
282 if (map()->unused_property_fields() != actual_unused_property_fields) { 361 } else {
283 // This could actually happen in the middle of StoreTransitionStub 362 VerifySlowProperties(obj);
284 // when the new extended backing store is already set into the object and 363 }
285 // the allocation of the MutableHeapNumber triggers GC (in this case map 364 }
286 // is not updated yet). 365
287 CHECK_EQ(map()->unused_property_fields(), 366 void VerifyElements(JSObject* obj) {
288 actual_unused_property_fields - JSObject::kFieldsAdded); 367 obj->VerifyHeapPointer(obj->elements());
368 // If a GC was caused while constructing this object, the elements
369 // pointer may point to a one pointer filler map.
370 if (!obj->ElementsAreSafeToExamine()) return;
371 Map* map = obj->map();
372 Heap* heap = obj->GetHeap();
373 FixedArrayBase* elements = obj->elements();
374 CHECK_EQ((map->has_fast_smi_or_object_elements() ||
375 (elements == heap->empty_fixed_array()) ||
376 obj->HasFastStringWrapperElements()),
377 (elements->map() == heap->fixed_array_map() ||
378 elements->map() == heap->fixed_cow_array_map()));
379 CHECK_EQ(map->has_fast_object_elements(), obj->HasFastObjectElements());
380
381 ElementsKind kind = obj->GetElementsKind();
382 if (IsFastSmiOrObjectElementsKind(kind)) {
383 CHECK(elements->map() == heap->fixed_array_map() ||
384 elements->map() == heap->fixed_cow_array_map());
385 } else if (IsFastDoubleElementsKind(kind)) {
386 CHECK(elements->IsFixedDoubleArray() ||
387 elements == heap->empty_fixed_array());
388 } else if (kind == DICTIONARY_ELEMENTS) {
389 CHECK(elements->IsSeededNumberDictionary());
390 VerifyDictionary(SeededNumberDictionary::cast(elements));
391 return;
392 } else {
393 CHECK(kind > DICTIONARY_ELEMENTS);
394 }
395 CHECK(!IsSloppyArgumentsElements(kind) ||
396 (elements->IsFixedArray() && elements->length() >= 2));
397
398 if (IsFastPackedElementsKind(kind)) {
399 uint32_t length = elements->length();
400 if (obj->IsJSArray()) {
401 Object* number = JSArray::cast(obj)->length();
402 if (number->IsSmi()) {
403 length = Min(length, static_cast<uint32_t>(Smi::cast(number)->value()));
404 }
289 } 405 }
290 DescriptorArray* descriptors = map()->instance_descriptors(); 406 if (kind == FAST_DOUBLE_ELEMENTS) {
291 Isolate* isolate = GetIsolate(); 407 for (uint32_t i = 0; i < length; i++) {
292 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) { 408 CHECK(!FixedDoubleArray::cast(elements)->is_the_hole(i));
293 if (descriptors->GetDetails(i).type() == DATA) { 409 }
294 Representation r = descriptors->GetDetails(i).representation(); 410 } else {
295 FieldIndex index = FieldIndex::ForDescriptor(map(), i); 411 for (uint32_t i = 0; i < length; i++) {
296 if (IsUnboxedDoubleField(index)) { 412 CHECK_NE(FixedArray::cast(elements)->get(i), heap->the_hole_value());
297 DCHECK(r.IsDouble());
298 continue;
299 }
300 Object* value = RawFastPropertyAt(index);
301 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
302 if (value->IsUninitialized(isolate)) continue;
303 if (r.IsSmi()) DCHECK(value->IsSmi());
304 if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
305 FieldType* field_type = descriptors->GetFieldType(i);
306 bool type_is_none = field_type->IsNone();
307 bool type_is_any = field_type->IsAny();
308 if (r.IsNone()) {
309 CHECK(type_is_none);
310 } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
311 // If allocation folding is off then GC could happen during inner
312 // object literal creation and we will end up having and undefined
313 // value that does not match the field type.
314 CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
315 (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
316 }
317 } 413 }
318 } 414 }
319 } 415 }
320
321 // If a GC was caused while constructing this object, the elements
322 // pointer may point to a one pointer filler map.
323 if (ElementsAreSafeToExamine()) {
324 CHECK_EQ((map()->has_fast_smi_or_object_elements() ||
325 (elements() == GetHeap()->empty_fixed_array()) ||
326 HasFastStringWrapperElements()),
327 (elements()->map() == GetHeap()->fixed_array_map() ||
328 elements()->map() == GetHeap()->fixed_cow_array_map()));
329 CHECK(map()->has_fast_object_elements() == HasFastObjectElements());
330 }
331 } 416 }
332 417
418 } // namespace
419
420 void JSObject::JSObjectVerify() {
421 VerifyProperties(this);
422 VerifyElements(this);
423 }
333 424
334 void Map::MapVerify() { 425 void Map::MapVerify() {
335 Heap* heap = GetHeap(); 426 Heap* heap = GetHeap();
336 CHECK(!heap->InNewSpace(this)); 427 CHECK(!heap->InNewSpace(this));
337 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); 428 CHECK_LE(FIRST_TYPE, instance_type());
429 CHECK_LE(instance_type(), LAST_TYPE);
338 CHECK(instance_size() == kVariableSizeSentinel || 430 CHECK(instance_size() == kVariableSizeSentinel ||
339 (kPointerSize <= instance_size() && 431 (kPointerSize <= instance_size() &&
340 instance_size() < heap->Capacity())); 432 instance_size() < heap->Capacity()));
341 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) || 433 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) ||
342 !Map::cast(GetBackPointer())->is_stable()); 434 !Map::cast(GetBackPointer())->is_stable());
343 VerifyHeapPointer(prototype()); 435 VerifyHeapPointer(prototype());
344 VerifyHeapPointer(instance_descriptors()); 436 VerifyHeapPointer(instance_descriptors());
345 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates()); 437 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
346 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this)); 438 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this));
347 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this)); 439 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this));
348 // TODO(ishell): turn it back to SLOW_DCHECK. 440 // TODO(ishell): turn it back to SLOW_DCHECK.
349 CHECK(!FLAG_unbox_double_fields || 441 CHECK(!FLAG_unbox_double_fields ||
350 layout_descriptor()->IsConsistentWithMap(this)); 442 layout_descriptor()->IsConsistentWithMap(this));
351 } 443 }
352 444
353 445
354 void Map::DictionaryMapVerify() { 446 void Map::DictionaryMapVerify() {
355 MapVerify(); 447 MapVerify();
356 CHECK(is_dictionary_map()); 448 CHECK(is_dictionary_map());
357 CHECK(instance_descriptors()->IsEmpty()); 449 CHECK(instance_descriptors()->IsEmpty());
358 CHECK_EQ(0, unused_property_fields()); 450 CHECK_EQ(0, unused_property_fields());
359 CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id()); 451 CHECK_EQ(Heap::GetStaticVisitorIdForMap(this), visitor_id());
452 CHECK_EQ(kInvalidEnumCacheSentinel, EnumLength());
360 } 453 }
361 454
362 455
363 void Map::VerifyOmittedMapChecks() { 456 void Map::VerifyOmittedMapChecks() {
364 if (!FLAG_omit_map_checks_for_leaf_maps) return; 457 if (!FLAG_omit_map_checks_for_leaf_maps) return;
365 if (!is_stable() || 458 if (!is_stable() ||
366 is_deprecated() || 459 is_deprecated() ||
367 is_dictionary_map()) { 460 is_dictionary_map()) {
368 CHECK(dependent_code()->IsEmpty(DependentCode::kPrototypeCheckGroup)); 461 CHECK(dependent_code()->IsEmpty(DependentCode::kPrototypeCheckGroup));
369 } 462 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 512
420 void JSGeneratorObject::JSGeneratorObjectVerify() { 513 void JSGeneratorObject::JSGeneratorObjectVerify() {
421 // In an expression like "new g()", there can be a point where a generator 514 // In an expression like "new g()", there can be a point where a generator
422 // object is allocated but its fields are all undefined, as it hasn't yet been 515 // object is allocated but its fields are all undefined, as it hasn't yet been
423 // initialized by the generator. Hence these weak checks. 516 // initialized by the generator. Hence these weak checks.
424 VerifyObjectField(kFunctionOffset); 517 VerifyObjectField(kFunctionOffset);
425 VerifyObjectField(kContextOffset); 518 VerifyObjectField(kContextOffset);
426 VerifyObjectField(kReceiverOffset); 519 VerifyObjectField(kReceiverOffset);
427 VerifyObjectField(kOperandStackOffset); 520 VerifyObjectField(kOperandStackOffset);
428 VerifyObjectField(kContinuationOffset); 521 VerifyObjectField(kContinuationOffset);
522 JSObjectVerify();
523 }
524
525 namespace {
526
527 void VerifyArgumentsParameterMap(FixedArray* elements) {
528 Isolate* isolate = elements->GetIsolate();
529 CHECK(elements->IsFixedArray());
530 CHECK_GE(elements->length(), 2);
531 HeapObject* context = HeapObject::cast(elements->get(0));
532 HeapObject* arguments = HeapObject::cast(elements->get(1));
533 // TODO(cbruni): fix arguments creation to be atomic.
534 CHECK_IMPLIES(context->IsUndefined(isolate), arguments->IsUndefined(isolate));
535 CHECK(context->IsUndefined(isolate) || context->IsContext());
536 CHECK(arguments->IsUndefined(isolate) || arguments->IsFixedArray());
537 }
538
539 } // namespace
540
541 void JSArgumentsObject::JSArgumentsObjectVerify() {
542 VerifyObjectField(kLengthOffset);
543 JSObjectVerify();
544 Isolate* isolate = GetIsolate();
545
546 if (isolate->bootstrapper()->IsActive()) return;
547 Context* context = isolate->context();
548 Object* constructor = map()->GetConstructor();
549 if (constructor->IsJSFunction()) {
550 context = JSFunction::cast(constructor)->context();
551 }
552 // TODO(cbruni): replace with NULL check once all hydrogren stubs manage to
553 // set up the contexts properly.
554 if (isolate->context()->IsSmi()) return;
555 Context* native_context = context->native_context();
556 if (map() == native_context->sloppy_arguments_map()) {
557 // Sloppy arguments without aliased arguments has a normal elements backing
558 // store which is already verified by JSObjectVerify() above.
559 } else if (map() == native_context->fast_aliased_arguments_map()) {
560 CHECK(HasFastArgumentsElements());
561 FixedArray* elements = FixedArray::cast(this->elements());
562 VerifyArgumentsParameterMap(FixedArray::cast(elements));
563 CHECK_EQ(elements->map(), isolate->heap()->sloppy_arguments_elements_map());
564 } else if (map() == native_context->slow_aliased_arguments_map()) {
565 CHECK(HasSlowArgumentsElements());
566 FixedArray* elements = FixedArray::cast(this->elements());
567 VerifyArgumentsParameterMap(elements);
568 VerifyDictionary(SeededNumberDictionary::cast(elements->get(1)));
569 CHECK_EQ(elements->map(), isolate->heap()->sloppy_arguments_elements_map());
570 } else if (map() == native_context->strict_arguments_map()) {
571 CHECK(HasFastElements());
572 } else {
573 // TODO(cbruni): follow up on normalized argument maps.
574 }
429 } 575 }
430 576
431 577
432 void JSValue::JSValueVerify() { 578 void JSValue::JSValueVerify() {
433 Object* v = value(); 579 Object* v = value();
434 if (v->IsHeapObject()) { 580 if (v->IsHeapObject()) {
435 VerifyHeapPointer(v); 581 VerifyHeapPointer(v);
436 } 582 }
583 JSObjectVerify();
437 } 584 }
438 585
439 586
440 void JSDate::JSDateVerify() { 587 void JSDate::JSDateVerify() {
588 JSObjectVerify();
441 if (value()->IsHeapObject()) { 589 if (value()->IsHeapObject()) {
442 VerifyHeapPointer(value()); 590 VerifyHeapPointer(value());
443 } 591 }
444 Isolate* isolate = GetIsolate(); 592 Isolate* isolate = GetIsolate();
445 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() || 593 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
446 value()->IsHeapNumber()); 594 value()->IsHeapNumber());
447 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN()); 595 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
448 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN()); 596 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
449 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN()); 597 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
450 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() || 598 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
(...skipping 29 matching lines...) Expand all
480 CHECK(0 <= weekday && weekday <= 6); 628 CHECK(0 <= weekday && weekday <= 6);
481 } 629 }
482 if (cache_stamp()->IsSmi()) { 630 if (cache_stamp()->IsSmi()) {
483 CHECK(Smi::cast(cache_stamp())->value() <= 631 CHECK(Smi::cast(cache_stamp())->value() <=
484 Smi::cast(isolate->date_cache()->stamp())->value()); 632 Smi::cast(isolate->date_cache()->stamp())->value());
485 } 633 }
486 } 634 }
487 635
488 636
489 void JSMessageObject::JSMessageObjectVerify() { 637 void JSMessageObject::JSMessageObjectVerify() {
638 JSObjectVerify();
490 CHECK(IsJSMessageObject()); 639 CHECK(IsJSMessageObject());
491 VerifyObjectField(kStartPositionOffset); 640 VerifyObjectField(kStartPositionOffset);
492 VerifyObjectField(kEndPositionOffset); 641 VerifyObjectField(kEndPositionOffset);
493 VerifyObjectField(kArgumentsOffset); 642 VerifyObjectField(kArgumentsOffset);
494 VerifyObjectField(kScriptOffset); 643 VerifyObjectField(kScriptOffset);
495 VerifyObjectField(kStackFramesOffset); 644 VerifyObjectField(kStackFramesOffset);
496 } 645 }
497 646
498 647
499 void String::StringVerify() { 648 void String::StringVerify() {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 VerifyObjectField(kBoundTargetFunctionOffset); 687 VerifyObjectField(kBoundTargetFunctionOffset);
539 VerifyObjectField(kBoundArgumentsOffset); 688 VerifyObjectField(kBoundArgumentsOffset);
540 CHECK(bound_target_function()->IsCallable()); 689 CHECK(bound_target_function()->IsCallable());
541 CHECK(IsCallable()); 690 CHECK(IsCallable());
542 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor()); 691 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
543 } 692 }
544 693
545 694
546 void JSFunction::JSFunctionVerify() { 695 void JSFunction::JSFunctionVerify() {
547 CHECK(IsJSFunction()); 696 CHECK(IsJSFunction());
697 JSObjectVerify();
548 VerifyObjectField(kPrototypeOrInitialMapOffset); 698 VerifyObjectField(kPrototypeOrInitialMapOffset);
549 VerifyObjectField(kNextFunctionLinkOffset); 699 VerifyObjectField(kNextFunctionLinkOffset);
550 CHECK(code()->IsCode()); 700 CHECK(code()->IsCode());
551 CHECK(next_function_link() == NULL || 701 CHECK(next_function_link() == NULL ||
552 next_function_link()->IsUndefined(GetIsolate()) || 702 next_function_link()->IsUndefined(GetIsolate()) ||
553 next_function_link()->IsJSFunction()); 703 next_function_link()->IsJSFunction());
554 CHECK(map()->is_callable()); 704 CHECK(map()->is_callable());
555 } 705 }
556 706
557 707
(...skipping 26 matching lines...) Expand all
584 } 734 }
585 735
586 736
587 void JSGlobalObject::JSGlobalObjectVerify() { 737 void JSGlobalObject::JSGlobalObjectVerify() {
588 CHECK(IsJSGlobalObject()); 738 CHECK(IsJSGlobalObject());
589 // Do not check the dummy global object for the builtins. 739 // Do not check the dummy global object for the builtins.
590 if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 && 740 if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 &&
591 elements()->length() == 0) { 741 elements()->length() == 0) {
592 return; 742 return;
593 } 743 }
744 CHECK(!HasFastProperties());
594 JSObjectVerify(); 745 JSObjectVerify();
595 } 746 }
596 747
597 748
598 void Oddball::OddballVerify() { 749 void Oddball::OddballVerify() {
599 CHECK(IsOddball()); 750 CHECK(IsOddball());
600 Heap* heap = GetHeap(); 751 Heap* heap = GetHeap();
601 VerifyHeapPointer(to_string()); 752 VerifyHeapPointer(to_string());
602 Object* number = to_number(); 753 Object* number = to_number();
603 if (number->IsHeapObject()) { 754 if (number->IsHeapObject()) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { 838 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
688 Object* obj = it.rinfo()->target_object(); 839 Object* obj = it.rinfo()->target_object();
689 if (IsWeakObject(obj)) { 840 if (IsWeakObject(obj)) {
690 if (obj->IsMap()) { 841 if (obj->IsMap()) {
691 Map* map = Map::cast(obj); 842 Map* map = Map::cast(obj);
692 CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup, 843 CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup,
693 cell)); 844 cell));
694 } else if (obj->IsJSObject()) { 845 } else if (obj->IsJSObject()) {
695 if (isolate->heap()->InNewSpace(obj)) { 846 if (isolate->heap()->InNewSpace(obj)) {
696 ArrayList* list = 847 ArrayList* list =
697 GetIsolate()->heap()->weak_new_space_object_to_code_list(); 848 isolate->heap()->weak_new_space_object_to_code_list();
698 bool found = false; 849 bool found = false;
699 for (int i = 0; i < list->Length(); i += 2) { 850 for (int i = 0; i < list->Length(); i += 2) {
700 WeakCell* obj_cell = WeakCell::cast(list->Get(i)); 851 WeakCell* obj_cell = WeakCell::cast(list->Get(i));
701 if (!obj_cell->cleared() && obj_cell->value() == obj && 852 if (!obj_cell->cleared() && obj_cell->value() == obj &&
702 WeakCell::cast(list->Get(i + 1)) == cell) { 853 WeakCell::cast(list->Get(i + 1)) == cell) {
703 found = true; 854 found = true;
704 break; 855 break;
705 } 856 }
706 } 857 }
707 CHECK(found); 858 CHECK(found);
708 } else { 859 } else {
709 Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate); 860 Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate);
710 DependentCode* dep = 861 DependentCode* dep =
711 GetIsolate()->heap()->LookupWeakObjectToCodeDependency(key_obj); 862 isolate->heap()->LookupWeakObjectToCodeDependency(key_obj);
712 dep->Contains(DependentCode::kWeakCodeGroup, cell); 863 dep->Contains(DependentCode::kWeakCodeGroup, cell);
713 } 864 }
714 } 865 }
715 } 866 }
716 } 867 }
717 } 868 }
718 869
719 870
720 void JSArray::JSArrayVerify() { 871 void JSArray::JSArrayVerify() {
872 CHECK(IsJSArray());
721 JSObjectVerify(); 873 JSObjectVerify();
722 Isolate* isolate = GetIsolate(); 874 Isolate* isolate = GetIsolate();
723 CHECK(length()->IsNumber() || length()->IsUndefined(isolate)); 875 // Allow undefined for not fully initialized JSArrays
876 if (length()->IsUndefined(isolate)) {
877 CHECK_EQ(FixedArray::cast(elements()),
878 isolate->heap()->empty_fixed_array());
879 return;
880 }
881 CHECK(length()->IsNumber());
724 // If a GC was caused while constructing this array, the elements 882 // If a GC was caused while constructing this array, the elements
725 // pointer may point to a one pointer filler map. 883 // pointer may point to a one pointer filler map.
726 if (ElementsAreSafeToExamine()) { 884 if (ElementsAreSafeToExamine()) {
727 CHECK(elements()->IsUndefined(isolate) || elements()->IsFixedArray() || 885 CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
728 elements()->IsFixedDoubleArray());
729 } 886 }
730 } 887 }
731 888
732
733 void JSSet::JSSetVerify() { 889 void JSSet::JSSetVerify() {
734 CHECK(IsJSSet()); 890 CHECK(IsJSSet());
735 JSObjectVerify(); 891 JSObjectVerify();
736 VerifyHeapPointer(table()); 892 VerifyHeapPointer(table());
737 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate())); 893 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate()));
738 // TODO(arv): Verify OrderedHashTable too. 894 // TODO(arv): Verify OrderedHashTable too.
739 } 895 }
740 896
741 897
742 void JSMap::JSMapVerify() { 898 void JSMap::JSMapVerify() {
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 if (isolate->bootstrapper()->IsActive()) return; 1445 if (isolate->bootstrapper()->IsActive()) return;
1290 1446
1291 static const int mask = RelocInfo::kCodeTargetMask; 1447 static const int mask = RelocInfo::kCodeTargetMask;
1292 RelocIterator old_it(old_code, mask); 1448 RelocIterator old_it(old_code, mask);
1293 RelocIterator new_it(new_code, mask); 1449 RelocIterator new_it(new_code, mask);
1294 Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck); 1450 Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck);
1295 1451
1296 while (!old_it.done()) { 1452 while (!old_it.done()) {
1297 RelocInfo* rinfo = old_it.rinfo(); 1453 RelocInfo* rinfo = old_it.rinfo();
1298 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 1454 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1299 CHECK(!target->is_handler() && !target->is_inline_cache_stub()); 1455 CHECK(!target->is_handler());
1456 CHECK(!target->is_inline_cache_stub());
1300 if (target == stack_check) break; 1457 if (target == stack_check) break;
1301 old_it.next(); 1458 old_it.next();
1302 } 1459 }
1303 1460
1304 while (!new_it.done()) { 1461 while (!new_it.done()) {
1305 RelocInfo* rinfo = new_it.rinfo(); 1462 RelocInfo* rinfo = new_it.rinfo();
1306 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 1463 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1307 CHECK(!target->is_handler() && !target->is_inline_cache_stub()); 1464 CHECK(!target->is_handler());
1465 CHECK(!target->is_inline_cache_stub());
1308 if (target == stack_check) break; 1466 if (target == stack_check) break;
1309 new_it.next(); 1467 new_it.next();
1310 } 1468 }
1311 1469
1312 // Either both are done because there is no stack check. 1470 // Either both are done because there is no stack check.
1313 // Or we are past the prologue for both. 1471 // Or we are past the prologue for both.
1314 CHECK_EQ(new_it.done(), old_it.done()); 1472 CHECK_EQ(new_it.done(), old_it.done());
1315 1473
1316 // After the prologue, each call in the old code has a corresponding call 1474 // After the prologue, each call in the old code has a corresponding call
1317 // in the new code. 1475 // in the new code.
(...skipping 15 matching lines...) Expand all
1333 1491
1334 // Both are done at the same time. 1492 // Both are done at the same time.
1335 CHECK_EQ(new_it.done(), old_it.done()); 1493 CHECK_EQ(new_it.done(), old_it.done());
1336 } 1494 }
1337 1495
1338 1496
1339 #endif // DEBUG 1497 #endif // DEBUG
1340 1498
1341 } // namespace internal 1499 } // namespace internal
1342 } // namespace v8 1500 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698