OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 8012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8023 | 8023 |
8024 void CodeCacheHashTable::RemoveByIndex(int index) { | 8024 void CodeCacheHashTable::RemoveByIndex(int index) { |
8025 ASSERT(index >= 0); | 8025 ASSERT(index >= 0); |
8026 Heap* heap = GetHeap(); | 8026 Heap* heap = GetHeap(); |
8027 set(EntryToIndex(index), heap->the_hole_value()); | 8027 set(EntryToIndex(index), heap->the_hole_value()); |
8028 set(EntryToIndex(index) + 1, heap->the_hole_value()); | 8028 set(EntryToIndex(index) + 1, heap->the_hole_value()); |
8029 ElementRemoved(); | 8029 ElementRemoved(); |
8030 } | 8030 } |
8031 | 8031 |
8032 | 8032 |
8033 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache, | 8033 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> code_cache, |
8034 MapHandleList* maps, | 8034 MapHandleList* maps, |
8035 Code::Flags flags, | 8035 Code::Flags flags, |
8036 Handle<Code> code) { | 8036 Handle<Code> code) { |
8037 Isolate* isolate = cache->GetIsolate(); | 8037 Isolate* isolate = code_cache->GetIsolate(); |
8038 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code)); | 8038 if (code_cache->cache()->IsUndefined()) { |
| 8039 Handle<PolymorphicCodeCacheHashTable> result = |
| 8040 PolymorphicCodeCacheHashTable::New( |
| 8041 isolate, |
| 8042 PolymorphicCodeCacheHashTable::kInitialSize); |
| 8043 code_cache->set_cache(*result); |
| 8044 } else { |
| 8045 // This entry shouldn't be contained in the cache yet. |
| 8046 ASSERT(PolymorphicCodeCacheHashTable::cast(code_cache->cache()) |
| 8047 ->Lookup(maps, flags)->IsUndefined()); |
| 8048 } |
| 8049 Handle<PolymorphicCodeCacheHashTable> hash_table = |
| 8050 handle(PolymorphicCodeCacheHashTable::cast(code_cache->cache())); |
| 8051 Handle<PolymorphicCodeCacheHashTable> new_cache = |
| 8052 PolymorphicCodeCacheHashTable::Put(hash_table, maps, flags, code); |
| 8053 code_cache->set_cache(*new_cache); |
8039 } | 8054 } |
8040 | 8055 |
8041 | 8056 |
8042 MaybeObject* PolymorphicCodeCache::Update(MapHandleList* maps, | |
8043 Code::Flags flags, | |
8044 Code* code) { | |
8045 // Initialize cache if necessary. | |
8046 if (cache()->IsUndefined()) { | |
8047 Object* result; | |
8048 { MaybeObject* maybe_result = | |
8049 PolymorphicCodeCacheHashTable::Allocate( | |
8050 GetHeap(), | |
8051 PolymorphicCodeCacheHashTable::kInitialSize); | |
8052 if (!maybe_result->ToObject(&result)) return maybe_result; | |
8053 } | |
8054 set_cache(result); | |
8055 } else { | |
8056 // This entry shouldn't be contained in the cache yet. | |
8057 ASSERT(PolymorphicCodeCacheHashTable::cast(cache()) | |
8058 ->Lookup(maps, flags)->IsUndefined()); | |
8059 } | |
8060 PolymorphicCodeCacheHashTable* hash_table = | |
8061 PolymorphicCodeCacheHashTable::cast(cache()); | |
8062 Object* new_cache; | |
8063 { MaybeObject* maybe_new_cache = hash_table->Put(maps, flags, code); | |
8064 if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache; | |
8065 } | |
8066 set_cache(new_cache); | |
8067 return this; | |
8068 } | |
8069 | |
8070 | |
8071 Handle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps, | 8057 Handle<Object> PolymorphicCodeCache::Lookup(MapHandleList* maps, |
8072 Code::Flags flags) { | 8058 Code::Flags flags) { |
8073 if (!cache()->IsUndefined()) { | 8059 if (!cache()->IsUndefined()) { |
8074 PolymorphicCodeCacheHashTable* hash_table = | 8060 PolymorphicCodeCacheHashTable* hash_table = |
8075 PolymorphicCodeCacheHashTable::cast(cache()); | 8061 PolymorphicCodeCacheHashTable::cast(cache()); |
8076 return Handle<Object>(hash_table->Lookup(maps, flags), GetIsolate()); | 8062 return Handle<Object>(hash_table->Lookup(maps, flags), GetIsolate()); |
8077 } else { | 8063 } else { |
8078 return GetIsolate()->factory()->undefined_value(); | 8064 return GetIsolate()->factory()->undefined_value(); |
8079 } | 8065 } |
8080 } | 8066 } |
8081 | 8067 |
8082 | 8068 |
8083 // Despite their name, object of this class are not stored in the actual | 8069 // Despite their name, object of this class are not stored in the actual |
8084 // hash table; instead they're temporarily used for lookups. It is therefore | 8070 // hash table; instead they're temporarily used for lookups. It is therefore |
8085 // safe to have a weak (non-owning) pointer to a MapList as a member field. | 8071 // safe to have a weak (non-owning) pointer to a MapList as a member field. |
8086 class PolymorphicCodeCacheHashTableKey : public HashTableKey { | 8072 class PolymorphicCodeCacheHashTableKey : public HashTableKey { |
8087 public: | 8073 public: |
8088 // Callers must ensure that |maps| outlives the newly constructed object. | 8074 // Callers must ensure that |maps| outlives the newly constructed object. |
8089 PolymorphicCodeCacheHashTableKey(MapHandleList* maps, int code_flags) | 8075 PolymorphicCodeCacheHashTableKey( |
8090 : maps_(maps), | 8076 Isolate* isolate, MapHandleList* maps, int code_flags) |
| 8077 : isolate_(isolate), |
| 8078 maps_(maps), |
8091 code_flags_(code_flags) {} | 8079 code_flags_(code_flags) {} |
8092 | 8080 |
8093 bool IsMatch(Object* other) { | 8081 bool IsMatch(Object* other) { |
8094 MapHandleList other_maps(kDefaultListAllocationSize); | 8082 MapHandleList other_maps(kDefaultListAllocationSize); |
8095 int other_flags; | 8083 int other_flags; |
8096 FromObject(other, &other_flags, &other_maps); | 8084 FromObject(other, &other_flags, &other_maps); |
8097 if (code_flags_ != other_flags) return false; | 8085 if (code_flags_ != other_flags) return false; |
8098 if (maps_->length() != other_maps.length()) return false; | 8086 if (maps_->length() != other_maps.length()) return false; |
8099 // Compare just the hashes first because it's faster. | 8087 // Compare just the hashes first because it's faster. |
8100 int this_hash = MapsHashHelper(maps_, code_flags_); | 8088 int this_hash = MapsHashHelper(maps_, code_flags_); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8146 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8134 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8147 } | 8135 } |
8148 FixedArray* list = FixedArray::cast(obj); | 8136 FixedArray* list = FixedArray::cast(obj); |
8149 list->set(0, Smi::FromInt(code_flags_)); | 8137 list->set(0, Smi::FromInt(code_flags_)); |
8150 for (int i = 0; i < maps_->length(); ++i) { | 8138 for (int i = 0; i < maps_->length(); ++i) { |
8151 list->set(i + 1, *maps_->at(i)); | 8139 list->set(i + 1, *maps_->at(i)); |
8152 } | 8140 } |
8153 return list; | 8141 return list; |
8154 } | 8142 } |
8155 | 8143 |
| 8144 Handle<FixedArray> AsHandle() { |
| 8145 CALL_HEAP_FUNCTION(isolate_, |
| 8146 AsObject(isolate_->heap()), |
| 8147 FixedArray); |
| 8148 } |
| 8149 |
8156 private: | 8150 private: |
8157 static MapHandleList* FromObject(Object* obj, | 8151 static MapHandleList* FromObject(Object* obj, |
8158 int* code_flags, | 8152 int* code_flags, |
8159 MapHandleList* maps) { | 8153 MapHandleList* maps) { |
8160 FixedArray* list = FixedArray::cast(obj); | 8154 FixedArray* list = FixedArray::cast(obj); |
8161 maps->Rewind(0); | 8155 maps->Rewind(0); |
8162 *code_flags = Smi::cast(list->get(0))->value(); | 8156 *code_flags = Smi::cast(list->get(0))->value(); |
8163 for (int i = 1; i < list->length(); ++i) { | 8157 for (int i = 1; i < list->length(); ++i) { |
8164 maps->Add(Handle<Map>(Map::cast(list->get(i)))); | 8158 maps->Add(Handle<Map>(Map::cast(list->get(i)))); |
8165 } | 8159 } |
8166 return maps; | 8160 return maps; |
8167 } | 8161 } |
8168 | 8162 |
| 8163 Isolate* isolate_; |
8169 MapHandleList* maps_; // weak. | 8164 MapHandleList* maps_; // weak. |
8170 int code_flags_; | 8165 int code_flags_; |
8171 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; | 8166 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; |
8172 }; | 8167 }; |
8173 | 8168 |
8174 | 8169 |
8175 Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps, | 8170 Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps, |
8176 int code_flags) { | 8171 int code_kind) { |
8177 PolymorphicCodeCacheHashTableKey key(maps, code_flags); | 8172 DisallowHeapAllocation no_alloc; |
| 8173 PolymorphicCodeCacheHashTableKey key(GetIsolate(), maps, code_kind); |
8178 int entry = FindEntry(&key); | 8174 int entry = FindEntry(&key); |
8179 if (entry == kNotFound) return GetHeap()->undefined_value(); | 8175 if (entry == kNotFound) return GetHeap()->undefined_value(); |
8180 return get(EntryToIndex(entry) + 1); | 8176 return get(EntryToIndex(entry) + 1); |
8181 } | 8177 } |
8182 | 8178 |
8183 | 8179 |
8184 MaybeObject* PolymorphicCodeCacheHashTable::Put(MapHandleList* maps, | 8180 Handle<PolymorphicCodeCacheHashTable> PolymorphicCodeCacheHashTable::Put( |
8185 int code_flags, | 8181 Handle<PolymorphicCodeCacheHashTable> hash_table, |
8186 Code* code) { | 8182 MapHandleList* maps, |
8187 PolymorphicCodeCacheHashTableKey key(maps, code_flags); | 8183 int code_kind, |
8188 Object* obj; | 8184 Handle<Code> code) { |
8189 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 8185 PolymorphicCodeCacheHashTableKey key( |
8190 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8186 hash_table->GetIsolate(), maps, code_kind); |
8191 } | 8187 Handle<PolymorphicCodeCacheHashTable> cache = |
8192 PolymorphicCodeCacheHashTable* cache = | 8188 EnsureCapacity(hash_table, 1, &key); |
8193 reinterpret_cast<PolymorphicCodeCacheHashTable*>(obj); | |
8194 int entry = cache->FindInsertionEntry(key.Hash()); | 8189 int entry = cache->FindInsertionEntry(key.Hash()); |
8195 { MaybeObject* maybe_obj = key.AsObject(GetHeap()); | 8190 |
8196 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8191 Handle<FixedArray> obj = key.AsHandle(); |
8197 } | 8192 cache->set(EntryToIndex(entry), *obj); |
8198 cache->set(EntryToIndex(entry), obj); | 8193 cache->set(EntryToIndex(entry) + 1, *code); |
8199 cache->set(EntryToIndex(entry) + 1, code); | |
8200 cache->ElementAdded(); | 8194 cache->ElementAdded(); |
8201 return cache; | 8195 return cache; |
8202 } | 8196 } |
8203 | 8197 |
8204 | 8198 |
8205 void FixedArray::Shrink(int new_length) { | 8199 void FixedArray::Shrink(int new_length) { |
8206 ASSERT(0 <= new_length && new_length <= length()); | 8200 ASSERT(0 <= new_length && new_length <= length()); |
8207 if (new_length < length()) { | 8201 if (new_length < length()) { |
8208 RightTrimFixedArray<Heap::FROM_MUTATOR>( | 8202 RightTrimFixedArray<Heap::FROM_MUTATOR>( |
8209 GetHeap(), this, length() - new_length); | 8203 GetHeap(), this, length() - new_length); |
(...skipping 8901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17111 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17105 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17112 static const char* error_messages_[] = { | 17106 static const char* error_messages_[] = { |
17113 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17107 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17114 }; | 17108 }; |
17115 #undef ERROR_MESSAGES_TEXTS | 17109 #undef ERROR_MESSAGES_TEXTS |
17116 return error_messages_[reason]; | 17110 return error_messages_[reason]; |
17117 } | 17111 } |
17118 | 17112 |
17119 | 17113 |
17120 } } // namespace v8::internal | 17114 } } // namespace v8::internal |
OLD | NEW |