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

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

Issue 11028027: Revert trunk to bleeding_edge at r12484 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 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-visiting.h » ('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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 375
376 376
377 uint32_t StringShape::full_representation_tag() { 377 uint32_t StringShape::full_representation_tag() {
378 return (type_ & (kStringRepresentationMask | kStringEncodingMask)); 378 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
379 } 379 }
380 380
381 381
382 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) == 382 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
383 Internals::kFullStringRepresentationMask); 383 Internals::kFullStringRepresentationMask);
384 384
385 STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
386 Internals::kStringEncodingMask);
387
388 385
389 bool StringShape::IsSequentialAscii() { 386 bool StringShape::IsSequentialAscii() {
390 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag); 387 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
391 } 388 }
392 389
393 390
394 bool StringShape::IsSequentialTwoByte() { 391 bool StringShape::IsSequentialTwoByte() {
395 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag); 392 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
396 } 393 }
397 394
398 395
399 bool StringShape::IsExternalAscii() { 396 bool StringShape::IsExternalAscii() {
400 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag); 397 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
401 } 398 }
402 399
403 400
404 STATIC_CHECK((kExternalStringTag | kAsciiStringTag) ==
405 Internals::kExternalAsciiRepresentationTag);
406
407 STATIC_CHECK(v8::String::ASCII_ENCODING == kAsciiStringTag);
408
409
410 bool StringShape::IsExternalTwoByte() { 401 bool StringShape::IsExternalTwoByte() {
411 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag); 402 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
412 } 403 }
413 404
414 405
415 STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) == 406 STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
416 Internals::kExternalTwoByteRepresentationTag); 407 Internals::kExternalTwoByteRepresentationTag);
417 408
418 STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
419 409
420 uc32 FlatStringReader::Get(int index) { 410 uc32 FlatStringReader::Get(int index) {
421 ASSERT(0 <= index && index <= length_); 411 ASSERT(0 <= index && index <= length_);
422 if (is_ascii_) { 412 if (is_ascii_) {
423 return static_cast<const byte*>(start_)[index]; 413 return static_cast<const byte*>(start_)[index];
424 } else { 414 } else {
425 return static_cast<const uc16*>(start_)[index]; 415 return static_cast<const uc16*>(start_)[index];
426 } 416 }
427 } 417 }
428 418
(...skipping 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 } 1889 }
1900 1890
1901 1891
1902 bool DescriptorArray::IsEmpty() { 1892 bool DescriptorArray::IsEmpty() {
1903 ASSERT(length() >= kFirstIndex || 1893 ASSERT(length() >= kFirstIndex ||
1904 this == HEAP->empty_descriptor_array()); 1894 this == HEAP->empty_descriptor_array());
1905 return length() < kFirstIndex; 1895 return length() < kFirstIndex;
1906 } 1896 }
1907 1897
1908 1898
1909 void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
1910 WRITE_FIELD(
1911 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
1912 }
1913
1914
1915 // Perform a binary search in a fixed array. Low and high are entry indices. If 1899 // Perform a binary search in a fixed array. Low and high are entry indices. If
1916 // there are three entries in this array it should be called with low=0 and 1900 // there are three entries in this array it should be called with low=0 and
1917 // high=2. 1901 // high=2.
1918 template<typename T> 1902 template<typename T>
1919 int BinarySearch(T* array, String* name, int low, int high) { 1903 int BinarySearch(T* array, String* name, int low, int high) {
1920 uint32_t hash = name->Hash(); 1904 uint32_t hash = name->Hash();
1921 int limit = high; 1905 int limit = high;
1922 1906
1923 ASSERT(low <= high); 1907 ASSERT(low <= high);
1924 1908
(...skipping 14 matching lines...) Expand all
1939 String* entry = array->GetKey(sort_index); 1923 String* entry = array->GetKey(sort_index);
1940 if (entry->Hash() != hash) break; 1924 if (entry->Hash() != hash) break;
1941 if (entry->Equals(name)) return sort_index; 1925 if (entry->Equals(name)) return sort_index;
1942 } 1926 }
1943 1927
1944 return T::kNotFound; 1928 return T::kNotFound;
1945 } 1929 }
1946 1930
1947 // Perform a linear search in this fixed array. len is the number of entry 1931 // Perform a linear search in this fixed array. len is the number of entry
1948 // indices that are valid. 1932 // indices that are valid.
1949 template<SearchMode search_mode, typename T> 1933 template<typename T>
1950 int LinearSearch(T* array, String* name, int len, int valid_entries) { 1934 int LinearSearch(T* array, String* name, int len) {
1951 uint32_t hash = name->Hash(); 1935 uint32_t hash = name->Hash();
1952 if (search_mode == ALL_ENTRIES) { 1936 for (int number = 0; number < len; number++) {
1953 for (int number = 0; number < len; number++) { 1937 int sorted_index = array->GetSortedKeyIndex(number);
1954 int sorted_index = array->GetSortedKeyIndex(number); 1938 String* entry = array->GetKey(sorted_index);
1955 String* entry = array->GetKey(sorted_index); 1939 uint32_t current_hash = entry->Hash();
1956 uint32_t current_hash = entry->Hash(); 1940 if (current_hash > hash) break;
1957 if (current_hash > hash) break; 1941 if (current_hash == hash && entry->Equals(name)) return sorted_index;
1958 if (current_hash == hash && entry->Equals(name)) return sorted_index;
1959 }
1960 } else {
1961 ASSERT(len >= valid_entries);
1962 for (int number = 0; number < valid_entries; number++) {
1963 String* entry = array->GetKey(number);
1964 uint32_t current_hash = entry->Hash();
1965 if (current_hash == hash && entry->Equals(name)) return number;
1966 }
1967 } 1942 }
1968 return T::kNotFound; 1943 return T::kNotFound;
1969 } 1944 }
1970 1945
1971 1946
1972 template<SearchMode search_mode, typename T> 1947 template<typename T>
1973 int Search(T* array, String* name, int valid_entries) { 1948 int Search(T* array, String* name) {
1974 if (search_mode == VALID_ENTRIES) { 1949 SLOW_ASSERT(array->IsSortedNoDuplicates());
1975 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
1976 } else {
1977 SLOW_ASSERT(array->IsSortedNoDuplicates());
1978 }
1979 1950
1980 int nof = array->number_of_entries(); 1951 int nof = array->number_of_entries();
1981 if (nof == 0) return T::kNotFound; 1952 if (nof == 0) return T::kNotFound;
1982 1953
1983 // Fast case: do linear search for small arrays. 1954 // Fast case: do linear search for small arrays.
1984 const int kMaxElementsForLinearSearch = 8; 1955 const int kMaxElementsForLinearSearch = 8;
1985 if (search_mode == VALID_ENTRIES || 1956 if (nof < kMaxElementsForLinearSearch) {
1986 (search_mode == ALL_ENTRIES && nof < kMaxElementsForLinearSearch)) { 1957 return LinearSearch(array, name, nof);
1987 return LinearSearch<search_mode>(array, name, nof, valid_entries);
1988 } 1958 }
1989 1959
1990 // Slow case: perform binary search. 1960 // Slow case: perform binary search.
1991 return BinarySearch(array, name, 0, nof - 1); 1961 return BinarySearch(array, name, 0, nof - 1);
1992 } 1962 }
1993 1963
1994 1964
1995 int DescriptorArray::Search(String* name, int valid_descriptors) { 1965 int DescriptorArray::Search(String* name) {
1996 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors); 1966 return internal::Search(this, name);
1997 } 1967 }
1998 1968
1999 1969
2000 int DescriptorArray::SearchWithCache(String* name, Map* map) { 1970 int DescriptorArray::SearchWithCache(String* name) {
2001 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); 1971 if (number_of_descriptors() == 0) return kNotFound;
2002 if (number_of_own_descriptors == 0) return kNotFound;
2003 1972
2004 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache(); 1973 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
2005 int number = cache->Lookup(map, name); 1974 int number = cache->Lookup(this, name);
2006 1975
2007 if (number == DescriptorLookupCache::kAbsent) { 1976 if (number == DescriptorLookupCache::kAbsent) {
2008 number = Search(name, number_of_own_descriptors); 1977 number = Search(name);
2009 cache->Update(map, name, number); 1978 cache->Update(this, name, number);
2010 } 1979 }
2011 1980
2012 return number; 1981 return number;
2013 } 1982 }
2014 1983
2015 1984
2016 void Map::LookupDescriptor(JSObject* holder, 1985 void Map::LookupDescriptor(JSObject* holder,
2017 String* name, 1986 String* name,
2018 LookupResult* result) { 1987 LookupResult* result) {
2019 DescriptorArray* descriptors = this->instance_descriptors(); 1988 DescriptorArray* descriptors = this->instance_descriptors();
2020 int number = descriptors->SearchWithCache(name, this); 1989 int number = descriptors->SearchWithCache(name);
2021 if (number == DescriptorArray::kNotFound) return result->NotFound(); 1990 if (number == DescriptorArray::kNotFound) return result->NotFound();
2022 result->DescriptorResult(holder, descriptors->GetDetails(number), number); 1991 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2023 } 1992 }
2024 1993
2025 1994
2026 void Map::LookupTransition(JSObject* holder, 1995 void Map::LookupTransition(JSObject* holder,
2027 String* name, 1996 String* name,
2028 LookupResult* result) { 1997 LookupResult* result) {
2029 if (HasTransitionArray()) { 1998 if (HasTransitionArray()) {
2030 TransitionArray* transition_array = transitions(); 1999 TransitionArray* transition_array = transitions();
(...skipping 23 matching lines...) Expand all
2054 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { 2023 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2055 return GetDetails(descriptor_number).pointer(); 2024 return GetDetails(descriptor_number).pointer();
2056 } 2025 }
2057 2026
2058 2027
2059 String* DescriptorArray::GetSortedKey(int descriptor_number) { 2028 String* DescriptorArray::GetSortedKey(int descriptor_number) {
2060 return GetKey(GetSortedKeyIndex(descriptor_number)); 2029 return GetKey(GetSortedKeyIndex(descriptor_number));
2061 } 2030 }
2062 2031
2063 2032
2064 void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) { 2033 void DescriptorArray::SetSortedKey(int pointer, int descriptor_number) {
2065 PropertyDetails details = GetDetails(descriptor_index); 2034 int details_index = ToDetailsIndex(pointer);
2066 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi()); 2035 PropertyDetails details = PropertyDetails(Smi::cast(get(details_index)));
2036 set_unchecked(details_index, details.set_pointer(descriptor_number).AsSmi());
2067 } 2037 }
2068 2038
2069 2039
2070 Object** DescriptorArray::GetValueSlot(int descriptor_number) { 2040 Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2071 ASSERT(descriptor_number < number_of_descriptors()); 2041 ASSERT(descriptor_number < number_of_descriptors());
2072 return HeapObject::RawField( 2042 return HeapObject::RawField(
2073 reinterpret_cast<HeapObject*>(this), 2043 reinterpret_cast<HeapObject*>(this),
2074 OffsetOfElementAt(ToValueIndex(descriptor_number))); 2044 OffsetOfElementAt(ToValueIndex(descriptor_number)));
2075 } 2045 }
2076 2046
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 desc->GetKey()); 2107 desc->GetKey());
2138 NoIncrementalWriteBarrierSet(this, 2108 NoIncrementalWriteBarrierSet(this,
2139 ToValueIndex(descriptor_number), 2109 ToValueIndex(descriptor_number),
2140 desc->GetValue()); 2110 desc->GetValue());
2141 NoIncrementalWriteBarrierSet(this, 2111 NoIncrementalWriteBarrierSet(this,
2142 ToDetailsIndex(descriptor_number), 2112 ToDetailsIndex(descriptor_number),
2143 desc->GetDetails().AsSmi()); 2113 desc->GetDetails().AsSmi());
2144 } 2114 }
2145 2115
2146 2116
2147 void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2148 // Range check.
2149 ASSERT(descriptor_number < number_of_descriptors());
2150 ASSERT(desc->GetDetails().descriptor_index() <=
2151 number_of_descriptors());
2152 ASSERT(desc->GetDetails().descriptor_index() > 0);
2153
2154 set(ToKeyIndex(descriptor_number), desc->GetKey());
2155 set(ToValueIndex(descriptor_number), desc->GetValue());
2156 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2157 }
2158
2159
2160 void DescriptorArray::EraseDescriptor(Heap* heap, int descriptor_number) {
2161 set_null_unchecked(heap, ToKeyIndex(descriptor_number));
2162 set_null_unchecked(heap, ToValueIndex(descriptor_number));
2163 }
2164
2165
2166 void DescriptorArray::Append(Descriptor* desc, 2117 void DescriptorArray::Append(Descriptor* desc,
2167 const WhitenessWitness& witness) { 2118 const WhitenessWitness& witness,
2168 int descriptor_number = number_of_descriptors(); 2119 int number_of_set_descriptors) {
2169 int enumeration_index = descriptor_number + 1; 2120 int enumeration_index = number_of_set_descriptors + 1;
2170 SetNumberOfDescriptors(descriptor_number + 1);
2171 desc->SetEnumerationIndex(enumeration_index); 2121 desc->SetEnumerationIndex(enumeration_index);
2172 Set(descriptor_number, desc, witness); 2122 Set(number_of_set_descriptors, desc, witness);
2173 2123
2174 uint32_t hash = desc->GetKey()->Hash(); 2124 uint32_t hash = desc->GetKey()->Hash();
2175 2125
2176 int insertion; 2126 int insertion;
2177 2127
2178 for (insertion = descriptor_number; insertion > 0; --insertion) { 2128 for (insertion = number_of_set_descriptors; insertion > 0; --insertion) {
2179 String* key = GetSortedKey(insertion - 1); 2129 String* key = GetSortedKey(insertion - 1);
2180 if (key->Hash() <= hash) break; 2130 if (key->Hash() <= hash) break;
2181 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); 2131 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2182 } 2132 }
2183 2133
2184 SetSortedKey(insertion, descriptor_number); 2134 SetSortedKey(insertion, number_of_set_descriptors);
2185 } 2135 }
2186 2136
2187 2137
2188 void DescriptorArray::Append(Descriptor* desc) {
2189 int descriptor_number = number_of_descriptors();
2190 int enumeration_index = descriptor_number + 1;
2191 SetNumberOfDescriptors(descriptor_number + 1);
2192 desc->SetEnumerationIndex(enumeration_index);
2193 Set(descriptor_number, desc);
2194
2195 uint32_t hash = desc->GetKey()->Hash();
2196
2197 int insertion;
2198
2199 for (insertion = descriptor_number; insertion > 0; --insertion) {
2200 String* key = GetSortedKey(insertion - 1);
2201 if (key->Hash() <= hash) break;
2202 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2203 }
2204
2205 SetSortedKey(insertion, descriptor_number);
2206 }
2207
2208
2209 void DescriptorArray::SwapSortedKeys(int first, int second) { 2138 void DescriptorArray::SwapSortedKeys(int first, int second) {
2210 int first_key = GetSortedKeyIndex(first); 2139 int first_key = GetSortedKeyIndex(first);
2211 SetSortedKey(first, GetSortedKeyIndex(second)); 2140 SetSortedKey(first, GetSortedKeyIndex(second));
2212 SetSortedKey(second, first_key); 2141 SetSortedKey(second, first_key);
2213 } 2142 }
2214 2143
2215 2144
2216 DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array) 2145 FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
2217 : marking_(array->GetHeap()->incremental_marking()) { 2146 : marking_(array->GetHeap()->incremental_marking()) {
2218 marking_->EnterNoMarkingScope(); 2147 marking_->EnterNoMarkingScope();
2219 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT); 2148 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2220 } 2149 }
2221 2150
2222 2151
2223 DescriptorArray::WhitenessWitness::~WhitenessWitness() { 2152 FixedArray::WhitenessWitness::~WhitenessWitness() {
2224 marking_->LeaveNoMarkingScope(); 2153 marking_->LeaveNoMarkingScope();
2225 } 2154 }
2226 2155
2227 2156
2228 template<typename Shape, typename Key> 2157 template<typename Shape, typename Key>
2229 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) { 2158 int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2230 const int kMinCapacity = 32; 2159 const int kMinCapacity = 32;
2231 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); 2160 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2232 if (capacity < kMinCapacity) { 2161 if (capacity < kMinCapacity) {
2233 capacity = kMinCapacity; // Guarantee min capacity. 2162 capacity = kMinCapacity; // Guarantee min capacity.
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after
3094 JSFunction* Map::unchecked_constructor() { 3023 JSFunction* Map::unchecked_constructor() {
3095 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset)); 3024 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3096 } 3025 }
3097 3026
3098 3027
3099 Code::Flags Code::flags() { 3028 Code::Flags Code::flags() {
3100 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset)); 3029 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3101 } 3030 }
3102 3031
3103 3032
3104 void Map::set_owns_descriptors(bool is_shared) {
3105 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
3106 }
3107
3108
3109 bool Map::owns_descriptors() {
3110 return OwnsDescriptors::decode(bit_field3());
3111 }
3112
3113
3114 void Code::set_flags(Code::Flags flags) { 3033 void Code::set_flags(Code::Flags flags) {
3115 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1); 3034 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
3116 // Make sure that all call stubs have an arguments count. 3035 // Make sure that all call stubs have an arguments count.
3117 ASSERT((ExtractKindFromFlags(flags) != CALL_IC && 3036 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3118 ExtractKindFromFlags(flags) != KEYED_CALL_IC) || 3037 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
3119 ExtractArgumentsCountFromFlags(flags) >= 0); 3038 ExtractArgumentsCountFromFlags(flags) >= 0);
3120 WRITE_INT_FIELD(this, kFlagsOffset, flags); 3039 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3121 } 3040 }
3122 3041
3123 3042
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
3539 } 3458 }
3540 3459
3541 3460
3542 void Map::set_prototype(Object* value, WriteBarrierMode mode) { 3461 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
3543 ASSERT(value->IsNull() || value->IsJSReceiver()); 3462 ASSERT(value->IsNull() || value->IsJSReceiver());
3544 WRITE_FIELD(this, kPrototypeOffset, value); 3463 WRITE_FIELD(this, kPrototypeOffset, value);
3545 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); 3464 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
3546 } 3465 }
3547 3466
3548 3467
3549 JSGlobalPropertyCell* Map::descriptors_pointer() {
3550 ASSERT(HasTransitionArray());
3551 return transitions()->descriptors_pointer();
3552 }
3553
3554
3555 DescriptorArray* Map::instance_descriptors() { 3468 DescriptorArray* Map::instance_descriptors() {
3556 if (HasTransitionArray()) return transitions()->descriptors(); 3469 if (!HasTransitionArray()) return GetHeap()->empty_descriptor_array();
3557 Object* back_pointer = GetBackPointer(); 3470 return transitions()->descriptors();
3558 if (!back_pointer->IsMap()) return GetHeap()->empty_descriptor_array();
3559 return Map::cast(back_pointer)->instance_descriptors();
3560 } 3471 }
3561 3472
3562 3473
3563 enum TransitionsKind { DESCRIPTORS_HOLDER, FULL_TRANSITION_ARRAY };
3564
3565
3566 // If the descriptor is using the empty transition array, install a new empty 3474 // If the descriptor is using the empty transition array, install a new empty
3567 // transition array that will have place for an element transition. 3475 // transition array that will have place for an element transition.
3568 static MaybeObject* EnsureHasTransitionArray(Map* map, TransitionsKind kind) { 3476 static MaybeObject* EnsureHasTransitionArray(Map* map) {
3477 if (map->HasTransitionArray()) return map;
3478
3569 TransitionArray* transitions; 3479 TransitionArray* transitions;
3570 MaybeObject* maybe_transitions; 3480 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3571 if (map->HasTransitionArray()) { 3481 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3572 if (kind != FULL_TRANSITION_ARRAY ||
3573 map->transitions()->IsFullTransitionArray()) {
3574 return map;
3575 }
3576 maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
3577 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3578 } else {
3579 JSGlobalPropertyCell* pointer = map->RetrieveDescriptorsPointer();
3580 if (kind == FULL_TRANSITION_ARRAY) {
3581 maybe_transitions = TransitionArray::Allocate(0, pointer);
3582 } else {
3583 maybe_transitions = TransitionArray::AllocateDescriptorsHolder(pointer);
3584 }
3585 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3586 transitions->set_back_pointer_storage(map->GetBackPointer());
3587 }
3588 map->set_transitions(transitions); 3482 map->set_transitions(transitions);
3589 return transitions; 3483 return transitions;
3590 } 3484 }
3591 3485
3592 3486
3593 MaybeObject* Map::SetDescriptors(DescriptorArray* value) { 3487 MaybeObject* Map::SetDescriptors(DescriptorArray* value,
3488 WriteBarrierMode mode) {
3594 ASSERT(!is_shared()); 3489 ASSERT(!is_shared());
3595 MaybeObject* maybe_failure = 3490 MaybeObject* maybe_failure = EnsureHasTransitionArray(this);
3596 EnsureHasTransitionArray(this, DESCRIPTORS_HOLDER);
3597 if (maybe_failure->IsFailure()) return maybe_failure; 3491 if (maybe_failure->IsFailure()) return maybe_failure;
3598 3492
3599 ASSERT(NumberOfOwnDescriptors() <= value->number_of_descriptors()); 3493 transitions()->set_descriptors(value, mode);
3600 transitions()->set_descriptors(value);
3601 return this; 3494 return this;
3602 } 3495 }
3603 3496
3604 3497
3605 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) { 3498 MaybeObject* Map::InitializeDescriptors(DescriptorArray* descriptors) {
3499 #ifdef DEBUG
3606 int len = descriptors->number_of_descriptors(); 3500 int len = descriptors->number_of_descriptors();
3607 #ifdef DEBUG
3608 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors); 3501 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
3502 SLOW_ASSERT(descriptors->IsSortedNoDuplicates());
3609 3503
3610 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors]; 3504 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
3611 for (int i = 0; i < len; ++i) used_indices[i] = false; 3505 for (int i = 0; i < len; ++i) used_indices[i] = false;
3612 3506
3613 // Ensure that all enumeration indexes between 1 and length occur uniquely in 3507 // Ensure that all enumeration indexes between 1 and length occur uniquely in
3614 // the descriptor array. 3508 // the descriptor array.
3615 for (int i = 0; i < len; ++i) { 3509 for (int i = 0; i < len; ++i) {
3616 int enum_index = descriptors->GetDetails(i).descriptor_index() - 3510 int enum_index = descriptors->GetDetails(i).descriptor_index() -
3617 PropertyDetails::kInitialIndex; 3511 PropertyDetails::kInitialIndex;
3618 ASSERT(0 <= enum_index && enum_index < len); 3512 ASSERT(0 <= enum_index && enum_index < len);
3619 ASSERT(!used_indices[enum_index]); 3513 ASSERT(!used_indices[enum_index]);
3620 used_indices[enum_index] = true; 3514 used_indices[enum_index] = true;
3621 } 3515 }
3622 #endif 3516 #endif
3623 3517
3624 MaybeObject* maybe_failure = SetDescriptors(descriptors); 3518 MaybeObject* maybe_failure = SetDescriptors(descriptors);
3625 if (maybe_failure->IsFailure()) return maybe_failure; 3519 if (maybe_failure->IsFailure()) return maybe_failure;
3626 3520
3627 SetNumberOfOwnDescriptors(len); 3521 SetNumberOfOwnDescriptors(descriptors->number_of_descriptors());
3522
3628 return this; 3523 return this;
3629 } 3524 }
3630 3525
3631 3526
3632 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset) 3527 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
3633 3528
3634 3529
3635 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { 3530 void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
3636 Object* back_pointer = GetBackPointer(); 3531 Object* back_pointer = GetBackPointer();
3637 #ifdef DEBUG 3532 #ifdef DEBUG
3638 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 3533 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
3639 if (object->IsTransitionArray()) { 3534 if (object->IsTransitionArray()) {
3640 ZapTransitions(); 3535 ZapTransitions();
3641 } else { 3536 } else {
3642 ASSERT(object->IsMap() || object->IsUndefined()); 3537 ASSERT(object->IsMap() || object->IsUndefined());
3643 } 3538 }
3644 #endif 3539 #endif
3645 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer); 3540 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
3646 CONDITIONAL_WRITE_BARRIER( 3541 CONDITIONAL_WRITE_BARRIER(
3647 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode); 3542 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
3648 } 3543 }
3649 3544
3650 3545
3651 void Map::AppendDescriptor(Descriptor* desc, 3546 void Map::AppendDescriptor(Descriptor* desc,
3652 const DescriptorArray::WhitenessWitness& witness) { 3547 const DescriptorArray::WhitenessWitness& witness) {
3653 DescriptorArray* descriptors = instance_descriptors(); 3548 DescriptorArray* descriptors = instance_descriptors();
3654 int number_of_own_descriptors = NumberOfOwnDescriptors(); 3549 int number_of_own_descriptors = NumberOfOwnDescriptors();
3655 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); 3550 ASSERT(number_of_own_descriptors < descriptors->number_of_descriptors());
3656 descriptors->Append(desc, witness); 3551 descriptors->Append(desc, witness, number_of_own_descriptors);
3657 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); 3552 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
3658 } 3553 }
3659 3554
3660 3555
3661 Object* Map::GetBackPointer() { 3556 Object* Map::GetBackPointer() {
3662 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 3557 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
3663 if (object->IsDescriptorArray()) { 3558 if (object->IsDescriptorArray()) {
3664 return TransitionArray::cast(object)->back_pointer_storage(); 3559 return TransitionArray::cast(object)->back_pointer_storage();
3665 } else { 3560 } else {
3666 ASSERT(object->IsMap() || object->IsUndefined()); 3561 ASSERT(object->IsMap() || object->IsUndefined());
(...skipping 19 matching lines...) Expand all
3686 3581
3687 3582
3688 bool Map::CanHaveMoreTransitions() { 3583 bool Map::CanHaveMoreTransitions() {
3689 if (!HasTransitionArray()) return true; 3584 if (!HasTransitionArray()) return true;
3690 return FixedArray::SizeFor(transitions()->length() + 3585 return FixedArray::SizeFor(transitions()->length() +
3691 TransitionArray::kTransitionSize) 3586 TransitionArray::kTransitionSize)
3692 <= Page::kMaxNonCodeHeapObjectSize; 3587 <= Page::kMaxNonCodeHeapObjectSize;
3693 } 3588 }
3694 3589
3695 3590
3696 JSGlobalPropertyCell* Map::RetrieveDescriptorsPointer() { 3591 MaybeObject* Map::AddTransition(String* key, Map* target) {
3697 if (!owns_descriptors()) return NULL; 3592 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
3698 Object* back_pointer = GetBackPointer(); 3593 return TransitionArray::NewWith(key, target);
3699 if (back_pointer->IsUndefined()) return NULL;
3700 Map* map = Map::cast(back_pointer);
3701 ASSERT(map->HasTransitionArray());
3702 return map->transitions()->descriptors_pointer();
3703 } 3594 }
3704 3595
3705 3596
3706 MaybeObject* Map::AddTransition(String* key,
3707 Map* target,
3708 SimpleTransitionFlag flag) {
3709 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
3710 JSGlobalPropertyCell* descriptors_pointer = RetrieveDescriptorsPointer();
3711 return TransitionArray::NewWith(
3712 flag, key, target, descriptors_pointer, GetBackPointer());
3713 }
3714
3715
3716 void Map::SetTransition(int transition_index, Map* target) { 3597 void Map::SetTransition(int transition_index, Map* target) {
3717 transitions()->SetTarget(transition_index, target); 3598 transitions()->SetTarget(transition_index, target);
3718 } 3599 }
3719 3600
3720 3601
3721 Map* Map::GetTransition(int transition_index) {
3722 return transitions()->GetTarget(transition_index);
3723 }
3724
3725
3726 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) { 3602 MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
3727 MaybeObject* allow_elements = 3603 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
3728 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY);
3729 if (allow_elements->IsFailure()) return allow_elements; 3604 if (allow_elements->IsFailure()) return allow_elements;
3730 transitions()->set_elements_transition(transitioned_map); 3605 transitions()->set_elements_transition(transitioned_map);
3731 return this; 3606 return this;
3732 } 3607 }
3733 3608
3734 3609
3735 FixedArray* Map::GetPrototypeTransitions() { 3610 FixedArray* Map::GetPrototypeTransitions() {
3736 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); 3611 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3737 if (!transitions()->HasPrototypeTransitions()) { 3612 if (!transitions()->HasPrototypeTransitions()) {
3738 return GetHeap()->empty_fixed_array(); 3613 return GetHeap()->empty_fixed_array();
3739 } 3614 }
3740 return transitions()->GetPrototypeTransitions(); 3615 return transitions()->GetPrototypeTransitions();
3741 } 3616 }
3742 3617
3743 3618
3744 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { 3619 MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3745 MaybeObject* allow_prototype = 3620 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3746 EnsureHasTransitionArray(this, FULL_TRANSITION_ARRAY);
3747 if (allow_prototype->IsFailure()) return allow_prototype; 3621 if (allow_prototype->IsFailure()) return allow_prototype;
3748 #ifdef DEBUG 3622 #ifdef DEBUG
3749 if (HasPrototypeTransitions()) { 3623 if (HasPrototypeTransitions()) {
3750 ASSERT(GetPrototypeTransitions() != proto_transitions); 3624 ASSERT(GetPrototypeTransitions() != proto_transitions);
3751 ZapPrototypeTransitions(); 3625 ZapPrototypeTransitions();
3752 } 3626 }
3753 #endif 3627 #endif
3754 transitions()->SetPrototypeTransitions(proto_transitions); 3628 transitions()->SetPrototypeTransitions(proto_transitions);
3755 return this; 3629 return this;
3756 } 3630 }
3757 3631
3758 3632
3759 bool Map::HasPrototypeTransitions() { 3633 bool Map::HasPrototypeTransitions() {
3760 return HasTransitionArray() && transitions()->HasPrototypeTransitions(); 3634 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3761 } 3635 }
3762 3636
3763 3637
3764 TransitionArray* Map::transitions() { 3638 TransitionArray* Map::transitions() {
3765 ASSERT(HasTransitionArray()); 3639 ASSERT(HasTransitionArray());
3766 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); 3640 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
3767 return TransitionArray::cast(object); 3641 return TransitionArray::cast(object);
3768 } 3642 }
3769 3643
3770 3644
3771 void Map::set_transitions(TransitionArray* transition_array, 3645 void Map::set_transitions(TransitionArray* transition_array,
3772 WriteBarrierMode mode) { 3646 WriteBarrierMode mode) {
3647 transition_array->set_descriptors(instance_descriptors());
3648 transition_array->set_back_pointer_storage(GetBackPointer());
3773 #ifdef DEBUG 3649 #ifdef DEBUG
3774 if (HasTransitionArray()) { 3650 if (HasTransitionArray()) {
3775 ASSERT(transitions() != transition_array); 3651 ASSERT(transitions() != transition_array);
3776 ZapTransitions(); 3652 ZapTransitions();
3777 } 3653 }
3778 #endif 3654 #endif
3779 3655
3780 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); 3656 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
3781 CONDITIONAL_WRITE_BARRIER( 3657 CONDITIONAL_WRITE_BARRIER(
3782 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); 3658 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
4942 // Slow case: compute hash code and set it. 4818 // Slow case: compute hash code and set it.
4943 return ComputeAndSetHash(); 4819 return ComputeAndSetHash();
4944 } 4820 }
4945 4821
4946 4822
4947 StringHasher::StringHasher(int length, uint32_t seed) 4823 StringHasher::StringHasher(int length, uint32_t seed)
4948 : length_(length), 4824 : length_(length),
4949 raw_running_hash_(seed), 4825 raw_running_hash_(seed),
4950 array_index_(0), 4826 array_index_(0),
4951 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), 4827 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4952 is_first_char_(true) { 4828 is_first_char_(true),
4829 is_valid_(true) {
4953 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0); 4830 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
4954 } 4831 }
4955 4832
4956 4833
4957 bool StringHasher::has_trivial_hash() { 4834 bool StringHasher::has_trivial_hash() {
4958 return length_ > String::kMaxHashCalcLength; 4835 return length_ > String::kMaxHashCalcLength;
4959 } 4836 }
4960 4837
4961 4838
4962 uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint32_t c) {
4963 running_hash += c;
4964 running_hash += (running_hash << 10);
4965 running_hash ^= (running_hash >> 6);
4966 return running_hash;
4967 }
4968
4969
4970 uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
4971 running_hash += (running_hash << 3);
4972 running_hash ^= (running_hash >> 11);
4973 running_hash += (running_hash << 15);
4974 if ((running_hash & String::kHashBitMask) == 0) {
4975 return 27;
4976 }
4977 return running_hash;
4978 }
4979
4980
4981 void StringHasher::AddCharacter(uint32_t c) { 4839 void StringHasher::AddCharacter(uint32_t c) {
4982 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { 4840 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4983 AddSurrogatePair(c); // Not inlined. 4841 AddSurrogatePair(c); // Not inlined.
4984 return; 4842 return;
4985 } 4843 }
4986 // Use the Jenkins one-at-a-time hash function to update the hash 4844 // Use the Jenkins one-at-a-time hash function to update the hash
4987 // for the given character. 4845 // for the given character.
4988 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c); 4846 raw_running_hash_ += c;
4847 raw_running_hash_ += (raw_running_hash_ << 10);
4848 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4989 // Incremental array index computation. 4849 // Incremental array index computation.
4990 if (is_array_index_) { 4850 if (is_array_index_) {
4991 if (c < '0' || c > '9') { 4851 if (c < '0' || c > '9') {
4992 is_array_index_ = false; 4852 is_array_index_ = false;
4993 } else { 4853 } else {
4994 int d = c - '0'; 4854 int d = c - '0';
4995 if (is_first_char_) { 4855 if (is_first_char_) {
4996 is_first_char_ = false; 4856 is_first_char_ = false;
4997 if (c == '0' && length_ > 1) { 4857 if (c == '0' && length_ > 1) {
4998 is_array_index_ = false; 4858 is_array_index_ = false;
4999 return; 4859 return;
5000 } 4860 }
5001 } 4861 }
5002 if (array_index_ > 429496729U - ((d + 2) >> 3)) { 4862 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
5003 is_array_index_ = false; 4863 is_array_index_ = false;
5004 } else { 4864 } else {
5005 array_index_ = array_index_ * 10 + d; 4865 array_index_ = array_index_ * 10 + d;
5006 } 4866 }
5007 } 4867 }
5008 } 4868 }
5009 } 4869 }
5010 4870
5011 4871
5012 void StringHasher::AddCharacterNoIndex(uint32_t c) { 4872 void StringHasher::AddCharacterNoIndex(uint32_t c) {
5013 ASSERT(!is_array_index()); 4873 ASSERT(!is_array_index());
5014 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) { 4874 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
5015 AddSurrogatePairNoIndex(c); // Not inlined. 4875 AddSurrogatePairNoIndex(c); // Not inlined.
5016 return; 4876 return;
5017 } 4877 }
5018 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c); 4878 raw_running_hash_ += c;
4879 raw_running_hash_ += (raw_running_hash_ << 10);
4880 raw_running_hash_ ^= (raw_running_hash_ >> 6);
5019 } 4881 }
5020 4882
5021 4883
5022 uint32_t StringHasher::GetHash() { 4884 uint32_t StringHasher::GetHash() {
5023 // Get the calculated raw hash value and do some more bit ops to distribute 4885 // Get the calculated raw hash value and do some more bit ops to distribute
5024 // the hash further. Ensure that we never return zero as the hash value. 4886 // the hash further. Ensure that we never return zero as the hash value.
5025 return GetHashCore(raw_running_hash_); 4887 uint32_t result = raw_running_hash_;
4888 result += (result << 3);
4889 result ^= (result >> 11);
4890 result += (result << 15);
4891 if ((result & String::kHashBitMask) == 0) {
4892 result = 27;
4893 }
4894 return result;
5026 } 4895 }
5027 4896
5028 4897
5029 template <typename schar> 4898 template <typename schar>
5030 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) { 4899 uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
5031 StringHasher hasher(length, seed); 4900 StringHasher hasher(length, seed);
5032 if (!hasher.has_trivial_hash()) { 4901 if (!hasher.has_trivial_hash()) {
5033 int i; 4902 int i;
5034 for (i = 0; hasher.is_array_index() && (i < length); i++) { 4903 for (i = 0; hasher.is_array_index() && (i < length); i++) {
5035 hasher.AddCharacter(chars[i]); 4904 hasher.AddCharacter(chars[i]);
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
5557 #undef WRITE_UINT32_FIELD 5426 #undef WRITE_UINT32_FIELD
5558 #undef READ_SHORT_FIELD 5427 #undef READ_SHORT_FIELD
5559 #undef WRITE_SHORT_FIELD 5428 #undef WRITE_SHORT_FIELD
5560 #undef READ_BYTE_FIELD 5429 #undef READ_BYTE_FIELD
5561 #undef WRITE_BYTE_FIELD 5430 #undef WRITE_BYTE_FIELD
5562 5431
5563 5432
5564 } } // namespace v8::internal 5433 } } // namespace v8::internal
5565 5434
5566 #endif // V8_OBJECTS_INL_H_ 5435 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-visiting.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698