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

Side by Side Diff: src/objects.cc

Issue 3028019: Cache maps when normalizing properties.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/contexts.h ('k') | src/v8-counters.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 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
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
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
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
OLDNEW
« no previous file with comments | « src/contexts.h ('k') | src/v8-counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698