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

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: 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"
Jakob Kummerow 2012/06/29 16:31:36 As an exception from not relying on indirect #incl
Toon Verwaest 2012/07/05 12:56:11 Done.
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
Jakob Kummerow 2012/06/29 16:31:36 nit: missing space after '.'.
Toon Verwaest 2012/07/05 12:56:11 Done.
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());
Jakob Kummerow 2012/06/29 16:31:36 Please either (fix and) enable this or remove it.
Toon Verwaest 2012/07/05 12:56:11 Done.
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;
Michael Starzinger 2012/06/28 16:02:12 Somehow it feels wrong to return NULL here. Either
Toon Verwaest 2012/06/29 08:14:55 Done.
1938 return NULL; 2002 Object* array = get(kTransitionsIndex);
1939 } 2003 if (array->IsSmi()) return NULL;
1940 Object* transition_map = get(kTransitionsIndex); 2004 return TransitionArray::cast(array);
1941 if (transition_map == Smi::FromInt(0)) {
1942 return NULL;
1943 } else {
1944 return Map::cast(transition_map);
1945 }
1946 } 2005 }
1947 2006
1948 2007
1949 void DescriptorArray::set_elements_transition_map( 2008 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)); 2009 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0));
1962 } 2010 }
1963 2011
1964 2012
2013 void DescriptorArray::set_transitions(
Jakob Kummerow 2012/06/29 16:31:36 nit: for declarations, each argument on its own li
Toon Verwaest 2012/07/05 12:56:11 Done.
2014 TransitionArray* transitions_array, WriteBarrierMode mode) {
2015 Heap* heap = GetHeap();
2016 WRITE_FIELD(this, kTransitionsOffset, transitions_array);
2017 CONDITIONAL_WRITE_BARRIER(
2018 heap, this, kTransitionsOffset, transitions_array, mode);
2019 }
2020
2021
1965 Object** DescriptorArray::GetKeySlot(int descriptor_number) { 2022 Object** DescriptorArray::GetKeySlot(int descriptor_number) {
1966 ASSERT(descriptor_number < number_of_descriptors()); 2023 ASSERT(descriptor_number < number_of_descriptors());
1967 return HeapObject::RawField( 2024 return HeapObject::RawField(
1968 reinterpret_cast<HeapObject*>(this), 2025 reinterpret_cast<HeapObject*>(this),
1969 OffsetOfElementAt(ToKeyIndex(descriptor_number))); 2026 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
1970 } 2027 }
1971 2028
1972 2029
1973 String* DescriptorArray::GetKey(int descriptor_number) { 2030 String* DescriptorArray::GetKey(int descriptor_number) {
1974 ASSERT(descriptor_number < number_of_descriptors()); 2031 ASSERT(descriptor_number < number_of_descriptors());
1975 return String::cast(get(ToKeyIndex(descriptor_number))); 2032 return String::cast(get(ToKeyIndex(descriptor_number)));
1976 } 2033 }
1977 2034
1978 2035
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) { 2036 Object** DescriptorArray::GetValueSlot(int descriptor_number) {
1991 ASSERT(descriptor_number < number_of_descriptors()); 2037 ASSERT(descriptor_number < number_of_descriptors());
1992 return HeapObject::RawField( 2038 return HeapObject::RawField(
1993 reinterpret_cast<HeapObject*>(this), 2039 reinterpret_cast<HeapObject*>(this),
1994 OffsetOfElementAt(ToValueIndex(descriptor_number))); 2040 OffsetOfElementAt(ToValueIndex(descriptor_number)));
1995 } 2041 }
1996 2042
1997 2043
1998 Object* DescriptorArray::GetValue(int descriptor_number) { 2044 Object* DescriptorArray::GetValue(int descriptor_number) {
1999 ASSERT(descriptor_number < number_of_descriptors()); 2045 ASSERT(descriptor_number < number_of_descriptors());
2000 return get(ToValueIndex(descriptor_number)); 2046 return get(ToValueIndex(descriptor_number));
2001 } 2047 }
2002 2048
2003 2049
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) { 2050 PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
2023 ASSERT(descriptor_number < number_of_descriptors()); 2051 ASSERT(descriptor_number < number_of_descriptors());
2024 Object* details = get(ToDetailsIndex(descriptor_number)); 2052 Object* details = get(ToDetailsIndex(descriptor_number));
2025 return PropertyDetails(Smi::cast(details)); 2053 return PropertyDetails(Smi::cast(details));
2026 } 2054 }
2027 2055
2028 2056
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) { 2057 PropertyType DescriptorArray::GetType(int descriptor_number) {
2036 return GetDetails(descriptor_number).type(); 2058 return GetDetails(descriptor_number).type();
2037 } 2059 }
2038 2060
2039 2061
2040 int DescriptorArray::GetFieldIndex(int descriptor_number) { 2062 int DescriptorArray::GetFieldIndex(int descriptor_number) {
2041 return Descriptor::IndexFromValue(GetValue(descriptor_number)); 2063 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2042 } 2064 }
2043 2065
2044 2066
2045 JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) { 2067 JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2046 return JSFunction::cast(GetValue(descriptor_number)); 2068 return JSFunction::cast(GetValue(descriptor_number));
2047 } 2069 }
2048 2070
2049 2071
2050 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) { 2072 Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2051 ASSERT(GetType(descriptor_number) == CALLBACKS); 2073 ASSERT(GetType(descriptor_number) == CALLBACKS);
2052 return GetValue(descriptor_number); 2074 return GetValue(descriptor_number);
2053 } 2075 }
2054 2076
2055 2077
2056 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) { 2078 AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2057 ASSERT(GetType(descriptor_number) == CALLBACKS); 2079 ASSERT(GetType(descriptor_number) == CALLBACKS);
2058 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number)); 2080 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
2059 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address()); 2081 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
2060 } 2082 }
2061 2083
2062 2084
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) { 2085 void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2096 desc->Init(GetKey(descriptor_number), 2086 desc->Init(GetKey(descriptor_number),
2097 GetValue(descriptor_number), 2087 GetValue(descriptor_number),
2098 GetDetails(descriptor_number)); 2088 GetDetails(descriptor_number));
2099 } 2089 }
2100 2090
2101 2091
2102 void DescriptorArray::Set(int descriptor_number, 2092 void DescriptorArray::Set(int descriptor_number,
2103 Descriptor* desc, 2093 Descriptor* desc,
2104 const WhitenessWitness&) { 2094 const WhitenessWitness&) {
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3424 } 3414 }
3425 } 3415 }
3426 3416
3427 3417
3428 void Map::init_instance_descriptors() { 3418 void Map::init_instance_descriptors() {
3429 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0)); 3419 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3430 } 3420 }
3431 3421
3432 3422
3433 void Map::clear_instance_descriptors() { 3423 void Map::clear_instance_descriptors() {
3434 Object* object = READ_FIELD(this, 3424 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3435 kInstanceDescriptorsOrBitField3Offset);
3436 if (!object->IsSmi()) { 3425 if (!object->IsSmi()) {
3437 #ifdef DEBUG
3438 ZapInstanceDescriptors();
3439 #endif
3440 WRITE_FIELD( 3426 WRITE_FIELD(
3441 this, 3427 this,
3442 kInstanceDescriptorsOrBitField3Offset, 3428 kInstanceDescriptorsOrBitField3Offset,
3443 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage())); 3429 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3444 } 3430 }
3445 } 3431 }
3446 3432
3447 3433
3448 void Map::set_instance_descriptors(DescriptorArray* value, 3434 void Map::set_instance_descriptors(DescriptorArray* value,
3449 WriteBarrierMode mode) { 3435 WriteBarrierMode mode) {
3450 Object* object = READ_FIELD(this, 3436 Object* object = READ_FIELD(this,
3451 kInstanceDescriptorsOrBitField3Offset); 3437 kInstanceDescriptorsOrBitField3Offset);
3452 Heap* heap = GetHeap(); 3438 Heap* heap = GetHeap();
3453 if (value == heap->empty_descriptor_array()) { 3439 if (value == heap->empty_descriptor_array()) {
3454 clear_instance_descriptors(); 3440 clear_instance_descriptors();
3455 return; 3441 return;
3456 } else { 3442 } else {
3457 if (object->IsSmi()) { 3443 if (object->IsSmi()) {
3458 value->set_bit_field3_storage(Smi::cast(object)->value()); 3444 value->set_bit_field3_storage(Smi::cast(object)->value());
3459 } else { 3445 } else {
3460 value->set_bit_field3_storage( 3446 value->set_bit_field3_storage(
3461 DescriptorArray::cast(object)->bit_field3_storage()); 3447 DescriptorArray::cast(object)->bit_field3_storage());
3462 } 3448 }
3463 } 3449 }
3464 ASSERT(!is_shared()); 3450 ASSERT(!is_shared());
3465 #ifdef DEBUG
3466 if (value != instance_descriptors()) {
3467 ZapInstanceDescriptors();
3468 }
3469 #endif
3470 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); 3451 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3471 CONDITIONAL_WRITE_BARRIER( 3452 CONDITIONAL_WRITE_BARRIER(
3472 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode); 3453 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
3473 } 3454 }
3474 3455
3475 3456
3476 int Map::bit_field3() { 3457 int Map::bit_field3() {
3477 Object* object = READ_FIELD(this, 3458 Object* object = READ_FIELD(this,
3478 kInstanceDescriptorsOrBitField3Offset); 3459 kInstanceDescriptorsOrBitField3Offset);
3479 if (object->IsSmi()) { 3460 if (object->IsSmi()) {
3480 return Smi::cast(object)->value(); 3461 return Smi::cast(object)->value();
3481 } else { 3462 } else {
3482 return DescriptorArray::cast(object)->bit_field3_storage(); 3463 return DescriptorArray::cast(object)->bit_field3_storage();
3483 } 3464 }
3484 } 3465 }
3485 3466
3486 3467
3487 void Map::ClearDescriptorArray() { 3468 void Map::ClearDescriptorArray() {
3488 int bitfield3 = bit_field3(); 3469 int bitfield3 = bit_field3();
3489 #ifdef DEBUG 3470 #ifdef DEBUG
3490 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); 3471 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3491 if (!object->IsSmi()) { 3472 if (!object->IsSmi()) {
3492 ZapInstanceDescriptors(); 3473 ZapTransitions();
3493 } 3474 }
3494 #endif 3475 #endif
3495 WRITE_FIELD(this, 3476 WRITE_FIELD(this,
3496 kInstanceDescriptorsOrBitField3Offset, 3477 kInstanceDescriptorsOrBitField3Offset,
3497 Smi::FromInt(bitfield3)); 3478 Smi::FromInt(bitfield3));
3498 } 3479 }
3499 3480
3500 3481
3501 void Map::set_bit_field3(int value) { 3482 void Map::set_bit_field3(int value) {
3502 ASSERT(Smi::IsValid(value)); 3483 ASSERT(Smi::IsValid(value));
(...skipping 11 matching lines...) Expand all
3514 Object* Map::GetBackPointer() { 3495 Object* Map::GetBackPointer() {
3515 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); 3496 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3516 if (object->IsFixedArray()) { 3497 if (object->IsFixedArray()) {
3517 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset); 3498 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3518 } else { 3499 } else {
3519 return object; 3500 return object;
3520 } 3501 }
3521 } 3502 }
3522 3503
3523 3504
3505 bool Map::HasElementsTransition() {
3506 return HasTransitionArray() && transitions()->HasElementsTransition();
3507 }
3508
3509
3510 bool Map::HasTransitionArray() {
3511 return instance_descriptors()->HasTransitionArray();
3512 }
3513
3514
3524 Map* Map::elements_transition_map() { 3515 Map* Map::elements_transition_map() {
3525 return instance_descriptors()->elements_transition_map(); 3516 return transitions()->elements();
3526 } 3517 }
3527 3518
3528 3519
3529 void Map::set_elements_transition_map(Map* transitioned_map) { 3520 // If the descriptor is using the empty transition array, install a new empty
3530 return instance_descriptors()->set_elements_transition_map(transitioned_map); 3521 // transition array that will have place for an element transition.
Jakob Kummerow 2012/06/29 16:31:36 nit: // If the descriptor array does not have a t
Toon Verwaest 2012/07/05 12:56:11 Done.
3522 static MaybeObject* AllowElementsTransition(Map* map) {
3523 if (map->HasTransitionArray()) return map;
3524
3525 TransitionArray* transitions;
3526 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3527 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3528 MaybeObject* added_transitions = map->set_transitions(transitions);
3529 if (added_transitions->IsFailure()) return added_transitions;
3530 return transitions;
3531 } 3531 }
3532 3532
3533 3533
3534 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
3535 MaybeObject* allow_elements = AllowElementsTransition(this);
3536 if (allow_elements->IsFailure()) return allow_elements;
3537 transitions()->set_elements(transitioned_map);
3538 return this;
3539 }
3540
3541
3542 TransitionArray* Map::transitions() {
3543 return instance_descriptors()->transitions();
3544 }
3545
3546
3547 // If the map is using the empty descriptor array, install a new empty
Jakob Kummerow 2012/06/29 16:31:36 This comment is confusing. Maybe something like "I
Toon Verwaest 2012/07/05 12:56:11 Done.
3548 // descriptor array that will contain an element transition.
3549 static MaybeObject* AllowTransitions(Map* map) {
3550 if (map->instance_descriptors()->MayContainTransitions()) return map;
3551 DescriptorArray* descriptors;
3552 MaybeObject* maybe_descriptors =
3553 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3554 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3555 map->set_instance_descriptors(descriptors);
3556 return descriptors;
3557 }
3558
3559
3560 void Map::ClearTransitions() {
3561 #ifdef DEBUG
3562 ZapTransitions();
3563 #endif
3564 DescriptorArray* descriptors = instance_descriptors();
3565 if (descriptors->number_of_descriptors() == 0) {
3566 ClearDescriptorArray();
3567 } else {
3568 descriptors->ClearTransitions();
3569 }
3570 }
3571
3572
3573 MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3574 MaybeObject* allow_transitions = AllowTransitions(this);
3575 if (allow_transitions->IsFailure()) return allow_transitions;
3576 #ifdef DEBUG
3577 if (transitions_array == transitions()) {
Jakob Kummerow 2012/06/29 16:31:36 You can just do ASSERT(transitions_array != transi
Toon Verwaest 2012/07/05 12:56:11 Done.
3578 UNREACHABLE();
3579 }
3580 ZapTransitions();
3581 #endif
3582 instance_descriptors()->set_transitions(transitions_array);
3583 return this;
3584 }
3585
3586
3534 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { 3587 void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3535 Heap* heap = GetHeap(); 3588 Heap* heap = GetHeap();
3536 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); 3589 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3537 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || 3590 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3538 (value->IsMap() && GetBackPointer()->IsUndefined())); 3591 (value->IsMap() && GetBackPointer()->IsUndefined()));
3539 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); 3592 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3540 if (object->IsFixedArray()) { 3593 if (object->IsFixedArray()) {
3541 FixedArray::cast(object)->set( 3594 FixedArray::cast(object)->set(
3542 kProtoTransitionBackPointerOffset, value, mode); 3595 kProtoTransitionBackPointerOffset, value, mode);
3543 } else { 3596 } else {
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after
5218 #undef WRITE_UINT32_FIELD 5271 #undef WRITE_UINT32_FIELD
5219 #undef READ_SHORT_FIELD 5272 #undef READ_SHORT_FIELD
5220 #undef WRITE_SHORT_FIELD 5273 #undef WRITE_SHORT_FIELD
5221 #undef READ_BYTE_FIELD 5274 #undef READ_BYTE_FIELD
5222 #undef WRITE_BYTE_FIELD 5275 #undef WRITE_BYTE_FIELD
5223 5276
5224 5277
5225 } } // namespace v8::internal 5278 } } // namespace v8::internal
5226 5279
5227 #endif // V8_OBJECTS_INL_H_ 5280 #endif // V8_OBJECTS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698