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

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: temporarily reducing verification strength 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
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 {
Igor Sheludko 2016/07/08 08:38:22 Add a blank line after this line.
Camillo Bruni 2016/07/11 11:46:38 done
271 void VerifyFastProperties(JSReceiver* receiver) {
272 // TODO(cbruni): JSProxy support for slow properties
273 if (!receiver->IsJSObject()) return;
274 Isolate* isolate = receiver->GetIsolate();
275 Map* map = receiver->map();
276 JSObject* obj = JSObject::cast(receiver);
277 int actual_unused_property_fields = map->GetInObjectProperties() +
278 obj->properties()->length() -
279 map->NextFreePropertyIndex();
280 if (map->unused_property_fields() != actual_unused_property_fields) {
281 // This could actually happen in the middle of StoreTransitionStub
282 // when the new extended backing store is already set into the object and
283 // the allocation of the MutableHeapNumber triggers GC (in this case map
284 // is not updated yet).
285 CHECK_EQ(map->unused_property_fields(),
286 actual_unused_property_fields - JSObject::kFieldsAdded);
287 }
288 DescriptorArray* descriptors = map->instance_descriptors();
289 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
290 if (descriptors->GetDetails(i).type() != DATA) continue;
291 Representation r = descriptors->GetDetails(i).representation();
292 FieldIndex index = FieldIndex::ForDescriptor(map, i);
293 if (obj->IsUnboxedDoubleField(index)) {
294 DCHECK(r.IsDouble());
295 continue;
296 }
297 Object* value = obj->RawFastPropertyAt(index);
298 if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
299 if (value->IsUninitialized(isolate)) continue;
300 if (r.IsSmi()) DCHECK(value->IsSmi());
301 if (r.IsHeapObject()) DCHECK(value->IsHeapObject());
302 FieldType* field_type = descriptors->GetFieldType(i);
303 bool type_is_none = field_type->IsNone();
304 bool type_is_any = field_type->IsAny();
305 if (r.IsNone()) {
306 CHECK(type_is_none);
307 } else if (!type_is_any && !(type_is_none && r.IsHeapObject())) {
308 // If allocation folding is off then GC could happen during inner
309 // object literal creation and we will end up having and undefined
310 // value that does not match the field type.
311 CHECK(!field_type->NowStable() || field_type->NowContains(value) ||
312 (!FLAG_use_allocation_folding && value->IsUndefined(isolate)));
313 }
314 }
315 }
268 316
269 void JSObject::JSObjectVerify() { 317 void VerifySlowProperties(JSReceiver* obj) {
270 VerifyHeapPointer(properties()); 318 CHECK(obj->properties()->IsDictionary());
271 VerifyHeapPointer(elements()); 319 }
272 320
273 if (HasSloppyArgumentsElements()) { 321 void VerifyProperties(JSReceiver* obj) {
274 CHECK(this->elements()->IsFixedArray()); 322 obj->VerifyHeapPointer(obj->properties());
275 CHECK_GE(this->elements()->length(), 2); 323 if (obj->HasFastProperties()) {
324 VerifyFastProperties(obj);
325 } else {
Igor Sheludko 2016/07/08 08:38:22 Instead of VerifySlowProperties: } else if (obj->
Camillo Bruni 2016/07/11 11:46:39 Kept the separate method to do further checks but
326 VerifySlowProperties(obj);
276 } 327 }
328 }
277 329
278 if (HasFastProperties()) { 330 template <typename T>
279 int actual_unused_property_fields = map()->GetInObjectProperties() + 331 void VerifyDictionary(T* dict) {
280 properties()->length() - 332 CHECK(dict->IsFixedArray());
281 map()->NextFreePropertyIndex(); 333 CHECK(dict->IsDictionary());
282 if (map()->unused_property_fields() != actual_unused_property_fields) { 334 int capacity = dict->Capacity();
283 // This could actually happen in the middle of StoreTransitionStub 335 int nof = dict->NumberOfElements();
284 // when the new extended backing store is already set into the object and 336 int nod = dict->NumberOfDeletedElements();
285 // the allocation of the MutableHeapNumber triggers GC (in this case map 337 CHECK_LE(capacity, dict->length());
286 // is not updated yet). 338 CHECK_LE(nof, capacity);
287 CHECK_EQ(map()->unused_property_fields(), 339 CHECK_LE(0, nof + nod);
288 actual_unused_property_fields - JSObject::kFieldsAdded); 340 CHECK_LE(nof + nod, capacity);
341 }
342
343 void VerifyElements(JSObject* obj) {
344 obj->VerifyHeapPointer(obj->elements());
345 // If a GC was caused while constructing this object, the elements
346 // pointer may point to a one pointer filler map.
347 if (!obj->ElementsAreSafeToExamine()) return;
348 Map* map = obj->map();
349 Heap* heap = obj->GetHeap();
350 FixedArrayBase* elements = obj->elements();
351 CHECK_EQ((map->has_fast_smi_or_object_elements() ||
352 (elements == heap->empty_fixed_array()) ||
353 obj->HasFastStringWrapperElements()),
354 (elements->map() == heap->fixed_array_map() ||
355 elements->map() == heap->fixed_cow_array_map()));
356 CHECK(map->has_fast_object_elements() == obj->HasFastObjectElements());
Igor Sheludko 2016/07/08 08:38:22 CHECK_EQ?
Camillo Bruni 2016/07/11 11:46:39 copy pasta
357
358 // If a GC was caused while constructing this object, the elements
Igor Sheludko 2016/07/08 08:38:22 I think this comment belongs only to ElementAreSaf
Camillo Bruni 2016/07/11 11:46:39 right.
359 // pointer may point to a one pointer filler map.
360 ElementsKind kind = obj->GetElementsKind();
361 if (IsFastSmiOrObjectElementsKind(kind)) {
362 CHECK(elements->map() == heap->fixed_array_map() ||
363 elements->map() == heap->fixed_cow_array_map());
364 } else if (IsFastDoubleElementsKind(kind)) {
365 CHECK(elements->IsFixedDoubleArray() ||
366 elements == heap->empty_fixed_array());
367 } else if (kind == DICTIONARY_ELEMENTS) {
368 CHECK(elements->IsSeededNumberDictionary());
369 VerifyDictionary(SeededNumberDictionary::cast(elements));
Igor Sheludko 2016/07/08 08:38:22 I think this check also applies to SLOW_SLOPPY_ARG
Camillo Bruni 2016/07/11 11:46:39 eventually I will have to put a switch statement h
370 return;
371 } else {
372 CHECK(kind > DICTIONARY_ELEMENTS);
373 }
374 CHECK(!IsSloppyArgumentsElements(kind) ||
375 (elements->IsFixedArray() && elements->length() >= 2));
376
377 if (IsFastPackedElementsKind(kind)) {
378 uint32_t length = elements->length();
379 if (obj->IsJSArray()) {
380 Object* number = JSArray::cast(obj)->length();
381 if (number->IsSmi()) {
382 length = Min(length, static_cast<uint32_t>(Smi::cast(number)->value()));
383 }
289 } 384 }
290 DescriptorArray* descriptors = map()->instance_descriptors(); 385 if (kind == FAST_DOUBLE_ELEMENTS) {
291 Isolate* isolate = GetIsolate(); 386 for (uint32_t i = 0; i < length; i++) {
292 for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) { 387 CHECK(!FixedDoubleArray::cast(elements)->is_the_hole(i));
293 if (descriptors->GetDetails(i).type() == DATA) { 388 }
294 Representation r = descriptors->GetDetails(i).representation(); 389 } else {
295 FieldIndex index = FieldIndex::ForDescriptor(map(), i); 390 for (uint32_t i = 0; i < length; i++) {
296 if (IsUnboxedDoubleField(index)) { 391 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 } 392 }
318 } 393 }
319 } 394 }
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 } 395 }
332 396
397 } // namespace
398
399 void JSObject::JSObjectVerify() {
400 VerifyProperties(this);
401 VerifyElements(this);
402 }
333 403
334 void Map::MapVerify() { 404 void Map::MapVerify() {
335 Heap* heap = GetHeap(); 405 Heap* heap = GetHeap();
336 CHECK(!heap->InNewSpace(this)); 406 CHECK(!heap->InNewSpace(this));
337 CHECK(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE); 407 CHECK(FIRST_TYPE <= instance_type());
Igor Sheludko 2016/07/08 08:38:22 CHECK_LE?
Camillo Bruni 2016/07/11 11:46:39 done.
408 CHECK(instance_type() <= LAST_TYPE);
338 CHECK(instance_size() == kVariableSizeSentinel || 409 CHECK(instance_size() == kVariableSizeSentinel ||
339 (kPointerSize <= instance_size() && 410 (kPointerSize <= instance_size() &&
340 instance_size() < heap->Capacity())); 411 instance_size() < heap->Capacity()));
341 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) || 412 CHECK(GetBackPointer()->IsUndefined(heap->isolate()) ||
342 !Map::cast(GetBackPointer())->is_stable()); 413 !Map::cast(GetBackPointer())->is_stable());
343 VerifyHeapPointer(prototype()); 414 VerifyHeapPointer(prototype());
344 VerifyHeapPointer(instance_descriptors()); 415 VerifyHeapPointer(instance_descriptors());
345 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates()); 416 SLOW_DCHECK(instance_descriptors()->IsSortedNoDuplicates());
346 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this)); 417 SLOW_DCHECK(TransitionArray::IsSortedNoDuplicates(this));
347 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this)); 418 SLOW_DCHECK(TransitionArray::IsConsistentWithBackPointers(this));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 490
420 void JSGeneratorObject::JSGeneratorObjectVerify() { 491 void JSGeneratorObject::JSGeneratorObjectVerify() {
421 // In an expression like "new g()", there can be a point where a generator 492 // 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 493 // object is allocated but its fields are all undefined, as it hasn't yet been
423 // initialized by the generator. Hence these weak checks. 494 // initialized by the generator. Hence these weak checks.
424 VerifyObjectField(kFunctionOffset); 495 VerifyObjectField(kFunctionOffset);
425 VerifyObjectField(kContextOffset); 496 VerifyObjectField(kContextOffset);
426 VerifyObjectField(kReceiverOffset); 497 VerifyObjectField(kReceiverOffset);
427 VerifyObjectField(kOperandStackOffset); 498 VerifyObjectField(kOperandStackOffset);
428 VerifyObjectField(kContinuationOffset); 499 VerifyObjectField(kContinuationOffset);
500 JSObjectVerify();
501 }
502
503 void JSArgumentsObject::JSArgumentsObjectVerify() {
504 VerifyObjectField(kLengthOffset);
505 JSObjectVerify();
506 Isolate* isolate = GetIsolate();
507
508 // TODO(cbruni): replace with NULL check once all hydrogren stubs manage to
509 // set up the contexts properly
510 if (isolate->context()->IsSmi()) return;
511 if (isolate->bootstrapper()->IsActive()) return;
512 if (map() == *isolate->sloppy_arguments_map()) {
513 // TODO(cbruni): normal array-like size verification
514 } else if (map() == *isolate->fast_aliased_arguments_map()) {
515 CHECK(HasFastArgumentsElements());
516 CHECK(this->elements()->IsFixedArray());
517 CHECK_GE(this->elements()->length(), 2);
518 } else if (map() == *isolate->slow_aliased_arguments_map()) {
519 CHECK(HasSlowArgumentsElements());
520 CHECK(this->elements()->IsFixedArray());
521 CHECK_GE(this->elements()->length(), 2);
522 } else if (map() == *isolate->strict_arguments_map()) {
523 Object* length = *Object::GetProperty(handle(this, isolate),
Igor Sheludko 2016/07/08 08:38:22 This is scary. I guess heap verification should no
Camillo Bruni 2016/07/11 11:46:39 right, also I just noticed that this can be easily
524 isolate->factory()->length_string())
525 .ToHandleChecked();
526 CHECK_EQ(Smi::cast(length)->value(), elements()->length());
527 CHECK(HasFastElements());
528 } else {
529 PrintF(".");
Igor Sheludko 2016/07/08 08:38:22 Surprise! :)
Camillo Bruni 2016/07/11 11:46:39 ... as good as unreachable.
530 }
429 } 531 }
430 532
431 533
432 void JSValue::JSValueVerify() { 534 void JSValue::JSValueVerify() {
433 Object* v = value(); 535 Object* v = value();
434 if (v->IsHeapObject()) { 536 if (v->IsHeapObject()) {
435 VerifyHeapPointer(v); 537 VerifyHeapPointer(v);
436 } 538 }
539 JSObjectVerify();
437 } 540 }
438 541
439 542
440 void JSDate::JSDateVerify() { 543 void JSDate::JSDateVerify() {
Igor Sheludko 2016/07/08 08:38:22 JSDate and all other JSObject builtins should also
441 if (value()->IsHeapObject()) { 544 if (value()->IsHeapObject()) {
442 VerifyHeapPointer(value()); 545 VerifyHeapPointer(value());
443 } 546 }
444 Isolate* isolate = GetIsolate(); 547 Isolate* isolate = GetIsolate();
445 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() || 548 CHECK(value()->IsUndefined(isolate) || value()->IsSmi() ||
446 value()->IsHeapNumber()); 549 value()->IsHeapNumber());
447 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN()); 550 CHECK(year()->IsUndefined(isolate) || year()->IsSmi() || year()->IsNaN());
448 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN()); 551 CHECK(month()->IsUndefined(isolate) || month()->IsSmi() || month()->IsNaN());
449 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN()); 552 CHECK(day()->IsUndefined(isolate) || day()->IsSmi() || day()->IsNaN());
450 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() || 553 CHECK(weekday()->IsUndefined(isolate) || weekday()->IsSmi() ||
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 VerifyObjectField(kBoundTargetFunctionOffset); 641 VerifyObjectField(kBoundTargetFunctionOffset);
539 VerifyObjectField(kBoundArgumentsOffset); 642 VerifyObjectField(kBoundArgumentsOffset);
540 CHECK(bound_target_function()->IsCallable()); 643 CHECK(bound_target_function()->IsCallable());
541 CHECK(IsCallable()); 644 CHECK(IsCallable());
542 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor()); 645 CHECK_EQ(IsConstructor(), bound_target_function()->IsConstructor());
543 } 646 }
544 647
545 648
546 void JSFunction::JSFunctionVerify() { 649 void JSFunction::JSFunctionVerify() {
547 CHECK(IsJSFunction()); 650 CHECK(IsJSFunction());
651 JSObjectVerify();
548 VerifyObjectField(kPrototypeOrInitialMapOffset); 652 VerifyObjectField(kPrototypeOrInitialMapOffset);
549 VerifyObjectField(kNextFunctionLinkOffset); 653 VerifyObjectField(kNextFunctionLinkOffset);
550 CHECK(code()->IsCode()); 654 CHECK(code()->IsCode());
551 CHECK(next_function_link() == NULL || 655 CHECK(next_function_link() == NULL ||
552 next_function_link()->IsUndefined(GetIsolate()) || 656 next_function_link()->IsUndefined(GetIsolate()) ||
553 next_function_link()->IsJSFunction()); 657 next_function_link()->IsJSFunction());
554 CHECK(map()->is_callable()); 658 CHECK(map()->is_callable());
555 } 659 }
556 660
557 661
(...skipping 26 matching lines...) Expand all
584 } 688 }
585 689
586 690
587 void JSGlobalObject::JSGlobalObjectVerify() { 691 void JSGlobalObject::JSGlobalObjectVerify() {
588 CHECK(IsJSGlobalObject()); 692 CHECK(IsJSGlobalObject());
589 // Do not check the dummy global object for the builtins. 693 // Do not check the dummy global object for the builtins.
590 if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 && 694 if (GlobalDictionary::cast(properties())->NumberOfElements() == 0 &&
591 elements()->length() == 0) { 695 elements()->length() == 0) {
592 return; 696 return;
593 } 697 }
698 CHECK(!HasFastProperties());
594 JSObjectVerify(); 699 JSObjectVerify();
595 } 700 }
596 701
597 702
598 void Oddball::OddballVerify() { 703 void Oddball::OddballVerify() {
599 CHECK(IsOddball()); 704 CHECK(IsOddball());
600 Heap* heap = GetHeap(); 705 Heap* heap = GetHeap();
601 VerifyHeapPointer(to_string()); 706 VerifyHeapPointer(to_string());
602 Object* number = to_number(); 707 Object* number = to_number();
603 if (number->IsHeapObject()) { 708 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()) { 792 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
688 Object* obj = it.rinfo()->target_object(); 793 Object* obj = it.rinfo()->target_object();
689 if (IsWeakObject(obj)) { 794 if (IsWeakObject(obj)) {
690 if (obj->IsMap()) { 795 if (obj->IsMap()) {
691 Map* map = Map::cast(obj); 796 Map* map = Map::cast(obj);
692 CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup, 797 CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup,
693 cell)); 798 cell));
694 } else if (obj->IsJSObject()) { 799 } else if (obj->IsJSObject()) {
695 if (isolate->heap()->InNewSpace(obj)) { 800 if (isolate->heap()->InNewSpace(obj)) {
696 ArrayList* list = 801 ArrayList* list =
697 GetIsolate()->heap()->weak_new_space_object_to_code_list(); 802 isolate->heap()->weak_new_space_object_to_code_list();
698 bool found = false; 803 bool found = false;
699 for (int i = 0; i < list->Length(); i += 2) { 804 for (int i = 0; i < list->Length(); i += 2) {
700 WeakCell* obj_cell = WeakCell::cast(list->Get(i)); 805 WeakCell* obj_cell = WeakCell::cast(list->Get(i));
701 if (!obj_cell->cleared() && obj_cell->value() == obj && 806 if (!obj_cell->cleared() && obj_cell->value() == obj &&
702 WeakCell::cast(list->Get(i + 1)) == cell) { 807 WeakCell::cast(list->Get(i + 1)) == cell) {
703 found = true; 808 found = true;
704 break; 809 break;
705 } 810 }
706 } 811 }
707 CHECK(found); 812 CHECK(found);
708 } else { 813 } else {
709 Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate); 814 Handle<HeapObject> key_obj(HeapObject::cast(obj), isolate);
710 DependentCode* dep = 815 DependentCode* dep =
711 GetIsolate()->heap()->LookupWeakObjectToCodeDependency(key_obj); 816 isolate->heap()->LookupWeakObjectToCodeDependency(key_obj);
712 dep->Contains(DependentCode::kWeakCodeGroup, cell); 817 dep->Contains(DependentCode::kWeakCodeGroup, cell);
713 } 818 }
714 } 819 }
715 } 820 }
716 } 821 }
717 } 822 }
718 823
719 824
720 void JSArray::JSArrayVerify() { 825 void JSArray::JSArrayVerify() {
826 CHECK(IsJSArray());
721 JSObjectVerify(); 827 JSObjectVerify();
722 Isolate* isolate = GetIsolate(); 828 Isolate* isolate = GetIsolate();
723 CHECK(length()->IsNumber() || length()->IsUndefined(isolate)); 829 // Allow undefined for not fully initialized JSArrays
830 if (length()->IsUndefined(isolate)) {
831 CHECK_EQ(FixedArray::cast(elements()),
832 isolate->heap()->empty_fixed_array());
833 return;
834 }
835 CHECK(length()->IsNumber());
724 // If a GC was caused while constructing this array, the elements 836 // If a GC was caused while constructing this array, the elements
725 // pointer may point to a one pointer filler map. 837 // pointer may point to a one pointer filler map.
726 if (ElementsAreSafeToExamine()) { 838 if (ElementsAreSafeToExamine()) {
727 CHECK(elements()->IsUndefined(isolate) || elements()->IsFixedArray() || 839 CHECK(elements()->IsFixedArray() || elements()->IsFixedDoubleArray());
728 elements()->IsFixedDoubleArray());
729 } 840 }
730 } 841 }
731 842
732
733 void JSSet::JSSetVerify() { 843 void JSSet::JSSetVerify() {
734 CHECK(IsJSSet()); 844 CHECK(IsJSSet());
735 JSObjectVerify(); 845 JSObjectVerify();
736 VerifyHeapPointer(table()); 846 VerifyHeapPointer(table());
737 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate())); 847 CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(GetIsolate()));
738 // TODO(arv): Verify OrderedHashTable too. 848 // TODO(arv): Verify OrderedHashTable too.
739 } 849 }
740 850
741 851
742 void JSMap::JSMapVerify() { 852 void JSMap::JSMapVerify() {
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 if (isolate->bootstrapper()->IsActive()) return; 1399 if (isolate->bootstrapper()->IsActive()) return;
1290 1400
1291 static const int mask = RelocInfo::kCodeTargetMask; 1401 static const int mask = RelocInfo::kCodeTargetMask;
1292 RelocIterator old_it(old_code, mask); 1402 RelocIterator old_it(old_code, mask);
1293 RelocIterator new_it(new_code, mask); 1403 RelocIterator new_it(new_code, mask);
1294 Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck); 1404 Code* stack_check = isolate->builtins()->builtin(Builtins::kStackCheck);
1295 1405
1296 while (!old_it.done()) { 1406 while (!old_it.done()) {
1297 RelocInfo* rinfo = old_it.rinfo(); 1407 RelocInfo* rinfo = old_it.rinfo();
1298 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 1408 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1299 CHECK(!target->is_handler() && !target->is_inline_cache_stub()); 1409 CHECK(!target->is_handler());
1410 CHECK(!target->is_inline_cache_stub());
1300 if (target == stack_check) break; 1411 if (target == stack_check) break;
1301 old_it.next(); 1412 old_it.next();
1302 } 1413 }
1303 1414
1304 while (!new_it.done()) { 1415 while (!new_it.done()) {
1305 RelocInfo* rinfo = new_it.rinfo(); 1416 RelocInfo* rinfo = new_it.rinfo();
1306 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); 1417 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1307 CHECK(!target->is_handler() && !target->is_inline_cache_stub()); 1418 CHECK(!target->is_handler());
1419 CHECK(!target->is_inline_cache_stub());
1308 if (target == stack_check) break; 1420 if (target == stack_check) break;
1309 new_it.next(); 1421 new_it.next();
1310 } 1422 }
1311 1423
1312 // Either both are done because there is no stack check. 1424 // Either both are done because there is no stack check.
1313 // Or we are past the prologue for both. 1425 // Or we are past the prologue for both.
1314 CHECK_EQ(new_it.done(), old_it.done()); 1426 CHECK_EQ(new_it.done(), old_it.done());
1315 1427
1316 // After the prologue, each call in the old code has a corresponding call 1428 // After the prologue, each call in the old code has a corresponding call
1317 // in the new code. 1429 // in the new code.
(...skipping 15 matching lines...) Expand all
1333 1445
1334 // Both are done at the same time. 1446 // Both are done at the same time.
1335 CHECK_EQ(new_it.done(), old_it.done()); 1447 CHECK_EQ(new_it.done(), old_it.done());
1336 } 1448 }
1337 1449
1338 1450
1339 #endif // DEBUG 1451 #endif // DEBUG
1340 1452
1341 } // namespace internal 1453 } // namespace internal
1342 } // namespace v8 1454 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698