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

Side by Side Diff: src/objects-inl.h

Issue 10697015: Separating transitions from descriptors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Using WhitenessWitness in TransitionArray code. Created 8 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 | Annotate | Revision Log
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('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 // 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 29 matching lines...) Expand all
40 #include "contexts.h" 40 #include "contexts.h"
41 #include "conversions-inl.h" 41 #include "conversions-inl.h"
42 #include "heap.h" 42 #include "heap.h"
43 #include "isolate.h" 43 #include "isolate.h"
44 #include "property.h" 44 #include "property.h"
45 #include "spaces.h" 45 #include "spaces.h"
46 #include "store-buffer.h" 46 #include "store-buffer.h"
47 #include "v8memory.h" 47 #include "v8memory.h"
48 #include "factory.h" 48 #include "factory.h"
49 #include "incremental-marking.h" 49 #include "incremental-marking.h"
50 #include "transitions-inl.h"
50 51
51 namespace v8 { 52 namespace v8 {
52 namespace internal { 53 namespace internal {
53 54
54 PropertyDetails::PropertyDetails(Smi* smi) { 55 PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value(); 56 value_ = smi->value();
56 } 57 }
57 58
58 59
59 Smi* PropertyDetails::AsSmi() { 60 Smi* PropertyDetails::AsSmi() {
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 TYPE_CHECKER(Map, MAP_TYPE) 518 TYPE_CHECKER(Map, MAP_TYPE)
518 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE) 519 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
519 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE) 520 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
520 521
521 522
522 bool Object::IsDescriptorArray() { 523 bool Object::IsDescriptorArray() {
523 return IsFixedArray(); 524 return IsFixedArray();
524 } 525 }
525 526
526 527
528 bool Object::IsTransitionArray() {
529 return IsFixedArray();
530 }
531
532
527 bool Object::IsDeoptimizationInputData() { 533 bool Object::IsDeoptimizationInputData() {
528 // Must be a fixed array. 534 // Must be a fixed array.
529 if (!IsFixedArray()) return false; 535 if (!IsFixedArray()) return false;
530 536
531 // There's no sure way to detect the difference between a fixed array and 537 // There's no sure way to detect the difference between a fixed array and
532 // a deoptimization data array. Since this is used for asserts we can 538 // a deoptimization data array. Since this is used for asserts we can
533 // check that the length is zero or else the fixed size plus a multiple of 539 // check that the length is zero or else the fixed size plus a multiple of
534 // the entry size. 540 // the entry size.
535 int length = FixedArray::cast(this)->length(); 541 int length = FixedArray::cast(this)->length();
536 if (length == 0) return true; 542 if (length == 0) return true;
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 this == HEAP->empty_descriptor_array()); 1884 this == HEAP->empty_descriptor_array());
1879 return length() < kFirstIndex; 1885 return length() < kFirstIndex;
1880 } 1886 }
1881 1887
1882 1888
1883 bool DescriptorArray::MayContainTransitions() { 1889 bool DescriptorArray::MayContainTransitions() {
1884 return !IsEmpty(); 1890 return !IsEmpty();
1885 } 1891 }
1886 1892
1887 1893
1894 bool DescriptorArray::HasTransitionArray() {
1895 return MayContainTransitions() && !get(kTransitionsIndex)->IsSmi();
1896 }
1897
1898
1888 int DescriptorArray::bit_field3_storage() { 1899 int DescriptorArray::bit_field3_storage() {
1889 Object* storage = READ_FIELD(this, kBitField3StorageOffset); 1900 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1890 return Smi::cast(storage)->value(); 1901 return Smi::cast(storage)->value();
1891 } 1902 }
1892 1903
1893 void DescriptorArray::set_bit_field3_storage(int value) { 1904 void DescriptorArray::set_bit_field3_storage(int value) {
1894 ASSERT(this->MayContainTransitions()); 1905 ASSERT(length() > kBitField3StorageIndex);
1895 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value)); 1906 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
1896 } 1907 }
1897 1908
1898 1909
1899 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array, 1910 void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1900 int first, 1911 int first,
1901 int second) { 1912 int second) {
1902 Object* tmp = array->get(first); 1913 Object* tmp = array->get(first);
1903 NoIncrementalWriteBarrierSet(array, first, array->get(second)); 1914 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1904 NoIncrementalWriteBarrierSet(array, second, tmp); 1915 NoIncrementalWriteBarrierSet(array, second, tmp);
1905 } 1916 }
1906 1917
1907 1918
1919 // Perform a binary search in a fixed array. Low and high are entry indices. If
1920 // there are three entries in this array it should be called with low=0 and
1921 // high=2.
1922 template<typename T>
1923 int BinarySearch(T* array, String* name, int low, int high) {
1924 uint32_t hash = name->Hash();
1925 int limit = high;
1926
1927 ASSERT(low <= high);
1928
1929 while (low != high) {
1930 int mid = (low + high) / 2;
1931 String* mid_name = array->GetKey(mid);
1932 uint32_t mid_hash = mid_name->Hash();
1933
1934 if (mid_hash >= hash) {
1935 high = mid;
1936 } else {
1937 low = mid + 1;
1938 }
1939 }
1940
1941 for (; low <= limit && array->GetKey(low)->Hash() == hash; ++low) {
1942 if (array->GetKey(low)->Equals(name)) return low;
1943 }
1944
1945 return T::kNotFound;
1946 }
1947
1948
1949 // Perform a linear search in this fixed array. len is the number of entry
1950 // indices that are valid.
1951 template<typename T>
1952 int LinearSearch(T* array, SearchMode mode, String* name, int len) {
1953 uint32_t hash = name->Hash();
1954 for (int number = 0; number < len; number++) {
1955 String* entry = array->GetKey(number);
1956 uint32_t current_hash = entry->Hash();
1957 if (mode == EXPECT_SORTED && current_hash > hash) break;
1958 if (current_hash == hash && name->Equals(entry)) return number;
1959 }
1960 return T::kNotFound;
1961 }
1962
1963
1964 template<typename T>
1965 int Search(T* array, String* name) {
1966 SLOW_ASSERT(array->IsSortedNoDuplicates());
1967
1968 // Check for empty descriptor array.
1969 int nof = array->number_of_entries();
1970 if (nof == 0) return T::kNotFound;
1971
1972 // Fast case: do linear search for small arrays.
1973 const int kMaxElementsForLinearSearch = 8;
1974 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
1975 return LinearSearch(array, EXPECT_SORTED, name, nof);
1976 }
1977
1978 // Slow case: perform binary search.
1979 return BinarySearch(array, name, 0, nof - 1);
1980 }
1981
1982
1908 int DescriptorArray::Search(String* name) { 1983 int DescriptorArray::Search(String* name) {
1909 SLOW_ASSERT(IsSortedNoDuplicates()); 1984 return internal::Search(this, name);
1910
1911 // Check for empty descriptor array.
1912 int nof = number_of_descriptors();
1913 if (nof == 0) return kNotFound;
1914
1915 // Fast case: do linear search for small arrays.
1916 const int kMaxElementsForLinearSearch = 8;
1917 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
1918 return LinearSearch(EXPECT_SORTED, name, nof);
1919 }
1920
1921 // Slow case: perform binary search.
1922 return BinarySearch(name, 0, nof - 1);
1923 } 1985 }
1924 1986
1925 1987
1926 int DescriptorArray::SearchWithCache(String* name) { 1988 int DescriptorArray::SearchWithCache(String* name) {
1927 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name); 1989 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
1990 int number = cache->Lookup(this, name);
1928 if (number == DescriptorLookupCache::kAbsent) { 1991 if (number == DescriptorLookupCache::kAbsent) {
1929 number = Search(name); 1992 number = internal::Search(this, name);
1930 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number); 1993 cache->Update(this, name, number);
1931 } 1994 }
1932 return number; 1995 return number;
1933 } 1996 }
1934 1997
1935 1998
1936 Map* DescriptorArray::elements_transition_map() { 1999 TransitionArray* DescriptorArray::transitions() {
1937 if (!this->MayContainTransitions()) { 2000 if (!this->MayContainTransitions()) return NULL;
1938 return NULL; 2001 Object* array = get(kTransitionsIndex);
1939 } 2002 return TransitionArray::cast(array);
1940 Object* transition_map = get(kTransitionsIndex);
1941 if (transition_map == Smi::FromInt(0)) {
1942 return NULL;
1943 } else {
1944 return Map::cast(transition_map);
1945 }
1946 } 2003 }
1947 2004
1948 2005
1949 void DescriptorArray::set_elements_transition_map( 2006 void DescriptorArray::ClearTransitions() {
1950 Map* transition_map, WriteBarrierMode mode) {
1951 ASSERT(this->length() > kTransitionsIndex);
1952 Heap* heap = GetHeap();
1953 WRITE_FIELD(this, kTransitionsOffset, transition_map);
1954 CONDITIONAL_WRITE_BARRIER(
1955 heap, this, kTransitionsOffset, transition_map, mode);
1956 ASSERT(DescriptorArray::cast(this));
1957 }
1958
1959
1960 void DescriptorArray::ClearElementsTransition() {
1961 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0)); 2007 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0));
1962 } 2008 }
1963 2009
1964 2010
2011 void DescriptorArray::set_transitions(TransitionArray* transitions_array,
2012 WriteBarrierMode mode) {
2013 Heap* heap = GetHeap();
2014 WRITE_FIELD(this, kTransitionsOffset, transitions_array);
2015 CONDITIONAL_WRITE_BARRIER(
2016 heap, this, kTransitionsOffset, transitions_array, mode);
2017 }
2018
2019
1965 Object** DescriptorArray::GetKeySlot(int descriptor_number) { 2020 Object** DescriptorArray::GetKeySlot(int descriptor_number) {
1966 ASSERT(descriptor_number < number_of_descriptors()); 2021 ASSERT(descriptor_number < number_of_descriptors());
1967 return HeapObject::RawField( 2022 return HeapObject::RawField(
1968 reinterpret_cast<HeapObject*>(this), 2023 reinterpret_cast<HeapObject*>(this),
1969 OffsetOfElementAt(ToKeyIndex(descriptor_number))); 2024 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
1970 } 2025 }
1971 2026
1972 2027
1973 String* DescriptorArray::GetKey(int descriptor_number) { 2028 String* DescriptorArray::GetKey(int descriptor_number) {
1974 ASSERT(descriptor_number < number_of_descriptors()); 2029 ASSERT(descriptor_number < number_of_descriptors());
1975 return String::cast(get(ToKeyIndex(descriptor_number))); 2030 return String::cast(get(ToKeyIndex(descriptor_number)));
1976 } 2031 }
1977 2032
1978 2033
1979 void DescriptorArray::SetKeyUnchecked(Heap* heap,
1980 int descriptor_number,
1981 String* key) {
1982 ASSERT(descriptor_number < number_of_descriptors());
1983 set_unchecked(heap,
1984 ToKeyIndex(descriptor_number),
1985 key,
1986 UPDATE_WRITE_BARRIER);
1987 }
1988
1989
1990 Object** DescriptorArray::GetValueSlot(int descriptor_number) { 2034 Object** DescriptorArray::GetValueSlot(int descriptor_number) {
1991 ASSERT(descriptor_number < number_of_descriptors()); 2035 ASSERT(descriptor_number < number_of_descriptors());
1992 return HeapObject::RawField( 2036 return HeapObject::RawField(
1993 reinterpret_cast<HeapObject*>(this), 2037 reinterpret_cast<HeapObject*>(this),
1994 OffsetOfElementAt(ToValueIndex(descriptor_number))); 2038 OffsetOfElementAt(ToValueIndex(descriptor_number)));
1995 } 2039 }
1996 2040
1997 2041
1998 Object* DescriptorArray::GetValue(int descriptor_number) { 2042 Object* DescriptorArray::GetValue(int descriptor_number) {
1999 ASSERT(descriptor_number < number_of_descriptors()); 2043 ASSERT(descriptor_number < number_of_descriptors());
2000 return get(ToValueIndex(descriptor_number)); 2044 return get(ToValueIndex(descriptor_number));
2001 } 2045 }
2002 2046
2003 2047
2004 void DescriptorArray::SetNullValueUnchecked(Heap* heap, int descriptor_number) {
2005 ASSERT(descriptor_number < number_of_descriptors());
2006 set_null_unchecked(heap, ToValueIndex(descriptor_number));
2007 }
2008
2009
2010
2011 void DescriptorArray::SetValueUnchecked(Heap* heap,
2012 int descriptor_number,
2013 Object* value) {
2014 ASSERT(descriptor_number < number_of_descriptors());
2015 set_unchecked(heap,
2016 ToValueIndex(descriptor_number),
2017 value,
2018 UPDATE_WRITE_BARRIER);
2019 }
2020
2021
2022 PropertyDetails DescriptorArray::GetDetails(int descriptor_number) { 2048 PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
2023 ASSERT(descriptor_number < number_of_descriptors()); 2049 ASSERT(descriptor_number < number_of_descriptors());
2024 Object* details = get(ToDetailsIndex(descriptor_number)); 2050 Object* details = get(ToDetailsIndex(descriptor_number));
2025 return PropertyDetails(Smi::cast(details)); 2051 return PropertyDetails(Smi::cast(details));
2026 } 2052 }
2027 2053
2028 2054
2029 void DescriptorArray::SetDetailsUnchecked(int descriptor_number, Smi* value) {
2030 ASSERT(descriptor_number < number_of_descriptors());
2031 set_unchecked(ToDetailsIndex(descriptor_number), value);
2032 }
2033
2034
2035 PropertyType DescriptorArray::GetType(int descriptor_number) { 2055 PropertyType DescriptorArray::GetType(int descriptor_number) {
2036 return GetDetails(descriptor_number).type(); 2056 return GetDetails(descriptor_number).type();
2037 } 2057 }
2038 2058
2039 2059
2040 int DescriptorArray::GetFieldIndex(int descriptor_number) { 2060 int DescriptorArray::GetFieldIndex(int descriptor_number) {
2041 return Descriptor::IndexFromValue(GetValue(descriptor_number)); 2061 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2042 } 2062 }
2043 2063
2044 2064
2045 JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) { 2065 JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2046 return JSFunction::cast(GetValue(descriptor_number)); 2066 return JSFunction::cast(GetValue(descriptor_number));
2047 } 2067 }
2048 2068
2049 2069
2050 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) { 2070 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2051 ASSERT(GetType(descriptor_number) == CALLBACKS); 2071 ASSERT(GetType(descriptor_number) == CALLBACKS);
2052 return GetValue(descriptor_number); 2072 return GetValue(descriptor_number);
2053 } 2073 }
2054 2074
2055 2075
2056 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) { 2076 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2057 ASSERT(GetType(descriptor_number) == CALLBACKS); 2077 ASSERT(GetType(descriptor_number) == CALLBACKS);
2058 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number)); 2078 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
2059 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address()); 2079 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
2060 } 2080 }
2061 2081
2062 2082
2063 bool DescriptorArray::IsProperty(int descriptor_number) {
2064 Entry entry(this, descriptor_number);
2065 return IsPropertyDescriptor(&entry);
2066 }
2067
2068
2069 bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
2070 switch (GetType(descriptor_number)) {
2071 case MAP_TRANSITION:
2072 case CONSTANT_TRANSITION:
2073 return true;
2074 case CALLBACKS: {
2075 Object* value = GetValue(descriptor_number);
2076 if (!value->IsAccessorPair()) return false;
2077 AccessorPair* accessors = AccessorPair::cast(value);
2078 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2079 }
2080 case NORMAL:
2081 case FIELD:
2082 case CONSTANT_FUNCTION:
2083 case HANDLER:
2084 case INTERCEPTOR:
2085 return false;
2086 case NONEXISTENT:
2087 UNREACHABLE();
2088 break;
2089 }
2090 UNREACHABLE(); // Keep the compiler happy.
2091 return false;
2092 }
2093
2094
2095 void DescriptorArray::Get(int descriptor_number, Descriptor* desc) { 2083 void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2096 desc->Init(GetKey(descriptor_number), 2084 desc->Init(GetKey(descriptor_number),
2097 GetValue(descriptor_number), 2085 GetValue(descriptor_number),
2098 GetDetails(descriptor_number)); 2086 GetDetails(descriptor_number));
2099 } 2087 }
2100 2088
2101 2089
2102 void DescriptorArray::Set(int descriptor_number, 2090 void DescriptorArray::Set(int descriptor_number,
2103 Descriptor* desc, 2091 Descriptor* desc,
2104 const WhitenessWitness&) { 2092 const WhitenessWitness&) {
(...skipping 17 matching lines...) Expand all
2122 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second)); 2110 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
2123 NoIncrementalWriteBarrierSwap(this, 2111 NoIncrementalWriteBarrierSwap(this,
2124 ToValueIndex(first), 2112 ToValueIndex(first),
2125 ToValueIndex(second)); 2113 ToValueIndex(second));
2126 NoIncrementalWriteBarrierSwap(this, 2114 NoIncrementalWriteBarrierSwap(this,
2127 ToDetailsIndex(first), 2115 ToDetailsIndex(first),
2128 ToDetailsIndex(second)); 2116 ToDetailsIndex(second));
2129 } 2117 }
2130 2118
2131 2119
2132 DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array) 2120 FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
2133 : marking_(array->GetHeap()->incremental_marking()) { 2121 : marking_(array->GetHeap()->incremental_marking()) {
2134 marking_->EnterNoMarkingScope(); 2122 marking_->EnterNoMarkingScope();
2135 if (array->number_of_descriptors() > 0) { 2123 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2136 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2137 }
2138 } 2124 }
2139 2125
2140 2126
2141 DescriptorArray::WhitenessWitness::~WhitenessWitness() { 2127 FixedArray::WhitenessWitness::~WhitenessWitness() {
2142 marking_->LeaveNoMarkingScope(); 2128 marking_->LeaveNoMarkingScope();
2143 } 2129 }
2144 2130
2145 2131
2146 template<typename Shape, typename Key> 2132 template<typename Shape, typename Key>
2147 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) { 2133 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2148 const int kMinCapacity = 32; 2134 const int kMinCapacity = 32;
2149 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); 2135 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2150 if (capacity < kMinCapacity) { 2136 if (capacity < kMinCapacity) {
2151 capacity = kMinCapacity; // Guarantee min capacity. 2137 capacity = kMinCapacity; // Guarantee min capacity.
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3424 } 3410 }
3425 } 3411 }
3426 3412
3427 3413
3428 void Map::init_instance_descriptors() { 3414 void Map::init_instance_descriptors() {
3429 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0)); 3415 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3430 } 3416 }
3431 3417
3432 3418
3433 void Map::clear_instance_descriptors() { 3419 void Map::clear_instance_descriptors() {
3434 Object* object = READ_FIELD(this, 3420 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3435 kInstanceDescriptorsOrBitField3Offset);
3436 if (!object->IsSmi()) { 3421 if (!object->IsSmi()) {
3437 #ifdef DEBUG
3438 ZapInstanceDescriptors();
3439 #endif
3440 WRITE_FIELD( 3422 WRITE_FIELD(
3441 this, 3423 this,
3442 kInstanceDescriptorsOrBitField3Offset, 3424 kInstanceDescriptorsOrBitField3Offset,
3443 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage())); 3425 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3444 } 3426 }
3445 } 3427 }
3446 3428
3447 3429
3448 void Map::set_instance_descriptors(DescriptorArray* value, 3430 void Map::set_instance_descriptors(DescriptorArray* value,
3449 WriteBarrierMode mode) { 3431 WriteBarrierMode mode) {
3450 Object* object = READ_FIELD(this, 3432 Object* object = READ_FIELD(this,
3451 kInstanceDescriptorsOrBitField3Offset); 3433 kInstanceDescriptorsOrBitField3Offset);
3452 Heap* heap = GetHeap(); 3434 Heap* heap = GetHeap();
3453 if (value == heap->empty_descriptor_array()) { 3435 if (value == heap->empty_descriptor_array()) {
3454 clear_instance_descriptors(); 3436 clear_instance_descriptors();
3455 return; 3437 return;
3456 } else { 3438 } else {
3457 if (object->IsSmi()) { 3439 if (object->IsSmi()) {
3458 value->set_bit_field3_storage(Smi::cast(object)->value()); 3440 value->set_bit_field3_storage(Smi::cast(object)->value());
3459 } else { 3441 } else {
3460 value->set_bit_field3_storage( 3442 value->set_bit_field3_storage(
3461 DescriptorArray::cast(object)->bit_field3_storage()); 3443 DescriptorArray::cast(object)->bit_field3_storage());
3462 } 3444 }
3463 } 3445 }
3464 ASSERT(!is_shared()); 3446 ASSERT(!is_shared());
3465 #ifdef DEBUG
3466 if (value != instance_descriptors()) {
3467 ZapInstanceDescriptors();
3468 }
3469 #endif
3470 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); 3447 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3471 CONDITIONAL_WRITE_BARRIER( 3448 CONDITIONAL_WRITE_BARRIER(
3472 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode); 3449 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
3473 } 3450 }
3474 3451
3475 3452
3476 int Map::bit_field3() { 3453 int Map::bit_field3() {
3477 Object* object = READ_FIELD(this, 3454 Object* object = READ_FIELD(this,
3478 kInstanceDescriptorsOrBitField3Offset); 3455 kInstanceDescriptorsOrBitField3Offset);
3479 if (object->IsSmi()) { 3456 if (object->IsSmi()) {
3480 return Smi::cast(object)->value(); 3457 return Smi::cast(object)->value();
3481 } else { 3458 } else {
3482 return DescriptorArray::cast(object)->bit_field3_storage(); 3459 return DescriptorArray::cast(object)->bit_field3_storage();
3483 } 3460 }
3484 } 3461 }
3485 3462
3486 3463
3487 void Map::ClearDescriptorArray() { 3464 void Map::ClearDescriptorArray() {
3488 int bitfield3 = bit_field3(); 3465 int bitfield3 = bit_field3();
3489 #ifdef DEBUG 3466 #ifdef DEBUG
3490 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); 3467 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3491 if (!object->IsSmi()) { 3468 if (!object->IsSmi()) {
3492 ZapInstanceDescriptors(); 3469 ZapTransitions();
3493 } 3470 }
3494 #endif 3471 #endif
3495 WRITE_FIELD(this, 3472 WRITE_FIELD(this,
3496 kInstanceDescriptorsOrBitField3Offset, 3473 kInstanceDescriptorsOrBitField3Offset,
3497 Smi::FromInt(bitfield3)); 3474 Smi::FromInt(bitfield3));
3498 } 3475 }
3499 3476
3500 3477
3501 void Map::set_bit_field3(int value) { 3478 void Map::set_bit_field3(int value) {
3502 ASSERT(Smi::IsValid(value)); 3479 ASSERT(Smi::IsValid(value));
(...skipping 11 matching lines...) Expand all
3514 Object* Map::GetBackPointer() { 3491 Object* Map::GetBackPointer() {
3515 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); 3492 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3516 if (object->IsFixedArray()) { 3493 if (object->IsFixedArray()) {
3517 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset); 3494 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3518 } else { 3495 } else {
3519 return object; 3496 return object;
3520 } 3497 }
3521 } 3498 }
3522 3499
3523 3500
3501 bool Map::HasElementsTransition() {
3502 return HasTransitionArray() && transitions()->HasElementsTransition();
3503 }
3504
3505
3506 bool Map::HasTransitionArray() {
3507 return instance_descriptors()->HasTransitionArray();
3508 }
3509
3510
3524 Map* Map::elements_transition_map() { 3511 Map* Map::elements_transition_map() {
3525 return instance_descriptors()->elements_transition_map(); 3512 return transitions()->elements_transition();
3526 } 3513 }
3527 3514
3528 3515
3529 void Map::set_elements_transition_map(Map* transitioned_map) { 3516 MaybeObject* Map::AddTransition(String* key, Object* value) {
3530 return instance_descriptors()->set_elements_transition_map(transitioned_map); 3517 if (HasTransitionArray()) return transitions()->CopyInsert(key, value);
3518 return TransitionArray::NewWith(key, value);
3531 } 3519 }
3532 3520
3533 3521
3522 // If the map does not have a descriptor array, install a new empty
3523 // descriptor array that has room for a transition array.
3524 static MaybeObject* AllowTransitions(Map* map) {
3525 if (map->instance_descriptors()->MayContainTransitions()) return map;
3526 DescriptorArray* descriptors;
3527 MaybeObject* maybe_descriptors =
3528 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3529 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3530 map->set_instance_descriptors(descriptors);
3531 return descriptors;
3532 }
3533
3534
3535 // If the descriptor does not have a transition array, install a new
3536 // transition array that has room for an element transition.
3537 static MaybeObject* AllowElementsTransition(Map* map) {
3538 if (map->HasTransitionArray()) return map;
3539
3540 AllowTransitions(map);
3541
3542 TransitionArray* transitions;
3543 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3544 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3545 MaybeObject* added_transitions = map->set_transitions(transitions);
3546 if (added_transitions->IsFailure()) return added_transitions;
3547 return transitions;
3548 }
3549
3550
3551 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
3552 MaybeObject* allow_elements = AllowElementsTransition(this);
3553 if (allow_elements->IsFailure()) return allow_elements;
3554 transitions()->set_elements_transition(transitioned_map);
3555 return this;
3556 }
3557
3558
3559 TransitionArray* Map::transitions() {
3560 return instance_descriptors()->transitions();
3561 }
3562
3563
3564 void Map::ClearTransitions() {
3565 #ifdef DEBUG
3566 ZapTransitions();
3567 #endif
3568 DescriptorArray* descriptors = instance_descriptors();
3569 if (descriptors->number_of_descriptors() == 0) {
3570 ClearDescriptorArray();
3571 } else {
3572 descriptors->ClearTransitions();
3573 }
3574 }
3575
3576
3577 MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3578 MaybeObject* allow_transitions = AllowTransitions(this);
3579 if (allow_transitions->IsFailure()) return allow_transitions;
3580 #ifdef DEBUG
3581 if (HasTransitionArray()) {
3582 ASSERT(transitions() != transitions_array);
3583 ZapTransitions();
3584 }
3585 #endif
3586 instance_descriptors()->set_transitions(transitions_array);
3587 return this;
3588 }
3589
3590
3534 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { 3591 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3535 Heap* heap = GetHeap(); 3592 Heap* heap = GetHeap();
3536 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); 3593 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3537 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || 3594 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3538 (value->IsMap() && GetBackPointer()->IsUndefined())); 3595 (value->IsMap() && GetBackPointer()->IsUndefined()));
3539 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); 3596 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3540 if (object->IsFixedArray()) { 3597 if (object->IsFixedArray()) {
3541 FixedArray::cast(object)->set( 3598 FixedArray::cast(object)->set(
3542 kProtoTransitionBackPointerOffset, value, mode); 3599 kProtoTransitionBackPointerOffset, value, mode);
3543 } else { 3600 } else {
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after
5218 #undef WRITE_UINT32_FIELD 5275 #undef WRITE_UINT32_FIELD
5219 #undef READ_SHORT_FIELD 5276 #undef READ_SHORT_FIELD
5220 #undef WRITE_SHORT_FIELD 5277 #undef WRITE_SHORT_FIELD
5221 #undef READ_BYTE_FIELD 5278 #undef READ_BYTE_FIELD
5222 #undef WRITE_BYTE_FIELD 5279 #undef WRITE_BYTE_FIELD
5223 5280
5224 5281
5225 } } // namespace v8::internal 5282 } } // namespace v8::internal
5226 5283
5227 #endif // V8_OBJECTS_INL_H_ 5284 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698