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

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

Powered by Google App Engine
This is Rietveld 408576698