OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 5128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5139 set(EntryToIndex(index) + 1, heap->null_value()); | 5139 set(EntryToIndex(index) + 1, heap->null_value()); |
5140 ElementRemoved(); | 5140 ElementRemoved(); |
5141 } | 5141 } |
5142 | 5142 |
5143 | 5143 |
5144 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache, | 5144 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache, |
5145 MapHandleList* maps, | 5145 MapHandleList* maps, |
5146 Code::Flags flags, | 5146 Code::Flags flags, |
5147 Handle<Code> code) { | 5147 Handle<Code> code) { |
5148 Isolate* isolate = cache->GetIsolate(); | 5148 Isolate* isolate = cache->GetIsolate(); |
5149 List<Map*> raw_maps(maps->length()); | 5149 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code)); |
5150 CALL_HEAP_FUNCTION_VOID( | |
5151 isolate, | |
5152 (raw_maps.Clear(), | |
5153 cache->Update(UnwrapHandleList(&raw_maps, maps), flags, *code))); | |
5154 } | 5150 } |
5155 | 5151 |
5156 | 5152 |
5157 MaybeObject* PolymorphicCodeCache::Update(MapList* maps, | 5153 MaybeObject* PolymorphicCodeCache::Update(MapHandleList* maps, |
5158 Code::Flags flags, | 5154 Code::Flags flags, |
5159 Code* code) { | 5155 Code* code) { |
5160 // Initialize cache if necessary. | 5156 // Initialize cache if necessary. |
5161 if (cache()->IsUndefined()) { | 5157 if (cache()->IsUndefined()) { |
5162 Object* result; | 5158 Object* result; |
5163 { MaybeObject* maybe_result = | 5159 { MaybeObject* maybe_result = |
5164 PolymorphicCodeCacheHashTable::Allocate( | 5160 PolymorphicCodeCacheHashTable::Allocate( |
5165 PolymorphicCodeCacheHashTable::kInitialSize); | 5161 PolymorphicCodeCacheHashTable::kInitialSize); |
5166 if (!maybe_result->ToObject(&result)) return maybe_result; | 5162 if (!maybe_result->ToObject(&result)) return maybe_result; |
5167 } | 5163 } |
5168 set_cache(result); | 5164 set_cache(result); |
5169 } else { | 5165 } else { |
5170 // This entry shouldn't be contained in the cache yet. | 5166 // This entry shouldn't be contained in the cache yet. |
5171 ASSERT(PolymorphicCodeCacheHashTable::cast(cache()) | 5167 ASSERT(PolymorphicCodeCacheHashTable::cast(cache()) |
5172 ->Lookup(maps, flags)->IsUndefined()); | 5168 ->Lookup(maps, flags)->IsUndefined()); |
5173 } | 5169 } |
5174 PolymorphicCodeCacheHashTable* hash_table = | 5170 PolymorphicCodeCacheHashTable* hash_table = |
5175 PolymorphicCodeCacheHashTable::cast(cache()); | 5171 PolymorphicCodeCacheHashTable::cast(cache()); |
5176 Object* new_cache; | 5172 Object* new_cache; |
5177 { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code); | 5173 { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code); |
5178 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; | 5174 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; |
5179 } | 5175 } |
5180 set_cache(new_cache); | 5176 set_cache(new_cache); |
5181 return this; | 5177 return this; |
5182 } | 5178 } |
5183 | 5179 |
5184 | 5180 |
5185 Handle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps, | 5181 Handle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps, |
5186 Code::Flags flags) { | 5182 Code::Flags flags) { |
5187 List<Map*> raw_maps(maps->length()); | |
5188 return Handle<Object>(Lookup(UnwrapHandleList(&raw_maps, maps), flags)); | |
5189 } | |
5190 | |
5191 | |
5192 Object* PolymorphicCodeCache::Lookup(MapList* maps, Code::Flags flags) { | |
5193 if (!cache()->IsUndefined()) { | 5183 if (!cache()->IsUndefined()) { |
5194 PolymorphicCodeCacheHashTable* hash_table = | 5184 PolymorphicCodeCacheHashTable* hash_table = |
5195 PolymorphicCodeCacheHashTable::cast(cache()); | 5185 PolymorphicCodeCacheHashTable::cast(cache()); |
5196 return hash_table->Lookup(maps, flags); | 5186 return Handle<Object>(hash_table->Lookup(maps, flags)); |
5197 } else { | 5187 } else { |
5198 return GetHeap()->undefined_value(); | 5188 return GetIsolate()->factory()->undefined_value(); |
5199 } | 5189 } |
5200 } | 5190 } |
5201 | 5191 |
5202 | 5192 |
5203 // Despite their name, object of this class are not stored in the actual | 5193 // Despite their name, object of this class are not stored in the actual |
5204 // hash table; instead they're temporarily used for lookups. It is therefore | 5194 // hash table; instead they're temporarily used for lookups. It is therefore |
5205 // safe to have a weak (non-owning) pointer to a MapList as a member field. | 5195 // safe to have a weak (non-owning) pointer to a MapList as a member field. |
5206 class PolymorphicCodeCacheHashTableKey : public HashTableKey { | 5196 class PolymorphicCodeCacheHashTableKey : public HashTableKey { |
5207 public: | 5197 public: |
5208 // Callers must ensure that |maps| outlives the newly constructed object. | 5198 // Callers must ensure that |maps| outlives the newly constructed object. |
5209 PolymorphicCodeCacheHashTableKey(MapList* maps, int code_flags) | 5199 PolymorphicCodeCacheHashTableKey(MapHandleList* maps, int code_flags) |
5210 : maps_(maps), | 5200 : maps_(maps), |
5211 code_flags_(code_flags) {} | 5201 code_flags_(code_flags) {} |
5212 | 5202 |
5213 bool IsMatch(Object* other) { | 5203 bool IsMatch(Object* other) { |
5214 MapList other_maps(kDefaultListAllocationSize); | 5204 MapHandleList other_maps(kDefaultListAllocationSize); |
ulan
2011/10/24 09:04:01
Adds new precondition (handle scope) for IsMatch.
| |
5215 int other_flags; | 5205 int other_flags; |
5216 FromObject(other, &other_flags, &other_maps); | 5206 FromObject(other, &other_flags, &other_maps); |
5217 if (code_flags_ != other_flags) return false; | 5207 if (code_flags_ != other_flags) return false; |
5218 if (maps_->length() != other_maps.length()) return false; | 5208 if (maps_->length() != other_maps.length()) return false; |
5219 // Compare just the hashes first because it's faster. | 5209 // Compare just the hashes first because it's faster. |
5220 int this_hash = MapsHashHelper(maps_, code_flags_); | 5210 int this_hash = MapsHashHelper(maps_, code_flags_); |
5221 int other_hash = MapsHashHelper(&other_maps, other_flags); | 5211 int other_hash = MapsHashHelper(&other_maps, other_flags); |
5222 if (this_hash != other_hash) return false; | 5212 if (this_hash != other_hash) return false; |
5223 | 5213 |
5224 // Full comparison: for each map in maps_, look for an equivalent map in | 5214 // Full comparison: for each map in maps_, look for an equivalent map in |
5225 // other_maps. This implementation is slow, but probably good enough for | 5215 // other_maps. This implementation is slow, but probably good enough for |
5226 // now because the lists are short (<= 4 elements currently). | 5216 // now because the lists are short (<= 4 elements currently). |
5227 for (int i = 0; i < maps_->length(); ++i) { | 5217 for (int i = 0; i < maps_->length(); ++i) { |
5228 bool match_found = false; | 5218 bool match_found = false; |
5229 for (int j = 0; j < other_maps.length(); ++j) { | 5219 for (int j = 0; j < other_maps.length(); ++j) { |
5230 if (maps_->at(i)->EquivalentTo(other_maps.at(j))) { | 5220 if (maps_->at(i)->EquivalentTo(*other_maps.at(j))) { |
5231 match_found = true; | 5221 match_found = true; |
5232 break; | 5222 break; |
5233 } | 5223 } |
5234 } | 5224 } |
5235 if (!match_found) return false; | 5225 if (!match_found) return false; |
5236 } | 5226 } |
5237 return true; | 5227 return true; |
5238 } | 5228 } |
5239 | 5229 |
5240 static uint32_t MapsHashHelper(MapList* maps, int code_flags) { | 5230 static uint32_t MapsHashHelper(MapHandleList* maps, int code_flags) { |
5241 uint32_t hash = code_flags; | 5231 uint32_t hash = code_flags; |
5242 for (int i = 0; i < maps->length(); ++i) { | 5232 for (int i = 0; i < maps->length(); ++i) { |
5243 hash ^= maps->at(i)->Hash(); | 5233 hash ^= maps->at(i)->Hash(); |
5244 } | 5234 } |
5245 return hash; | 5235 return hash; |
5246 } | 5236 } |
5247 | 5237 |
5248 uint32_t Hash() { | 5238 uint32_t Hash() { |
5249 return MapsHashHelper(maps_, code_flags_); | 5239 return MapsHashHelper(maps_, code_flags_); |
5250 } | 5240 } |
5251 | 5241 |
5252 uint32_t HashForObject(Object* obj) { | 5242 uint32_t HashForObject(Object* obj) { |
5253 MapList other_maps(kDefaultListAllocationSize); | 5243 MapHandleList other_maps(kDefaultListAllocationSize); |
ulan
2011/10/24 09:04:01
Adds new precondition (handle scope) for HashForOb
| |
5254 int other_flags; | 5244 int other_flags; |
5255 FromObject(obj, &other_flags, &other_maps); | 5245 FromObject(obj, &other_flags, &other_maps); |
5256 return MapsHashHelper(&other_maps, other_flags); | 5246 return MapsHashHelper(&other_maps, other_flags); |
5257 } | 5247 } |
5258 | 5248 |
5259 MUST_USE_RESULT MaybeObject* AsObject() { | 5249 MUST_USE_RESULT MaybeObject* AsObject() { |
5260 Object* obj; | 5250 Object* obj; |
5261 // The maps in |maps_| must be copied to a newly allocated FixedArray, | 5251 // The maps in |maps_| must be copied to a newly allocated FixedArray, |
5262 // both because the referenced MapList is short-lived, and because C++ | 5252 // both because the referenced MapList is short-lived, and because C++ |
5263 // objects can't be stored in the heap anyway. | 5253 // objects can't be stored in the heap anyway. |
5264 { MaybeObject* maybe_obj = | 5254 { MaybeObject* maybe_obj = |
5265 HEAP->AllocateUninitializedFixedArray(maps_->length() + 1); | 5255 HEAP->AllocateUninitializedFixedArray(maps_->length() + 1); |
5266 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 5256 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
5267 } | 5257 } |
5268 FixedArray* list = FixedArray::cast(obj); | 5258 FixedArray* list = FixedArray::cast(obj); |
5269 list->set(0, Smi::FromInt(code_flags_)); | 5259 list->set(0, Smi::FromInt(code_flags_)); |
5270 for (int i = 0; i < maps_->length(); ++i) { | 5260 for (int i = 0; i < maps_->length(); ++i) { |
5271 list->set(i + 1, maps_->at(i)); | 5261 list->set(i + 1, *maps_->at(i)); |
5272 } | 5262 } |
5273 return list; | 5263 return list; |
5274 } | 5264 } |
5275 | 5265 |
5276 private: | 5266 private: |
5277 static MapList* FromObject(Object* obj, int* code_flags, MapList* maps) { | 5267 static MapHandleList* FromObject(Object* obj, |
5268 int* code_flags, | |
5269 MapHandleList* maps) { | |
5278 FixedArray* list = FixedArray::cast(obj); | 5270 FixedArray* list = FixedArray::cast(obj); |
5279 maps->Rewind(0); | 5271 maps->Rewind(0); |
5280 *code_flags = Smi::cast(list->get(0))->value(); | 5272 *code_flags = Smi::cast(list->get(0))->value(); |
5281 for (int i = 1; i < list->length(); ++i) { | 5273 for (int i = 1; i < list->length(); ++i) { |
5282 maps->Add(Map::cast(list->get(i))); | 5274 maps->Add(Handle<Map>(Map::cast(list->get(i)))); |
5283 } | 5275 } |
5284 return maps; | 5276 return maps; |
5285 } | 5277 } |
5286 | 5278 |
5287 MapList* maps_; // weak. | 5279 MapHandleList* maps_; // weak. |
5288 int code_flags_; | 5280 int code_flags_; |
5289 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; | 5281 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; |
5290 }; | 5282 }; |
5291 | 5283 |
5292 | 5284 |
5293 Object* PolymorphicCodeCacheHashTable::Lookup(MapList* maps, int code_flags) { | 5285 Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps, |
5286 int code_flags) { | |
5294 PolymorphicCodeCacheHashTableKey key(maps, code_flags); | 5287 PolymorphicCodeCacheHashTableKey key(maps, code_flags); |
5295 int entry = FindEntry(&key); | 5288 int entry = FindEntry(&key); |
5296 if (entry == kNotFound) return GetHeap()->undefined_value(); | 5289 if (entry == kNotFound) return GetHeap()->undefined_value(); |
5297 return get(EntryToIndex(entry) + 1); | 5290 return get(EntryToIndex(entry) + 1); |
5298 } | 5291 } |
5299 | 5292 |
5300 | 5293 |
5301 MaybeObject* PolymorphicCodeCacheHashTable::Put(MapList* maps, | 5294 MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps, |
5302 int code_flags, | 5295 int code_flags, |
5303 Code* code) { | 5296 Code* code) { |
5304 PolymorphicCodeCacheHashTableKey key(maps, code_flags); | 5297 PolymorphicCodeCacheHashTableKey key(maps, code_flags); |
5305 Object* obj; | 5298 Object* obj; |
5306 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 5299 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
5307 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 5300 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
5308 } | 5301 } |
5309 PolymorphicCodeCacheHashTable* cache = | 5302 PolymorphicCodeCacheHashTable* cache = |
5310 reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj); | 5303 reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj); |
5311 int entry = cache->FindInsertionEntry(key.Hash()); | 5304 int entry = cache->FindInsertionEntry(key.Hash()); |
(...skipping 7322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12634 if (break_point_objects()->IsUndefined()) return 0; | 12627 if (break_point_objects()->IsUndefined()) return 0; |
12635 // Single break point. | 12628 // Single break point. |
12636 if (!break_point_objects()->IsFixedArray()) return 1; | 12629 if (!break_point_objects()->IsFixedArray()) return 1; |
12637 // Multiple break points. | 12630 // Multiple break points. |
12638 return FixedArray::cast(break_point_objects())->length(); | 12631 return FixedArray::cast(break_point_objects())->length(); |
12639 } | 12632 } |
12640 #endif // ENABLE_DEBUGGER_SUPPORT | 12633 #endif // ENABLE_DEBUGGER_SUPPORT |
12641 | 12634 |
12642 | 12635 |
12643 } } // namespace v8::internal | 12636 } } // namespace v8::internal |
OLD | NEW |