OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 2096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2107 if (HasLocalElement(index)) return NONE; | 2107 if (HasLocalElement(index)) return NONE; |
2108 return ABSENT; | 2108 return ABSENT; |
2109 } | 2109 } |
2110 // Named property. | 2110 // Named property. |
2111 LookupResult result; | 2111 LookupResult result; |
2112 LocalLookup(name, &result); | 2112 LocalLookup(name, &result); |
2113 return GetPropertyAttribute(this, &result, name, false); | 2113 return GetPropertyAttribute(this, &result, name, false); |
2114 } | 2114 } |
2115 | 2115 |
2116 | 2116 |
2117 class NormalizedMapCache { | |
Mads Ager (chromium)
2010/07/23 09:07:32
: public AllStatic ?
Also, please have public: se
| |
2118 static bool IsMatchFor(Map* slow, Map* fast, PropertyNormalizationMode mode); | |
2119 | |
2120 public: | |
2121 static int Hash(Map* fast, PropertyNormalizationMode mode); | |
2122 | |
2123 static Object* Get(Map* fast, int hash, PropertyNormalizationMode mode); | |
2124 | |
2125 static void Set(int hash, Map* slow); | |
2126 }; | |
2127 | |
2128 | |
2129 int NormalizedMapCache::Hash(Map* fast, PropertyNormalizationMode mode) { | |
2130 // XOR bytes in every fields that will be copied to the normalized fast_map. | |
2131 // Ignoring: | |
2132 // instance_size (determined by instance_type and inobject_properties) | |
2133 // scavenger (determined by instance_type and instance_size) | |
2134 // pre_allocated_property_fields (always 0) | |
2135 // unused_property_fields (always 0) | |
2136 // code_cache (always empty) | |
2137 // instance_descriptors (always empty) | |
2138 | |
2139 int index = | |
2140 (static_cast<uint32_t>( | |
2141 reinterpret_cast<uintptr_t>(fast->constructor())) >> 2) ^ | |
2142 (static_cast<uint32_t>( | |
2143 reinterpret_cast<uintptr_t>(fast->prototype())) >> 2); | |
2144 | |
2145 index ^= (index >> 16); | |
2146 index ^= (index >> 8); | |
2147 | |
2148 index ^= | |
2149 ((mode == CLEAR_INOBJECT_PROPERTIES) ? 0 : fast->inobject_properties()); | |
2150 index ^= fast->instance_type(); | |
2151 index ^= fast->bit_field(); | |
2152 index ^= fast->bit_field2(); | |
2153 | |
2154 return index & 0xFF; | |
Mads Ager (chromium)
2010/07/23 09:07:32
Why do you return only 8 bits?
| |
2155 } | |
2156 | |
2157 | |
2158 bool NormalizedMapCache::IsMatchFor(Map* slow, | |
2159 Map* fast, | |
2160 PropertyNormalizationMode mode) { | |
2161 ASSERT(slow->pre_allocated_property_fields() == 0); | |
2162 ASSERT(slow->unused_property_fields() == 0); | |
2163 | |
2164 return | |
2165 slow->constructor() == fast->constructor() && | |
2166 slow->prototype() == fast->prototype() && | |
2167 slow->inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ? | |
2168 0 : | |
2169 fast->inobject_properties()) && | |
2170 slow->instance_type() == fast->instance_type() && | |
2171 slow->bit_field() == fast->bit_field() && | |
2172 slow->bit_field2() == fast->bit_field2(); | |
2173 } | |
2174 | |
2175 | |
2176 Object* NormalizedMapCache::Get(Map* fast, | |
2177 int hash, | |
2178 PropertyNormalizationMode mode) { | |
2179 Object* cached = Top::slow_map_cache()->get(hash); | |
2180 if (!cached->IsMap()) return cached; // Cache miss. | |
2181 | |
2182 Map* slow = Map::cast(cached); | |
2183 if (IsMatchFor(slow, fast, mode)) return cached; // Found the right map. | |
2184 | |
2185 // Hash collision. Pretend there was a miss, the entry will be overwritten. | |
2186 return Heap::undefined_value(); | |
2187 } | |
2188 | |
2189 | |
2190 void NormalizedMapCache::Set(int hash, Map* map) { | |
2191 Top::slow_map_cache()->set(hash, map); | |
2192 } | |
2193 | |
2194 | |
2117 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 2195 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
2118 int expected_additional_properties) { | 2196 int expected_additional_properties) { |
2119 if (!HasFastProperties()) return this; | 2197 if (!HasFastProperties()) return this; |
2120 | 2198 |
2121 // The global object is always normalized. | 2199 // The global object is always normalized. |
2122 ASSERT(!IsGlobalObject()); | 2200 ASSERT(!IsGlobalObject()); |
2123 | 2201 |
2124 // Allocate new content. | 2202 // Allocate new content. |
2125 int property_count = map()->NumberOfDescribedProperties(); | 2203 int property_count = map()->NumberOfDescribedProperties(); |
2126 if (expected_additional_properties > 0) { | 2204 if (expected_additional_properties > 0) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2171 break; | 2249 break; |
2172 default: | 2250 default: |
2173 UNREACHABLE(); | 2251 UNREACHABLE(); |
2174 } | 2252 } |
2175 } | 2253 } |
2176 | 2254 |
2177 // Copy the next enumeration index from instance descriptor. | 2255 // Copy the next enumeration index from instance descriptor. |
2178 int index = map()->instance_descriptors()->NextEnumerationIndex(); | 2256 int index = map()->instance_descriptors()->NextEnumerationIndex(); |
2179 dictionary->SetNextEnumerationIndex(index); | 2257 dictionary->SetNextEnumerationIndex(index); |
2180 | 2258 |
2181 // Allocate new map. | 2259 int hash = NormalizedMapCache::Hash(map(), mode); |
2182 obj = map()->CopyDropDescriptors(); | 2260 obj = NormalizedMapCache::Get(map(), hash, mode); |
2183 if (obj->IsFailure()) return obj; | 2261 if (obj->IsMap()) { |
2184 Map* new_map = Map::cast(obj); | 2262 Map* new_map = Map::cast(obj); |
2263 int new_instance_size = new_map->instance_size(); | |
2264 int instance_size_delta = map()->instance_size() - new_instance_size; | |
2265 if (instance_size_delta != 0) { | |
2266 Heap::CreateFillerObjectAt(this->address() + new_instance_size, | |
2267 instance_size_delta); | |
2268 } | |
2269 set_map(new_map); | |
2270 } else { | |
2271 // Allocate new map. | |
2272 obj = map()->CopyDropDescriptors(); | |
2273 if (obj->IsFailure()) return obj; | |
2274 Map* new_map = Map::cast(obj); | |
2185 | 2275 |
2186 // Clear inobject properties if needed by adjusting the instance size and | 2276 // Clear inobject properties if needed by adjusting the instance size and |
2187 // putting in a filler object instead of the inobject properties. | 2277 // putting in a filler object instead of the inobject properties. |
2188 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { | 2278 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { |
2189 int instance_size_delta = map()->inobject_properties() * kPointerSize; | 2279 int instance_size_delta = map()->inobject_properties() * kPointerSize; |
2190 int new_instance_size = map()->instance_size() - instance_size_delta; | 2280 int new_instance_size = map()->instance_size() - instance_size_delta; |
2191 new_map->set_inobject_properties(0); | 2281 new_map->set_inobject_properties(0); |
2192 new_map->set_instance_size(new_instance_size); | 2282 new_map->set_instance_size(new_instance_size); |
2193 new_map->set_scavenger(Heap::GetScavenger(new_map->instance_type(), | 2283 new_map->set_scavenger(Heap::GetScavenger(new_map->instance_type(), |
2194 new_map->instance_size())); | 2284 new_map->instance_size())); |
2195 Heap::CreateFillerObjectAt(this->address() + new_instance_size, | 2285 Heap::CreateFillerObjectAt(this->address() + new_instance_size, |
2196 instance_size_delta); | 2286 instance_size_delta); |
2287 } | |
2288 new_map->set_unused_property_fields(0); | |
2289 new_map->set_pre_allocated_property_fields(0); | |
2290 | |
2291 // We have now successfully allocated all the necessary objects. | |
2292 // Changes can now be made with the guarantee that all of them take effect. | |
2293 set_map(new_map); | |
2294 map()->set_instance_descriptors(Heap::empty_descriptor_array()); | |
2295 NormalizedMapCache::Set(hash, new_map); | |
2296 Counters::normalized_maps.Increment(); | |
2197 } | 2297 } |
2198 new_map->set_unused_property_fields(0); | |
2199 | |
2200 // We have now successfully allocated all the necessary objects. | |
2201 // Changes can now be made with the guarantee that all of them take effect. | |
2202 set_map(new_map); | |
2203 map()->set_instance_descriptors(Heap::empty_descriptor_array()); | |
2204 | 2298 |
2205 set_properties(dictionary); | 2299 set_properties(dictionary); |
2206 | 2300 |
2207 Counters::props_to_dictionary.Increment(); | 2301 Counters::props_to_dictionary.Increment(); |
2208 | 2302 |
2209 #ifdef DEBUG | 2303 #ifdef DEBUG |
2210 if (FLAG_trace_normalization) { | 2304 if (FLAG_trace_normalization) { |
2211 PrintF("Object properties have been normalized:\n"); | 2305 PrintF("Object properties have been normalized:\n"); |
2212 Print(); | 2306 Print(); |
2213 } | 2307 } |
(...skipping 6597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8811 if (break_point_objects()->IsUndefined()) return 0; | 8905 if (break_point_objects()->IsUndefined()) return 0; |
8812 // Single beak point. | 8906 // Single beak point. |
8813 if (!break_point_objects()->IsFixedArray()) return 1; | 8907 if (!break_point_objects()->IsFixedArray()) return 1; |
8814 // Multiple break points. | 8908 // Multiple break points. |
8815 return FixedArray::cast(break_point_objects())->length(); | 8909 return FixedArray::cast(break_point_objects())->length(); |
8816 } | 8910 } |
8817 #endif | 8911 #endif |
8818 | 8912 |
8819 | 8913 |
8820 } } // namespace v8::internal | 8914 } } // namespace v8::internal |
OLD | NEW |