| 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 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 String* entry = array->GetKey(sort_index); | 1933 String* entry = array->GetKey(sort_index); |
| 1934 if (entry->Hash() != hash) break; | 1934 if (entry->Hash() != hash) break; |
| 1935 if (entry->Equals(name)) return sort_index; | 1935 if (entry->Equals(name)) return sort_index; |
| 1936 } | 1936 } |
| 1937 | 1937 |
| 1938 return T::kNotFound; | 1938 return T::kNotFound; |
| 1939 } | 1939 } |
| 1940 | 1940 |
| 1941 // Perform a linear search in this fixed array. len is the number of entry | 1941 // Perform a linear search in this fixed array. len is the number of entry |
| 1942 // indices that are valid. | 1942 // indices that are valid. |
| 1943 template<SearchMode search_mode, typename T> | 1943 template<typename T> |
| 1944 int LinearSearch(T* array, String* name, int len, int valid_entries) { | 1944 int LinearSearch(T* array, String* name, int len) { |
| 1945 uint32_t hash = name->Hash(); | 1945 uint32_t hash = name->Hash(); |
| 1946 if (search_mode == ALL_ENTRIES) { | 1946 for (int number = 0; number < len; number++) { |
| 1947 for (int number = 0; number < len; number++) { | 1947 int sorted_index = array->GetSortedKeyIndex(number); |
| 1948 int sorted_index = array->GetSortedKeyIndex(number); | 1948 String* entry = array->GetKey(sorted_index); |
| 1949 String* entry = array->GetKey(sorted_index); | 1949 uint32_t current_hash = entry->Hash(); |
| 1950 uint32_t current_hash = entry->Hash(); | 1950 if (current_hash > hash) break; |
| 1951 if (current_hash > hash) break; | 1951 if (current_hash == hash && entry->Equals(name)) return sorted_index; |
| 1952 if (current_hash == hash && entry->Equals(name)) return sorted_index; | |
| 1953 } | |
| 1954 } else { | |
| 1955 ASSERT(len >= valid_entries); | |
| 1956 for (int number = 0; number < valid_entries; number++) { | |
| 1957 String* entry = array->GetKey(number); | |
| 1958 uint32_t current_hash = entry->Hash(); | |
| 1959 if (current_hash == hash && entry->Equals(name)) return number; | |
| 1960 } | |
| 1961 } | 1952 } |
| 1962 return T::kNotFound; | 1953 return T::kNotFound; |
| 1963 } | 1954 } |
| 1964 | 1955 |
| 1965 | 1956 |
| 1966 template<SearchMode search_mode, typename T> | 1957 template<typename T> |
| 1967 int Search(T* array, String* name, int valid_entries) { | 1958 int Search(T* array, String* name) { |
| 1968 if (search_mode == VALID_ENTRIES) { | 1959 SLOW_ASSERT(array->IsSortedNoDuplicates()); |
| 1969 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries)); | |
| 1970 } else { | |
| 1971 SLOW_ASSERT(array->IsSortedNoDuplicates()); | |
| 1972 } | |
| 1973 | 1960 |
| 1974 int nof = array->number_of_entries(); | 1961 int nof = array->number_of_entries(); |
| 1975 if (nof == 0) return T::kNotFound; | 1962 if (nof == 0) return T::kNotFound; |
| 1976 | 1963 |
| 1977 // Fast case: do linear search for small arrays. | 1964 // Fast case: do linear search for small arrays. |
| 1978 const int kMaxElementsForLinearSearch = 8; | 1965 const int kMaxElementsForLinearSearch = 8; |
| 1979 if (search_mode == VALID_ENTRIES || | 1966 if (nof < kMaxElementsForLinearSearch) { |
| 1980 (search_mode == ALL_ENTRIES && nof < kMaxElementsForLinearSearch)) { | 1967 return LinearSearch(array, name, nof); |
| 1981 return LinearSearch<search_mode>(array, name, nof, valid_entries); | |
| 1982 } | 1968 } |
| 1983 | 1969 |
| 1984 // Slow case: perform binary search. | 1970 // Slow case: perform binary search. |
| 1985 return BinarySearch(array, name, 0, nof - 1); | 1971 return BinarySearch(array, name, 0, nof - 1); |
| 1986 } | 1972 } |
| 1987 | 1973 |
| 1988 | 1974 |
| 1989 int DescriptorArray::Search(String* name, int valid_descriptors) { | 1975 int DescriptorArray::Search(String* name) { |
| 1990 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors); | 1976 return internal::Search(this, name); |
| 1991 } | 1977 } |
| 1992 | 1978 |
| 1993 | 1979 |
| 1994 int DescriptorArray::SearchWithCache(String* name, Map* map) { | 1980 int DescriptorArray::SearchWithCache(String* name) { |
| 1995 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 1981 if (number_of_descriptors() == 0) return kNotFound; |
| 1996 if (number_of_own_descriptors == 0) return kNotFound; | |
| 1997 | 1982 |
| 1998 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); | 1983 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); |
| 1999 int number = cache->Lookup(map, name); | 1984 int number = cache->Lookup(this, name); |
| 2000 | 1985 |
| 2001 if (number == DescriptorLookupCache::kAbsent) { | 1986 if (number == DescriptorLookupCache::kAbsent) { |
| 2002 number = Search(name, number_of_own_descriptors); | 1987 number = Search(name); |
| 2003 cache->Update(map, name, number); | 1988 cache->Update(this, name, number); |
| 2004 } | 1989 } |
| 2005 | 1990 |
| 2006 return number; | 1991 return number; |
| 2007 } | 1992 } |
| 2008 | 1993 |
| 2009 | 1994 |
| 2010 void Map::LookupDescriptor(JSObject* holder, | 1995 void Map::LookupDescriptor(JSObject* holder, |
| 2011 String* name, | 1996 String* name, |
| 2012 LookupResult* result) { | 1997 LookupResult* result) { |
| 2013 DescriptorArray* descriptors = this->instance_descriptors(); | 1998 DescriptorArray* descriptors = this->instance_descriptors(); |
| 2014 int number = descriptors->SearchWithCache(name, this); | 1999 int number = descriptors->SearchWithCache(name); |
| 2015 if (number == DescriptorArray::kNotFound) return result->NotFound(); | 2000 if (number == DescriptorArray::kNotFound) return result->NotFound(); |
| 2016 result->DescriptorResult(holder, descriptors->GetDetails(number), number); | 2001 result->DescriptorResult(holder, descriptors->GetDetails(number), number); |
| 2017 } | 2002 } |
| 2018 | 2003 |
| 2019 | 2004 |
| 2020 void Map::LookupTransition(JSObject* holder, | 2005 void Map::LookupTransition(JSObject* holder, |
| 2021 String* name, | 2006 String* name, |
| 2022 LookupResult* result) { | 2007 LookupResult* result) { |
| 2023 if (HasTransitionArray()) { | 2008 if (HasTransitionArray()) { |
| 2024 TransitionArray* transition_array = transitions(); | 2009 TransitionArray* transition_array = transitions(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2048 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { | 2033 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { |
| 2049 return GetDetails(descriptor_number).pointer(); | 2034 return GetDetails(descriptor_number).pointer(); |
| 2050 } | 2035 } |
| 2051 | 2036 |
| 2052 | 2037 |
| 2053 String* DescriptorArray::GetSortedKey(int descriptor_number) { | 2038 String* DescriptorArray::GetSortedKey(int descriptor_number) { |
| 2054 return GetKey(GetSortedKeyIndex(descriptor_number)); | 2039 return GetKey(GetSortedKeyIndex(descriptor_number)); |
| 2055 } | 2040 } |
| 2056 | 2041 |
| 2057 | 2042 |
| 2058 void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) { | 2043 void DescriptorArray::SetSortedKey(int pointer, int descriptor_number) { |
| 2059 PropertyDetails details = GetDetails(descriptor_index); | 2044 int details_index = ToDetailsIndex(pointer); |
| 2060 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi()); | 2045 PropertyDetails details = PropertyDetails(Smi::cast(get(details_index))); |
| 2046 set_unchecked(details_index, details.set_pointer(descriptor_number).AsSmi()); |
| 2061 } | 2047 } |
| 2062 | 2048 |
| 2063 | 2049 |
| 2064 Object** DescriptorArray::GetValueSlot(int descriptor_number) { | 2050 Object** DescriptorArray::GetValueSlot(int descriptor_number) { |
| 2065 ASSERT(descriptor_number < number_of_descriptors()); | 2051 ASSERT(descriptor_number < number_of_descriptors()); |
| 2066 return HeapObject::RawField( | 2052 return HeapObject::RawField( |
| 2067 reinterpret_cast<HeapObject*>(this), | 2053 reinterpret_cast<HeapObject*>(this), |
| 2068 OffsetOfElementAt(ToValueIndex(descriptor_number))); | 2054 OffsetOfElementAt(ToValueIndex(descriptor_number))); |
| 2069 } | 2055 } |
| 2070 | 2056 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2134 desc->GetValue()); | 2120 desc->GetValue()); |
| 2135 NoIncrementalWriteBarrierSet(this, | 2121 NoIncrementalWriteBarrierSet(this, |
| 2136 ToDetailsIndex(descriptor_number), | 2122 ToDetailsIndex(descriptor_number), |
| 2137 desc->GetDetails().AsSmi()); | 2123 desc->GetDetails().AsSmi()); |
| 2138 } | 2124 } |
| 2139 | 2125 |
| 2140 | 2126 |
| 2141 void DescriptorArray::Append(Descriptor* desc, | 2127 void DescriptorArray::Append(Descriptor* desc, |
| 2142 const WhitenessWitness& witness, | 2128 const WhitenessWitness& witness, |
| 2143 int number_of_set_descriptors) { | 2129 int number_of_set_descriptors) { |
| 2144 int descriptor_number = number_of_set_descriptors; | 2130 int enumeration_index = number_of_set_descriptors + 1; |
| 2145 int enumeration_index = descriptor_number + 1; | |
| 2146 desc->SetEnumerationIndex(enumeration_index); | 2131 desc->SetEnumerationIndex(enumeration_index); |
| 2147 Set(descriptor_number, desc, witness); | 2132 Set(number_of_set_descriptors, desc, witness); |
| 2148 | 2133 |
| 2149 uint32_t hash = desc->GetKey()->Hash(); | 2134 uint32_t hash = desc->GetKey()->Hash(); |
| 2150 | 2135 |
| 2151 int insertion; | 2136 int insertion; |
| 2152 | 2137 |
| 2153 for (insertion = descriptor_number; insertion > 0; --insertion) { | 2138 for (insertion = number_of_set_descriptors; insertion > 0; --insertion) { |
| 2154 String* key = GetSortedKey(insertion - 1); | 2139 String* key = GetSortedKey(insertion - 1); |
| 2155 if (key->Hash() <= hash) break; | 2140 if (key->Hash() <= hash) break; |
| 2156 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); | 2141 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); |
| 2157 } | 2142 } |
| 2158 | 2143 |
| 2159 SetSortedKey(insertion, descriptor_number); | 2144 SetSortedKey(insertion, number_of_set_descriptors); |
| 2160 } | 2145 } |
| 2161 | 2146 |
| 2162 | 2147 |
| 2163 void DescriptorArray::SwapSortedKeys(int first, int second) { | 2148 void DescriptorArray::SwapSortedKeys(int first, int second) { |
| 2164 int first_key = GetSortedKeyIndex(first); | 2149 int first_key = GetSortedKeyIndex(first); |
| 2165 SetSortedKey(first, GetSortedKeyIndex(second)); | 2150 SetSortedKey(first, GetSortedKeyIndex(second)); |
| 2166 SetSortedKey(second, first_key); | 2151 SetSortedKey(second, first_key); |
| 2167 } | 2152 } |
| 2168 | 2153 |
| 2169 | 2154 |
| (...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3048 JSFunction* Map::unchecked_constructor() { | 3033 JSFunction* Map::unchecked_constructor() { |
| 3049 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); | 3034 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); |
| 3050 } | 3035 } |
| 3051 | 3036 |
| 3052 | 3037 |
| 3053 Code::Flags Code::flags() { | 3038 Code::Flags Code::flags() { |
| 3054 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); | 3039 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); |
| 3055 } | 3040 } |
| 3056 | 3041 |
| 3057 | 3042 |
| 3058 void Map::set_owns_descriptors(bool is_shared) { | |
| 3059 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared)); | |
| 3060 } | |
| 3061 | |
| 3062 | |
| 3063 bool Map::owns_descriptors() { | |
| 3064 return OwnsDescriptors::decode(bit_field3()); | |
| 3065 } | |
| 3066 | |
| 3067 | |
| 3068 void Code::set_flags(Code::Flags flags) { | 3043 void Code::set_flags(Code::Flags flags) { |
| 3069 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); | 3044 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); |
| 3070 // Make sure that all call stubs have an arguments count. | 3045 // Make sure that all call stubs have an arguments count. |
| 3071 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && | 3046 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && |
| 3072 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || | 3047 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || |
| 3073 ExtractArgumentsCountFromFlags(flags) >= 0); | 3048 ExtractArgumentsCountFromFlags(flags) >= 0); |
| 3074 WRITE_INT_FIELD(this, kFlagsOffset, flags); | 3049 WRITE_INT_FIELD(this, kFlagsOffset, flags); |
| 3075 } | 3050 } |
| 3076 | 3051 |
| 3077 | 3052 |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3493 } | 3468 } |
| 3494 | 3469 |
| 3495 | 3470 |
| 3496 void Map::set_prototype(Object* value, WriteBarrierMode mode) { | 3471 void Map::set_prototype(Object* value, WriteBarrierMode mode) { |
| 3497 ASSERT(value->IsNull() || value->IsJSReceiver()); | 3472 ASSERT(value->IsNull() || value->IsJSReceiver()); |
| 3498 WRITE_FIELD(this, kPrototypeOffset, value); | 3473 WRITE_FIELD(this, kPrototypeOffset, value); |
| 3499 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); | 3474 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); |
| 3500 } | 3475 } |
| 3501 | 3476 |
| 3502 | 3477 |
| 3503 JSGlobalPropertyCell* Map::descriptors_pointer() { | |
| 3504 ASSERT(HasTransitionArray()); | |
| 3505 return transitions()->descriptors_pointer(); | |
| 3506 } | |
| 3507 | |
| 3508 | |
| 3509 DescriptorArray* Map::instance_descriptors() { | 3478 DescriptorArray* Map::instance_descriptors() { |
| 3510 if (HasTransitionArray()) return transitions()->descriptors(); | 3479 if (!HasTransitionArray()) return GetHeap()->empty_descriptor_array(); |
| 3511 Object* back_pointer = GetBackPointer(); | 3480 return transitions()->descriptors(); |
| 3512 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array(); | |
| 3513 return Map::cast(back_pointer)->instance_descriptors(); | |
| 3514 } | 3481 } |
| 3515 | 3482 |
| 3516 | 3483 |
| 3517 // If the descriptor is using the empty transition array, install a new empty | 3484 // If the descriptor is using the empty transition array, install a new empty |
| 3518 // transition array that will have place for an element transition. | 3485 // transition array that will have place for an element transition. |
| 3519 static MaybeObject* EnsureHasTransitionArray(Map* map) { | 3486 static MaybeObject* EnsureHasTransitionArray(Map* map) { |
| 3520 if (map->HasTransitionArray()) return map; | 3487 if (map->HasTransitionArray()) return map; |
| 3521 | 3488 |
| 3522 TransitionArray* transitions; | 3489 TransitionArray* transitions; |
| 3523 JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer(); | 3490 MaybeObject* maybe_transitions = TransitionArray::Allocate(0); |
| 3524 MaybeObject* maybe_transitions = TransitionArray::Allocate(0, pointer); | |
| 3525 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 3491 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| 3526 | |
| 3527 transitions->set_back_pointer_storage(map->GetBackPointer()); | |
| 3528 map->set_transitions(transitions); | 3492 map->set_transitions(transitions); |
| 3529 return transitions; | 3493 return transitions; |
| 3530 } | 3494 } |
| 3531 | 3495 |
| 3532 | 3496 |
| 3533 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { | 3497 MaybeObject* Map::SetDescriptors(DescriptorArray* value, |
| 3498 WriteBarrierMode mode) { |
| 3534 ASSERT(!is_shared()); | 3499 ASSERT(!is_shared()); |
| 3535 MaybeObject* maybe_failure = EnsureHasTransitionArray(this); | 3500 MaybeObject* maybe_failure = EnsureHasTransitionArray(this); |
| 3536 if (maybe_failure->IsFailure()) return maybe_failure; | 3501 if (maybe_failure->IsFailure()) return maybe_failure; |
| 3537 | 3502 |
| 3538 ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors()); | 3503 transitions()->set_descriptors(value, mode); |
| 3539 transitions()->set_descriptors(value); | |
| 3540 return this; | 3504 return this; |
| 3541 } | 3505 } |
| 3542 | 3506 |
| 3543 | 3507 |
| 3544 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { | 3508 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { |
| 3509 #ifdef DEBUG |
| 3545 int len = descriptors->number_of_descriptors(); | 3510 int len = descriptors->number_of_descriptors(); |
| 3546 #ifdef DEBUG | |
| 3547 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); | 3511 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); |
| 3512 SLOW_ASSERT(descriptors->IsSortedNoDuplicates()); |
| 3548 | 3513 |
| 3549 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; | 3514 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; |
| 3550 for (int i = 0; i < len; ++i) used_indices[i] = false; | 3515 for (int i = 0; i < len; ++i) used_indices[i] = false; |
| 3551 | 3516 |
| 3552 // Ensure that all enumeration indexes between 1 and length occur uniquely in | 3517 // Ensure that all enumeration indexes between 1 and length occur uniquely in |
| 3553 // the descriptor array. | 3518 // the descriptor array. |
| 3554 for (int i = 0; i < len; ++i) { | 3519 for (int i = 0; i < len; ++i) { |
| 3555 int enum_index = descriptors->GetDetails(i).descriptor_index() - | 3520 int enum_index = descriptors->GetDetails(i).descriptor_index() - |
| 3556 PropertyDetails::kInitialIndex; | 3521 PropertyDetails::kInitialIndex; |
| 3557 ASSERT(0 <= enum_index && enum_index < len); | 3522 ASSERT(0 <= enum_index && enum_index < len); |
| 3558 ASSERT(!used_indices[enum_index]); | 3523 ASSERT(!used_indices[enum_index]); |
| 3559 used_indices[enum_index] = true; | 3524 used_indices[enum_index] = true; |
| 3560 } | 3525 } |
| 3561 #endif | 3526 #endif |
| 3562 | 3527 |
| 3563 MaybeObject* maybe_failure = SetDescriptors(descriptors); | 3528 MaybeObject* maybe_failure = SetDescriptors(descriptors); |
| 3564 if (maybe_failure->IsFailure()) return maybe_failure; | 3529 if (maybe_failure->IsFailure()) return maybe_failure; |
| 3565 | 3530 |
| 3566 SetNumberOfOwnDescriptors(len); | 3531 SetNumberOfOwnDescriptors(descriptors->number_of_descriptors()); |
| 3532 |
| 3567 return this; | 3533 return this; |
| 3568 } | 3534 } |
| 3569 | 3535 |
| 3570 | 3536 |
| 3571 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) | 3537 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) |
| 3572 | 3538 |
| 3573 | 3539 |
| 3574 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { | 3540 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { |
| 3575 Object* back_pointer = GetBackPointer(); | 3541 Object* back_pointer = GetBackPointer(); |
| 3576 #ifdef DEBUG | 3542 #ifdef DEBUG |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3625 | 3591 |
| 3626 | 3592 |
| 3627 bool Map::CanHaveMoreTransitions() { | 3593 bool Map::CanHaveMoreTransitions() { |
| 3628 if (!HasTransitionArray()) return true; | 3594 if (!HasTransitionArray()) return true; |
| 3629 return FixedArray::SizeFor(transitions()->length() + | 3595 return FixedArray::SizeFor(transitions()->length() + |
| 3630 TransitionArray::kTransitionSize) | 3596 TransitionArray::kTransitionSize) |
| 3631 <= Page::kMaxNonCodeHeapObjectSize; | 3597 <= Page::kMaxNonCodeHeapObjectSize; |
| 3632 } | 3598 } |
| 3633 | 3599 |
| 3634 | 3600 |
| 3635 JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() { | |
| 3636 if (!owns_descriptors()) return NULL; | |
| 3637 Object* back_pointer = GetBackPointer(); | |
| 3638 if (back_pointer->IsUndefined()) return NULL; | |
| 3639 Map* map = Map::cast(back_pointer); | |
| 3640 ASSERT(map->HasTransitionArray()); | |
| 3641 return map->transitions()->descriptors_pointer(); | |
| 3642 } | |
| 3643 | |
| 3644 | |
| 3645 MaybeObject* Map::AddTransition(String* key, Map* target) { | 3601 MaybeObject* Map::AddTransition(String* key, Map* target) { |
| 3646 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); | 3602 if (HasTransitionArray()) return transitions()->CopyInsert(key, target); |
| 3647 JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer(); | 3603 return TransitionArray::NewWith(key, target); |
| 3648 return TransitionArray::NewWith( | |
| 3649 key, target, descriptors_pointer, GetBackPointer()); | |
| 3650 } | 3604 } |
| 3651 | 3605 |
| 3652 | 3606 |
| 3653 void Map::SetTransition(int transition_index, Map* target) { | 3607 void Map::SetTransition(int transition_index, Map* target) { |
| 3654 transitions()->SetTarget(transition_index, target); | 3608 transitions()->SetTarget(transition_index, target); |
| 3655 } | 3609 } |
| 3656 | 3610 |
| 3657 | 3611 |
| 3658 Map* Map::GetTransition(int transition_index) { | |
| 3659 return transitions()->GetTarget(transition_index); | |
| 3660 } | |
| 3661 | |
| 3662 | |
| 3663 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { | 3612 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { |
| 3664 MaybeObject* allow_elements = EnsureHasTransitionArray(this); | 3613 MaybeObject* allow_elements = EnsureHasTransitionArray(this); |
| 3665 if (allow_elements->IsFailure()) return allow_elements; | 3614 if (allow_elements->IsFailure()) return allow_elements; |
| 3666 transitions()->set_elements_transition(transitioned_map); | 3615 transitions()->set_elements_transition(transitioned_map); |
| 3667 return this; | 3616 return this; |
| 3668 } | 3617 } |
| 3669 | 3618 |
| 3670 | 3619 |
| 3671 FixedArray* Map::GetPrototypeTransitions() { | 3620 FixedArray* Map::GetPrototypeTransitions() { |
| 3672 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); | 3621 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3698 | 3647 |
| 3699 TransitionArray* Map::transitions() { | 3648 TransitionArray* Map::transitions() { |
| 3700 ASSERT(HasTransitionArray()); | 3649 ASSERT(HasTransitionArray()); |
| 3701 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); | 3650 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); |
| 3702 return TransitionArray::cast(object); | 3651 return TransitionArray::cast(object); |
| 3703 } | 3652 } |
| 3704 | 3653 |
| 3705 | 3654 |
| 3706 void Map::set_transitions(TransitionArray* transition_array, | 3655 void Map::set_transitions(TransitionArray* transition_array, |
| 3707 WriteBarrierMode mode) { | 3656 WriteBarrierMode mode) { |
| 3657 transition_array->set_descriptors(instance_descriptors()); |
| 3658 transition_array->set_back_pointer_storage(GetBackPointer()); |
| 3708 #ifdef DEBUG | 3659 #ifdef DEBUG |
| 3709 if (HasTransitionArray()) { | 3660 if (HasTransitionArray()) { |
| 3710 ASSERT(transitions() != transition_array); | 3661 ASSERT(transitions() != transition_array); |
| 3711 ZapTransitions(); | 3662 ZapTransitions(); |
| 3712 } | 3663 } |
| 3713 #endif | 3664 #endif |
| 3714 | 3665 |
| 3715 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); | 3666 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); |
| 3716 CONDITIONAL_WRITE_BARRIER( | 3667 CONDITIONAL_WRITE_BARRIER( |
| 3717 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); | 3668 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); |
| (...skipping 1767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5485 #undef WRITE_UINT32_FIELD | 5436 #undef WRITE_UINT32_FIELD |
| 5486 #undef READ_SHORT_FIELD | 5437 #undef READ_SHORT_FIELD |
| 5487 #undef WRITE_SHORT_FIELD | 5438 #undef WRITE_SHORT_FIELD |
| 5488 #undef READ_BYTE_FIELD | 5439 #undef READ_BYTE_FIELD |
| 5489 #undef WRITE_BYTE_FIELD | 5440 #undef WRITE_BYTE_FIELD |
| 5490 | 5441 |
| 5491 | 5442 |
| 5492 } } // namespace v8::internal | 5443 } } // namespace v8::internal |
| 5493 | 5444 |
| 5494 #endif // V8_OBJECTS_INL_H_ | 5445 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |