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

Side by Side Diff: src/objects.cc

Issue 8368024: Use handle lists instead of raw pointer lists in polymorphic code cache. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698