| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1879 } | 1879 } |
| 1880 | 1880 |
| 1881 | 1881 |
| 1882 bool DescriptorArray::IsEmpty() { | 1882 bool DescriptorArray::IsEmpty() { |
| 1883 ASSERT(length() >= kFirstIndex || | 1883 ASSERT(length() >= kFirstIndex || |
| 1884 this == HEAP->empty_descriptor_array()); | 1884 this == HEAP->empty_descriptor_array()); |
| 1885 return length() < kFirstIndex; | 1885 return length() < kFirstIndex; |
| 1886 } | 1886 } |
| 1887 | 1887 |
| 1888 | 1888 |
| 1889 bool DescriptorArray::MayContainTransitions() { | |
| 1890 return !IsEmpty(); | |
| 1891 } | |
| 1892 | |
| 1893 | |
| 1894 bool DescriptorArray::HasTransitionArray() { | |
| 1895 return MayContainTransitions() && !get(kTransitionsIndex)->IsSmi(); | |
| 1896 } | |
| 1897 | |
| 1898 | |
| 1899 Object* DescriptorArray::back_pointer_storage() { | |
| 1900 return READ_FIELD(this, kBackPointerStorageOffset); | |
| 1901 } | |
| 1902 | |
| 1903 | |
| 1904 void DescriptorArray::set_back_pointer_storage(Object* value, | |
| 1905 WriteBarrierMode mode) { | |
| 1906 ASSERT(length() > kBackPointerStorageIndex); | |
| 1907 Heap* heap = GetHeap(); | |
| 1908 WRITE_FIELD(this, kBackPointerStorageOffset, value); | |
| 1909 CONDITIONAL_WRITE_BARRIER(heap, this, kBackPointerStorageOffset, value, mode); | |
| 1910 } | |
| 1911 | |
| 1912 | |
| 1913 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array, | 1889 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array, |
| 1914 int first, | 1890 int first, |
| 1915 int second) { | 1891 int second) { |
| 1916 Object* tmp = array->get(first); | 1892 Object* tmp = array->get(first); |
| 1917 NoIncrementalWriteBarrierSet(array, first, array->get(second)); | 1893 NoIncrementalWriteBarrierSet(array, first, array->get(second)); |
| 1918 NoIncrementalWriteBarrierSet(array, second, tmp); | 1894 NoIncrementalWriteBarrierSet(array, second, tmp); |
| 1919 } | 1895 } |
| 1920 | 1896 |
| 1921 | 1897 |
| 1922 // Perform a binary search in a fixed array. Low and high are entry indices. If | 1898 // Perform a binary search in a fixed array. Low and high are entry indices. If |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1992 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); | 1968 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); |
| 1993 int number = cache->Lookup(this, name); | 1969 int number = cache->Lookup(this, name); |
| 1994 if (number == DescriptorLookupCache::kAbsent) { | 1970 if (number == DescriptorLookupCache::kAbsent) { |
| 1995 number = internal::Search(this, name); | 1971 number = internal::Search(this, name); |
| 1996 cache->Update(this, name, number); | 1972 cache->Update(this, name, number); |
| 1997 } | 1973 } |
| 1998 return number; | 1974 return number; |
| 1999 } | 1975 } |
| 2000 | 1976 |
| 2001 | 1977 |
| 2002 TransitionArray* DescriptorArray::transitions() { | |
| 2003 ASSERT(MayContainTransitions()); | |
| 2004 Object* array = get(kTransitionsIndex); | |
| 2005 return TransitionArray::cast(array); | |
| 2006 } | |
| 2007 | |
| 2008 | |
| 2009 void DescriptorArray::ClearTransitions() { | |
| 2010 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0)); | |
| 2011 } | |
| 2012 | |
| 2013 | |
| 2014 void DescriptorArray::set_transitions(TransitionArray* transitions_array, | |
| 2015 WriteBarrierMode mode) { | |
| 2016 Heap* heap = GetHeap(); | |
| 2017 WRITE_FIELD(this, kTransitionsOffset, transitions_array); | |
| 2018 CONDITIONAL_WRITE_BARRIER( | |
| 2019 heap, this, kTransitionsOffset, transitions_array, mode); | |
| 2020 } | |
| 2021 | |
| 2022 | |
| 2023 Object** DescriptorArray::GetKeySlot(int descriptor_number) { | 1978 Object** DescriptorArray::GetKeySlot(int descriptor_number) { |
| 2024 ASSERT(descriptor_number < number_of_descriptors()); | 1979 ASSERT(descriptor_number < number_of_descriptors()); |
| 2025 return HeapObject::RawField( | 1980 return HeapObject::RawField( |
| 2026 reinterpret_cast<HeapObject*>(this), | 1981 reinterpret_cast<HeapObject*>(this), |
| 2027 OffsetOfElementAt(ToKeyIndex(descriptor_number))); | 1982 OffsetOfElementAt(ToKeyIndex(descriptor_number))); |
| 2028 } | 1983 } |
| 2029 | 1984 |
| 2030 | 1985 |
| 2031 String* DescriptorArray::GetKey(int descriptor_number) { | 1986 String* DescriptorArray::GetKey(int descriptor_number) { |
| 2032 ASSERT(descriptor_number < number_of_descriptors()); | 1987 ASSERT(descriptor_number < number_of_descriptors()); |
| (...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3451 | 3406 |
| 3452 | 3407 |
| 3453 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3408 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
| 3454 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3409 ASSERT(value->IsNull() || value->IsJSReceiver()); |
| 3455 WRITE_FIELD(this, kPrototypeOffset, value); | 3410 WRITE_FIELD(this, kPrototypeOffset, value); |
| 3456 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); | 3411 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
| 3457 } | 3412 } |
| 3458 | 3413 |
| 3459 | 3414 |
| 3460 DescriptorArray* Map::instance_descriptors() { | 3415 DescriptorArray* Map::instance_descriptors() { |
| 3461 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | 3416 if (!HasTransitionArray()) return GetHeap()->empty_descriptor_array(); |
| 3462 if (!object->IsDescriptorArray()) { | 3417 return transitions()->descriptors(); |
| 3463 ASSERT(object->IsMap() || object->IsUndefined()); | |
| 3464 return GetHeap()->empty_descriptor_array(); | |
| 3465 } else { | |
| 3466 return DescriptorArray::cast(object); | |
| 3467 } | |
| 3468 } | 3418 } |
| 3469 | 3419 |
| 3470 | 3420 |
| 3471 void Map::set_instance_descriptors(DescriptorArray* value, | 3421 // If the descriptor is using the empty transition array, install a new empty |
| 3472 WriteBarrierMode mode) { | 3422 // transition array that will have place for an element transition. |
| 3473 Heap* heap = GetHeap(); | 3423 static MaybeObject* EnsureHasTransitionArray(Map* map) { |
| 3424 if (map->HasTransitionArray()) return map; |
| 3474 | 3425 |
| 3475 if (value == heap->empty_descriptor_array()) { | 3426 TransitionArray* transitions; |
| 3476 ClearDescriptorArray(heap, mode); | 3427 MaybeObject* maybe_transitions = TransitionArray::Allocate(0); |
| 3477 return; | 3428 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| 3478 } | 3429 map->set_transitions(transitions); |
| 3479 | 3430 return transitions; |
| 3480 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | |
| 3481 | |
| 3482 if (object->IsDescriptorArray()) { | |
| 3483 value->set_back_pointer_storage( | |
| 3484 DescriptorArray::cast(object)->back_pointer_storage()); | |
| 3485 } else { | |
| 3486 ASSERT(object->IsMap() || object->IsUndefined()); | |
| 3487 value->set_back_pointer_storage(object); | |
| 3488 } | |
| 3489 | |
| 3490 ASSERT(!is_shared()); | |
| 3491 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value); | |
| 3492 CONDITIONAL_WRITE_BARRIER( | |
| 3493 heap, this, kInstanceDescriptorsOrBackPointerOffset, value, mode); | |
| 3494 } | 3431 } |
| 3495 | 3432 |
| 3496 | 3433 |
| 3497 void Map::InitializeDescriptors(DescriptorArray* descriptors) { | 3434 MaybeObject* Map::SetDescriptors(DescriptorArray* value, |
| 3435 WriteBarrierMode mode) { |
| 3436 ASSERT(!is_shared()); |
| 3437 MaybeObject* maybe_failure = EnsureHasTransitionArray(this); |
| 3438 if (maybe_failure->IsFailure()) return maybe_failure; |
| 3439 |
| 3440 transitions()->set_descriptors(value, mode); |
| 3441 return this; |
| 3442 } |
| 3443 |
| 3444 |
| 3445 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { |
| 3498 int len = descriptors->number_of_descriptors(); | 3446 int len = descriptors->number_of_descriptors(); |
| 3499 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); | 3447 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); |
| 3500 SLOW_ASSERT(descriptors->IsSortedNoDuplicates()); | 3448 SLOW_ASSERT(descriptors->IsSortedNoDuplicates()); |
| 3501 | 3449 |
| 3502 #ifdef DEBUG | 3450 #ifdef DEBUG |
| 3503 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; | 3451 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; |
| 3504 for (int i = 0; i < len; ++i) used_indices[i] = false; | 3452 for (int i = 0; i < len; ++i) used_indices[i] = false; |
| 3505 | 3453 |
| 3506 // Ensure that all enumeration indexes between 1 and length occur uniquely in | 3454 // Ensure that all enumeration indexes between 1 and length occur uniquely in |
| 3507 // the descriptor array. | 3455 // the descriptor array. |
| 3508 for (int i = 0; i < len; ++i) { | 3456 for (int i = 0; i < len; ++i) { |
| 3509 int enum_index = descriptors->GetDetails(i).index() - | 3457 int enum_index = descriptors->GetDetails(i).index() - |
| 3510 PropertyDetails::kInitialIndex; | 3458 PropertyDetails::kInitialIndex; |
| 3511 ASSERT(0 <= enum_index && enum_index < len); | 3459 ASSERT(0 <= enum_index && enum_index < len); |
| 3512 ASSERT(!used_indices[enum_index]); | 3460 ASSERT(!used_indices[enum_index]); |
| 3513 used_indices[enum_index] = true; | 3461 used_indices[enum_index] = true; |
| 3514 } | 3462 } |
| 3515 #endif | 3463 #endif |
| 3516 | 3464 |
| 3517 set_instance_descriptors(descriptors); | 3465 MaybeObject* maybe_failure = SetDescriptors(descriptors); |
| 3466 if (maybe_failure->IsFailure()) return maybe_failure; |
| 3518 | 3467 |
| 3519 for (int i = 0; i < len; ++i) { | 3468 for (int i = 0; i < len; ++i) { |
| 3520 if (descriptors->GetDetails(i).index() == len) { | 3469 if (descriptors->GetDetails(i).index() == len) { |
| 3521 SetLastAdded(i); | 3470 SetLastAdded(i); |
| 3522 break; | 3471 return this; |
| 3523 } | 3472 } |
| 3524 } | 3473 } |
| 3525 | 3474 |
| 3526 ASSERT((len == 0 && LastAdded() == kNoneAdded) || | 3475 ASSERT(len == 0 && LastAdded() == kNoneAdded); |
| 3527 len == descriptors->GetDetails(LastAdded()).index()); | 3476 return this; |
| 3528 } | 3477 } |
| 3529 | 3478 |
| 3530 | 3479 |
| 3531 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) | 3480 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) |
| 3532 | 3481 |
| 3533 | 3482 |
| 3534 void Map::ClearDescriptorArray(Heap* heap, WriteBarrierMode mode) { | 3483 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { |
| 3535 Object* back_pointer = GetBackPointer(); | 3484 Object* back_pointer = GetBackPointer(); |
| 3536 #ifdef DEBUG | 3485 #ifdef DEBUG |
| 3537 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | 3486 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 3538 if (object->IsDescriptorArray()) { | 3487 if (object->IsTransitionArray()) { |
| 3539 ZapTransitions(); | 3488 ZapTransitions(); |
| 3540 } else { | 3489 } else { |
| 3541 ASSERT(object->IsMap() || object->IsUndefined()); | 3490 ASSERT(object->IsMap() || object->IsUndefined()); |
| 3542 } | 3491 } |
| 3543 #endif | 3492 #endif |
| 3544 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, back_pointer); | 3493 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); |
| 3545 CONDITIONAL_WRITE_BARRIER( | 3494 CONDITIONAL_WRITE_BARRIER( |
| 3546 heap, this, kInstanceDescriptorsOrBackPointerOffset, back_pointer, mode); | 3495 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); |
| 3547 } | 3496 } |
| 3548 | 3497 |
| 3549 | 3498 |
| 3550 void Map::AppendDescriptor(Descriptor* desc, | 3499 void Map::AppendDescriptor(Descriptor* desc, |
| 3551 const DescriptorArray::WhitenessWitness& witness) { | 3500 const DescriptorArray::WhitenessWitness& witness) { |
| 3552 DescriptorArray* descriptors = instance_descriptors(); | 3501 DescriptorArray* descriptors = instance_descriptors(); |
| 3553 int set_descriptors = NumberOfSetDescriptors(); | 3502 int set_descriptors = NumberOfSetDescriptors(); |
| 3554 int new_last_added = descriptors->Append(desc, witness, set_descriptors); | 3503 int new_last_added = descriptors->Append(desc, witness, set_descriptors); |
| 3555 SetLastAdded(new_last_added); | 3504 SetLastAdded(new_last_added); |
| 3556 } | 3505 } |
| 3557 | 3506 |
| 3558 | 3507 |
| 3559 Object* Map::GetBackPointer() { | 3508 Object* Map::GetBackPointer() { |
| 3560 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | 3509 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 3561 if (object->IsDescriptorArray()) { | 3510 if (object->IsDescriptorArray()) { |
| 3562 return DescriptorArray::cast(object)->back_pointer_storage(); | 3511 return TransitionArray::cast(object)->back_pointer_storage(); |
| 3563 } else { | 3512 } else { |
| 3564 ASSERT(object->IsMap() || object->IsUndefined()); | 3513 ASSERT(object->IsMap() || object->IsUndefined()); |
| 3565 return object; | 3514 return object; |
| 3566 } | 3515 } |
| 3567 } | 3516 } |
| 3568 | 3517 |
| 3569 | 3518 |
| 3570 bool Map::HasElementsTransition() { | 3519 bool Map::HasElementsTransition() { |
| 3571 return HasTransitionArray() && transitions()->HasElementsTransition(); | 3520 return HasTransitionArray() && transitions()->HasElementsTransition(); |
| 3572 } | 3521 } |
| 3573 | 3522 |
| 3574 | 3523 |
| 3575 bool Map::HasTransitionArray() { | 3524 bool Map::HasTransitionArray() { |
| 3576 return instance_descriptors()->HasTransitionArray(); | 3525 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 3526 return object->IsTransitionArray(); |
| 3577 } | 3527 } |
| 3578 | 3528 |
| 3579 | 3529 |
| 3580 Map* Map::elements_transition_map() { | 3530 Map* Map::elements_transition_map() { |
| 3581 return transitions()->elements_transition(); | 3531 return transitions()->elements_transition(); |
| 3582 } | 3532 } |
| 3583 | 3533 |
| 3584 | 3534 |
| 3585 bool Map::CanHaveMoreTransitions() { | 3535 bool Map::CanHaveMoreTransitions() { |
| 3586 if (!HasTransitionArray()) return true; | 3536 if (!HasTransitionArray()) return true; |
| 3587 return FixedArray::SizeFor(transitions()->length() + | 3537 return FixedArray::SizeFor(transitions()->length() + |
| 3588 TransitionArray::kTransitionSize) | 3538 TransitionArray::kTransitionSize) |
| 3589 <= Page::kMaxNonCodeHeapObjectSize; | 3539 <= Page::kMaxNonCodeHeapObjectSize; |
| 3590 } | 3540 } |
| 3591 | 3541 |
| 3592 | 3542 |
| 3593 MaybeObject* Map::AddTransition(String* key, Map* target) { | 3543 MaybeObject* Map::AddTransition(String* key, Map* target) { |
| 3594 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); | 3544 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); |
| 3595 return TransitionArray::NewWith(key, target); | 3545 return TransitionArray::NewWith(key, target); |
| 3596 } | 3546 } |
| 3597 | 3547 |
| 3598 | 3548 |
| 3599 void Map::SetTransition(int transition_index, Map* target) { | 3549 void Map::SetTransition(int transition_index, Map* target) { |
| 3600 transitions()->SetTarget(transition_index, target); | 3550 transitions()->SetTarget(transition_index, target); |
| 3601 } | 3551 } |
| 3602 | 3552 |
| 3603 | 3553 |
| 3604 // If the map is using the empty descriptor array, install a new empty | |
| 3605 // descriptor array that will contain an elements transition. | |
| 3606 static MaybeObject* AllowTransitions(Map* map) { | |
| 3607 if (map->instance_descriptors()->MayContainTransitions()) return map; | |
| 3608 DescriptorArray* descriptors; | |
| 3609 MaybeObject* maybe_descriptors = | |
| 3610 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED); | |
| 3611 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | |
| 3612 map->set_instance_descriptors(descriptors); | |
| 3613 return descriptors; | |
| 3614 } | |
| 3615 | |
| 3616 | |
| 3617 // If the descriptor is using the empty transition array, install a new empty | |
| 3618 // transition array that will have place for an element transition. | |
| 3619 static MaybeObject* EnsureHasTransitionArray(Map* map) { | |
| 3620 if (map->HasTransitionArray()) return map; | |
| 3621 | |
| 3622 AllowTransitions(map); | |
| 3623 | |
| 3624 TransitionArray* transitions; | |
| 3625 MaybeObject* maybe_transitions = TransitionArray::Allocate(0); | |
| 3626 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | |
| 3627 MaybeObject* added_transitions = map->set_transitions(transitions); | |
| 3628 if (added_transitions->IsFailure()) return added_transitions; | |
| 3629 return transitions; | |
| 3630 } | |
| 3631 | |
| 3632 | |
| 3633 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { | 3554 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { |
| 3634 MaybeObject* allow_elements = EnsureHasTransitionArray(this); | 3555 MaybeObject* allow_elements = EnsureHasTransitionArray(this); |
| 3635 if (allow_elements->IsFailure()) return allow_elements; | 3556 if (allow_elements->IsFailure()) return allow_elements; |
| 3636 transitions()->set_elements_transition(transitioned_map); | 3557 transitions()->set_elements_transition(transitioned_map); |
| 3637 return this; | 3558 return this; |
| 3638 } | 3559 } |
| 3639 | 3560 |
| 3640 | 3561 |
| 3641 FixedArray* Map::GetPrototypeTransitions() { | 3562 FixedArray* Map::GetPrototypeTransitions() { |
| 3642 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); | 3563 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3660 return this; | 3581 return this; |
| 3661 } | 3582 } |
| 3662 | 3583 |
| 3663 | 3584 |
| 3664 bool Map::HasPrototypeTransitions() { | 3585 bool Map::HasPrototypeTransitions() { |
| 3665 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); | 3586 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); |
| 3666 } | 3587 } |
| 3667 | 3588 |
| 3668 | 3589 |
| 3669 TransitionArray* Map::transitions() { | 3590 TransitionArray* Map::transitions() { |
| 3670 return instance_descriptors()->transitions(); | 3591 ASSERT(HasTransitionArray()); |
| 3592 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 3593 return TransitionArray::cast(object); |
| 3671 } | 3594 } |
| 3672 | 3595 |
| 3673 | 3596 |
| 3674 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { | 3597 void Map::set_transitions(TransitionArray* transition_array, |
| 3675 #ifdef DEBUG | 3598 WriteBarrierMode mode) { |
| 3676 ZapTransitions(); | 3599 transition_array->set_descriptors(instance_descriptors()); |
| 3677 #endif | 3600 transition_array->set_back_pointer_storage(GetBackPointer()); |
| 3678 DescriptorArray* descriptors = instance_descriptors(); | |
| 3679 if (descriptors->number_of_descriptors() == 0) { | |
| 3680 ClearDescriptorArray(heap, mode); | |
| 3681 } else { | |
| 3682 descriptors->ClearTransitions(); | |
| 3683 } | |
| 3684 } | |
| 3685 | |
| 3686 | |
| 3687 MaybeObject* Map::set_transitions(TransitionArray* transitions_array) { | |
| 3688 MaybeObject* allow_transitions = AllowTransitions(this); | |
| 3689 if (allow_transitions->IsFailure()) return allow_transitions; | |
| 3690 #ifdef DEBUG | 3601 #ifdef DEBUG |
| 3691 if (HasTransitionArray()) { | 3602 if (HasTransitionArray()) { |
| 3692 ASSERT(transitions() != transitions_array); | 3603 ASSERT(transitions() != transition_array); |
| 3693 ZapTransitions(); | 3604 ZapTransitions(); |
| 3694 } | 3605 } |
| 3695 #endif | 3606 #endif |
| 3696 instance_descriptors()->set_transitions(transitions_array); | 3607 |
| 3697 return this; | 3608 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); |
| 3609 CONDITIONAL_WRITE_BARRIER( |
| 3610 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); |
| 3698 } | 3611 } |
| 3699 | 3612 |
| 3700 | 3613 |
| 3701 void Map::init_back_pointer(Object* undefined) { | 3614 void Map::init_back_pointer(Object* undefined) { |
| 3702 ASSERT(undefined->IsUndefined()); | 3615 ASSERT(undefined->IsUndefined()); |
| 3703 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined); | 3616 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined); |
| 3704 } | 3617 } |
| 3705 | 3618 |
| 3706 | 3619 |
| 3707 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { | 3620 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { |
| 3708 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); | 3621 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); |
| 3709 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || | 3622 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || |
| 3710 (value->IsMap() && GetBackPointer()->IsUndefined())); | 3623 (value->IsMap() && GetBackPointer()->IsUndefined())); |
| 3711 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset); | 3624 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 3712 if (object->IsDescriptorArray()) { | 3625 if (object->IsTransitionArray()) { |
| 3713 DescriptorArray::cast(object)->set_back_pointer_storage(value); | 3626 TransitionArray::cast(object)->set_back_pointer_storage(value); |
| 3714 } else { | 3627 } else { |
| 3715 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value); | 3628 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value); |
| 3716 CONDITIONAL_WRITE_BARRIER( | 3629 CONDITIONAL_WRITE_BARRIER( |
| 3717 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode); | 3630 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode); |
| 3718 } | 3631 } |
| 3719 } | 3632 } |
| 3720 | 3633 |
| 3721 | 3634 |
| 3722 // Can either be Smi (no transitions), normal transition array, or a transition | 3635 // Can either be Smi (no transitions), normal transition array, or a transition |
| 3723 // array with the header overwritten as a Smi (thus iterating). | 3636 // array with the header overwritten as a Smi (thus iterating). |
| 3724 TransitionArray* Map::unchecked_transition_array() { | 3637 TransitionArray* Map::unchecked_transition_array() { |
| 3725 ASSERT(HasTransitionArray()); | 3638 Object* object = *HeapObject::RawField(this, |
| 3726 Object* object = *HeapObject::RawField(instance_descriptors(), | 3639 Map::kTransitionsOrBackPointerOffset); |
| 3727 DescriptorArray::kTransitionsOffset); | |
| 3728 ASSERT(!object->IsSmi()); | |
| 3729 TransitionArray* transition_array = static_cast<TransitionArray*>(object); | 3640 TransitionArray* transition_array = static_cast<TransitionArray*>(object); |
| 3730 return transition_array; | 3641 return transition_array; |
| 3731 } | 3642 } |
| 3732 | 3643 |
| 3733 | 3644 |
| 3734 HeapObject* Map::UncheckedPrototypeTransitions() { | 3645 HeapObject* Map::UncheckedPrototypeTransitions() { |
| 3735 ASSERT(HasTransitionArray()); | 3646 ASSERT(HasTransitionArray()); |
| 3736 ASSERT(unchecked_transition_array()->HasPrototypeTransitions()); | 3647 ASSERT(unchecked_transition_array()->HasPrototypeTransitions()); |
| 3737 return unchecked_transition_array()->UncheckedPrototypeTransitions(); | 3648 return unchecked_transition_array()->UncheckedPrototypeTransitions(); |
| 3738 } | 3649 } |
| (...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5390 #undef WRITE_UINT32_FIELD | 5301 #undef WRITE_UINT32_FIELD |
| 5391 #undef READ_SHORT_FIELD | 5302 #undef READ_SHORT_FIELD |
| 5392 #undef WRITE_SHORT_FIELD | 5303 #undef WRITE_SHORT_FIELD |
| 5393 #undef READ_BYTE_FIELD | 5304 #undef READ_BYTE_FIELD |
| 5394 #undef WRITE_BYTE_FIELD | 5305 #undef WRITE_BYTE_FIELD |
| 5395 | 5306 |
| 5396 | 5307 |
| 5397 } } // namespace v8::internal | 5308 } } // namespace v8::internal |
| 5398 | 5309 |
| 5399 #endif // V8_OBJECTS_INL_H_ | 5310 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |