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

Side by Side Diff: src/objects.cc

Issue 3501007: Merge r5518 into 2.3 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/2.3/
Patch Set: '' Created 10 years, 3 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 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 2080 matching lines...) Expand 10 before | Expand all | Expand 10 after
2091 if (HasLocalElement(index)) return NONE; 2091 if (HasLocalElement(index)) return NONE;
2092 return ABSENT; 2092 return ABSENT;
2093 } 2093 }
2094 // Named property. 2094 // Named property.
2095 LookupResult result; 2095 LookupResult result;
2096 LocalLookup(name, &result); 2096 LocalLookup(name, &result);
2097 return GetPropertyAttribute(this, &result, name, false); 2097 return GetPropertyAttribute(this, &result, name, false);
2098 } 2098 }
2099 2099
2100 2100
2101 bool NormalizedMapCache::IsCacheable(JSObject* object) {
2102 // Caching for global objects is not worth it (there are too few of them).
2103 return !object->IsGlobalObject();
2104 }
2105
2106
2107 Object* NormalizedMapCache::Get(JSObject* obj, PropertyNormalizationMode mode) { 2101 Object* NormalizedMapCache::Get(JSObject* obj, PropertyNormalizationMode mode) {
2108 Object* result; 2102 Map* fast = obj->map();
2103 int index = Hash(fast) % kEntries;
2104 Object* result = get(index);
2105 if (result->IsMap() && CheckHit(Map::cast(result), fast, mode)) {
2106 #ifdef DEBUG
2107 if (FLAG_enable_slow_asserts) {
2108 // The cached map should match newly created normalized map bit-by-bit.
2109 Object* fresh = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
2110 if (!fresh->IsFailure()) {
2111 // Copy the unused byte so that the assertion below works.
2112 Map::cast(fresh)->address()[Map::kUnusedOffset] =
2113 Map::cast(result)->address()[Map::kUnusedOffset];
2114 ASSERT(memcmp(Map::cast(fresh)->address(),
2115 Map::cast(result)->address(),
2116 Map::kSize) == 0);
2117 }
2118 }
2119 #endif
2120 return result;
2121 }
2109 2122
2110 Map* fast = obj->map(); 2123 result = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
2111 if (!IsCacheable(obj)) { 2124 if (result->IsFailure()) return result;
2112 result = fast->CopyNormalized(mode); 2125 set(index, result);
2113 if (result->IsFailure()) return result;
2114 } else {
2115 int index = Hash(fast) % kEntries;
2116 result = get(index);
2117
2118 if (result->IsMap() && CheckHit(Map::cast(result), fast, mode)) {
2119 #ifdef DEBUG
2120 if (FLAG_enable_slow_asserts) {
2121 // Make sure that the new slow map has exactly the same hash as the
2122 // original fast map. This way we can use hash to check if a slow map
2123 // is already in the hash (see Contains method).
2124 ASSERT(Hash(fast) == Hash(Map::cast(result)));
2125 // The cached map should match newly created normalized map bit-by-bit.
2126 Object* fresh = fast->CopyNormalized(mode);
2127 if (!fresh->IsFailure()) {
2128 // Copy the unused byte so that the assertion below works.
2129 Map::cast(fresh)->address()[Map::kUnusedOffset] =
2130 Map::cast(result)->address()[Map::kUnusedOffset];
2131 ASSERT(memcmp(Map::cast(fresh)->address(),
2132 Map::cast(result)->address(),
2133 Map::kSize) == 0);
2134 }
2135 }
2136 #endif
2137 return result;
2138 }
2139
2140 result = fast->CopyNormalized(mode);
2141 if (result->IsFailure()) return result;
2142 set(index, result);
2143 }
2144 Counters::normalized_maps.Increment(); 2126 Counters::normalized_maps.Increment();
2145 2127
2146 return result; 2128 return result;
2147 } 2129 }
2148 2130
2149 2131
2150 bool NormalizedMapCache::Contains(Map* map) {
2151 // If the map is present in the cache it can only be at one place:
2152 // at the index calculated from the hash. We assume that a slow map has the
2153 // same hash as a fast map it has been generated from.
2154 int index = Hash(map) % kEntries;
2155 return get(index) == map;
2156 }
2157
2158
2159 void NormalizedMapCache::Clear() { 2132 void NormalizedMapCache::Clear() {
2160 int entries = length(); 2133 int entries = length();
2161 for (int i = 0; i != entries; i++) { 2134 for (int i = 0; i != entries; i++) {
2162 set_undefined(i); 2135 set_undefined(i);
2163 } 2136 }
2164 } 2137 }
2165 2138
2166 2139
2167 int NormalizedMapCache::Hash(Map* fast) { 2140 int NormalizedMapCache::Hash(Map* fast) {
2168 // For performance reasons we only hash the 3 most variable fields of a map: 2141 // For performance reasons we only hash the 3 most variable fields of a map:
(...skipping 10 matching lines...) Expand all
2179 reinterpret_cast<uintptr_t>(fast->prototype())) << 2); 2152 reinterpret_cast<uintptr_t>(fast->prototype())) << 2);
2180 2153
2181 return hash ^ (hash >> 16) ^ fast->bit_field2(); 2154 return hash ^ (hash >> 16) ^ fast->bit_field2();
2182 } 2155 }
2183 2156
2184 2157
2185 bool NormalizedMapCache::CheckHit(Map* slow, 2158 bool NormalizedMapCache::CheckHit(Map* slow,
2186 Map* fast, 2159 Map* fast,
2187 PropertyNormalizationMode mode) { 2160 PropertyNormalizationMode mode) {
2188 #ifdef DEBUG 2161 #ifdef DEBUG
2189 slow->NormalizedMapVerify(); 2162 slow->SharedMapVerify();
2190 #endif 2163 #endif
2191 return 2164 return
2192 slow->constructor() == fast->constructor() && 2165 slow->constructor() == fast->constructor() &&
2193 slow->prototype() == fast->prototype() && 2166 slow->prototype() == fast->prototype() &&
2194 slow->inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ? 2167 slow->inobject_properties() == ((mode == CLEAR_INOBJECT_PROPERTIES) ?
2195 0 : 2168 0 :
2196 fast->inobject_properties()) && 2169 fast->inobject_properties()) &&
2197 slow->instance_type() == fast->instance_type() && 2170 slow->instance_type() == fast->instance_type() &&
2198 slow->bit_field() == fast->bit_field() && 2171 slow->bit_field() == fast->bit_field() &&
2199 slow->bit_field2() == fast->bit_field2(); 2172 (slow->bit_field2() & ~(1<<Map::kIsShared)) == fast->bit_field2();
2200 } 2173 }
2201 2174
2202 2175
2203 Object* JSObject::UpdateMapCodeCache(String* name, Code* code) { 2176 Object* JSObject::UpdateMapCodeCache(String* name, Code* code) {
2204 if (!HasFastProperties() && 2177 if (map()->is_shared()) {
2205 NormalizedMapCache::IsCacheable(this) && 2178 // Fast case maps are never marked as shared.
2206 Top::context()->global_context()->normalized_map_cache()-> 2179 ASSERT(!HasFastProperties());
2207 Contains(map())) { 2180 // Replace the map with an identical copy that can be safely modified.
2208 // Replace the map with the identical copy that can be safely modified. 2181 Object* obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
2209 Object* obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES); 2182 UNIQUE_NORMALIZED_MAP);
2210 if (obj->IsFailure()) return obj; 2183 if (obj->IsFailure()) return obj;
2211 Counters::normalized_maps.Increment(); 2184 Counters::normalized_maps.Increment();
2212 2185
2213 set_map(Map::cast(obj)); 2186 set_map(Map::cast(obj));
2214 } 2187 }
2215 return map()->UpdateCodeCache(name, code); 2188 return map()->UpdateCodeCache(name, code);
2216 } 2189 }
2217 2190
2218 2191
2219 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, 2192 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
3184 Object* descriptors = 3157 Object* descriptors =
3185 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); 3158 ctor->initial_map()->instance_descriptors()->RemoveTransitions();
3186 if (descriptors->IsFailure()) return descriptors; 3159 if (descriptors->IsFailure()) return descriptors;
3187 Map::cast(result)->set_instance_descriptors( 3160 Map::cast(result)->set_instance_descriptors(
3188 DescriptorArray::cast(descriptors)); 3161 DescriptorArray::cast(descriptors));
3189 Map::cast(result)->set_pre_allocated_property_fields( 3162 Map::cast(result)->set_pre_allocated_property_fields(
3190 pre_allocated_property_fields()); 3163 pre_allocated_property_fields());
3191 } 3164 }
3192 Map::cast(result)->set_bit_field(bit_field()); 3165 Map::cast(result)->set_bit_field(bit_field());
3193 Map::cast(result)->set_bit_field2(bit_field2()); 3166 Map::cast(result)->set_bit_field2(bit_field2());
3167 Map::cast(result)->set_is_shared(false);
3194 Map::cast(result)->ClearCodeCache(); 3168 Map::cast(result)->ClearCodeCache();
3195 return result; 3169 return result;
3196 } 3170 }
3197 3171
3198 3172
3199 Object* Map::CopyNormalized(PropertyNormalizationMode mode) { 3173 Object* Map::CopyNormalized(PropertyNormalizationMode mode,
3174 NormalizedMapSharingMode sharing) {
3200 int new_instance_size = instance_size(); 3175 int new_instance_size = instance_size();
3201 if (mode == CLEAR_INOBJECT_PROPERTIES) { 3176 if (mode == CLEAR_INOBJECT_PROPERTIES) {
3202 new_instance_size -= inobject_properties() * kPointerSize; 3177 new_instance_size -= inobject_properties() * kPointerSize;
3203 } 3178 }
3204 3179
3205 Object* result = Heap::AllocateMap(instance_type(), new_instance_size); 3180 Object* result = Heap::AllocateMap(instance_type(), new_instance_size);
3206 if (result->IsFailure()) return result; 3181 if (result->IsFailure()) return result;
3207 3182
3208 if (mode != CLEAR_INOBJECT_PROPERTIES) { 3183 if (mode != CLEAR_INOBJECT_PROPERTIES) {
3209 Map::cast(result)->set_inobject_properties(inobject_properties()); 3184 Map::cast(result)->set_inobject_properties(inobject_properties());
3210 } 3185 }
3211 3186
3212 Map::cast(result)->set_prototype(prototype()); 3187 Map::cast(result)->set_prototype(prototype());
3213 Map::cast(result)->set_constructor(constructor()); 3188 Map::cast(result)->set_constructor(constructor());
3214 3189
3215 Map::cast(result)->set_bit_field(bit_field()); 3190 Map::cast(result)->set_bit_field(bit_field());
3216 Map::cast(result)->set_bit_field2(bit_field2()); 3191 Map::cast(result)->set_bit_field2(bit_field2());
3217 3192
3193 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
3194
3218 #ifdef DEBUG 3195 #ifdef DEBUG
3219 Map::cast(result)->NormalizedMapVerify(); 3196 if (Map::cast(result)->is_shared()) {
3197 Map::cast(result)->SharedMapVerify();
3198 }
3220 #endif 3199 #endif
3221 3200
3222 return result; 3201 return result;
3223 } 3202 }
3224 3203
3225 3204
3226 Object* Map::CopyDropTransitions() { 3205 Object* Map::CopyDropTransitions() {
3227 Object* new_map = CopyDropDescriptors(); 3206 Object* new_map = CopyDropDescriptors();
3228 if (new_map->IsFailure()) return new_map; 3207 if (new_map->IsFailure()) return new_map;
3229 Object* descriptors = instance_descriptors()->RemoveTransitions(); 3208 Object* descriptors = instance_descriptors()->RemoveTransitions();
(...skipping 5678 matching lines...) Expand 10 before | Expand all | Expand 10 after
8908 if (break_point_objects()->IsUndefined()) return 0; 8887 if (break_point_objects()->IsUndefined()) return 0;
8909 // Single beak point. 8888 // Single beak point.
8910 if (!break_point_objects()->IsFixedArray()) return 1; 8889 if (!break_point_objects()->IsFixedArray()) return 1;
8911 // Multiple break points. 8890 // Multiple break points.
8912 return FixedArray::cast(break_point_objects())->length(); 8891 return FixedArray::cast(break_point_objects())->length();
8913 } 8892 }
8914 #endif 8893 #endif
8915 8894
8916 8895
8917 } } // namespace v8::internal 8896 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | src/objects-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698