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 7943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7954 // is created using the flags and not a code object it can only be used for | 7954 // is created using the flags and not a code object it can only be used for |
7955 // lookup not to create a new entry. | 7955 // lookup not to create a new entry. |
7956 class CodeCacheHashTableKey : public HashTableKey { | 7956 class CodeCacheHashTableKey : public HashTableKey { |
7957 public: | 7957 public: |
7958 CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags) | 7958 CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags) |
7959 : name_(name), flags_(flags), code_() { } | 7959 : name_(name), flags_(flags), code_() { } |
7960 | 7960 |
7961 CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code) | 7961 CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code) |
7962 : name_(name), flags_(code->flags()), code_(code) { } | 7962 : name_(name), flags_(code->flags()), code_(code) { } |
7963 | 7963 |
7964 | 7964 bool IsMatch(Object* other) V8_OVERRIDE { |
7965 bool IsMatch(Object* other) { | |
7966 if (!other->IsFixedArray()) return false; | 7965 if (!other->IsFixedArray()) return false; |
7967 FixedArray* pair = FixedArray::cast(other); | 7966 FixedArray* pair = FixedArray::cast(other); |
7968 Name* name = Name::cast(pair->get(0)); | 7967 Name* name = Name::cast(pair->get(0)); |
7969 Code::Flags flags = Code::cast(pair->get(1))->flags(); | 7968 Code::Flags flags = Code::cast(pair->get(1))->flags(); |
7970 if (flags != flags_) { | 7969 if (flags != flags_) { |
7971 return false; | 7970 return false; |
7972 } | 7971 } |
7973 return name_->Equals(name); | 7972 return name_->Equals(name); |
7974 } | 7973 } |
7975 | 7974 |
7976 static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) { | 7975 static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) { |
7977 return name->Hash() ^ flags; | 7976 return name->Hash() ^ flags; |
7978 } | 7977 } |
7979 | 7978 |
7980 uint32_t Hash() { return NameFlagsHashHelper(*name_, flags_); } | 7979 uint32_t Hash() V8_OVERRIDE { return NameFlagsHashHelper(*name_, flags_); } |
7981 | 7980 |
7982 uint32_t HashForObject(Object* obj) { | 7981 uint32_t HashForObject(Object* obj) V8_OVERRIDE { |
7983 FixedArray* pair = FixedArray::cast(obj); | 7982 FixedArray* pair = FixedArray::cast(obj); |
7984 Name* name = Name::cast(pair->get(0)); | 7983 Name* name = Name::cast(pair->get(0)); |
7985 Code* code = Code::cast(pair->get(1)); | 7984 Code* code = Code::cast(pair->get(1)); |
7986 return NameFlagsHashHelper(name, code->flags()); | 7985 return NameFlagsHashHelper(name, code->flags()); |
7987 } | 7986 } |
7988 | 7987 |
7989 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { | 7988 MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
7990 Handle<Code> code = code_.ToHandleChecked(); | 7989 Handle<Code> code = code_.ToHandleChecked(); |
7991 Object* obj; | 7990 Handle<FixedArray> pair = isolate->factory()->NewFixedArray(2); |
7992 { MaybeObject* maybe_obj = heap->AllocateFixedArray(2); | |
7993 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
7994 } | |
7995 FixedArray* pair = FixedArray::cast(obj); | |
7996 pair->set(0, *name_); | 7991 pair->set(0, *name_); |
7997 pair->set(1, *code); | 7992 pair->set(1, *code); |
7998 return pair; | 7993 return pair; |
7999 } | 7994 } |
8000 | 7995 |
8001 Handle<FixedArray> AsHandle() { | |
8002 Isolate* isolate = name_->GetIsolate(); | |
8003 CALL_HEAP_FUNCTION(isolate, | |
8004 AsObject(isolate->heap()), | |
8005 FixedArray); | |
8006 } | |
8007 | |
8008 private: | 7996 private: |
8009 Handle<Name> name_; | 7997 Handle<Name> name_; |
8010 Code::Flags flags_; | 7998 Code::Flags flags_; |
8011 // TODO(jkummerow): We should be able to get by without this. | 7999 // TODO(jkummerow): We should be able to get by without this. |
8012 MaybeHandle<Code> code_; | 8000 MaybeHandle<Code> code_; |
8013 }; | 8001 }; |
8014 | 8002 |
8015 | 8003 |
8016 Object* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) { | 8004 Object* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) { |
8017 DisallowHeapAllocation no_alloc; | 8005 DisallowHeapAllocation no_alloc; |
8018 CodeCacheHashTableKey key(handle(name), flags); | 8006 CodeCacheHashTableKey key(handle(name), flags); |
8019 int entry = FindEntry(&key); | 8007 int entry = FindEntry(&key); |
8020 if (entry == kNotFound) return GetHeap()->undefined_value(); | 8008 if (entry == kNotFound) return GetHeap()->undefined_value(); |
8021 return get(EntryToIndex(entry) + 1); | 8009 return get(EntryToIndex(entry) + 1); |
8022 } | 8010 } |
8023 | 8011 |
8024 | 8012 |
8025 Handle<CodeCacheHashTable> CodeCacheHashTable::Put( | 8013 Handle<CodeCacheHashTable> CodeCacheHashTable::Put( |
8026 Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) { | 8014 Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) { |
8027 CodeCacheHashTableKey key(name, code); | 8015 CodeCacheHashTableKey key(name, code); |
8028 | 8016 |
8029 Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key); | 8017 Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key); |
8030 | 8018 |
8031 int entry = new_cache->FindInsertionEntry(key.Hash()); | 8019 int entry = new_cache->FindInsertionEntry(key.Hash()); |
8032 Handle<Object> k = key.AsHandle(); | 8020 Handle<Object> k = key.AsHandle(cache->GetIsolate()); |
8033 | 8021 |
8034 new_cache->set(EntryToIndex(entry), *k); | 8022 new_cache->set(EntryToIndex(entry), *k); |
8035 new_cache->set(EntryToIndex(entry) + 1, *code); | 8023 new_cache->set(EntryToIndex(entry) + 1, *code); |
8036 new_cache->ElementAdded(); | 8024 new_cache->ElementAdded(); |
8037 return new_cache; | 8025 return new_cache; |
8038 } | 8026 } |
8039 | 8027 |
8040 | 8028 |
8041 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { | 8029 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { |
8042 DisallowHeapAllocation no_alloc; | 8030 DisallowHeapAllocation no_alloc; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8090 } | 8078 } |
8091 } | 8079 } |
8092 | 8080 |
8093 | 8081 |
8094 // Despite their name, object of this class are not stored in the actual | 8082 // Despite their name, object of this class are not stored in the actual |
8095 // hash table; instead they're temporarily used for lookups. It is therefore | 8083 // hash table; instead they're temporarily used for lookups. It is therefore |
8096 // safe to have a weak (non-owning) pointer to a MapList as a member field. | 8084 // safe to have a weak (non-owning) pointer to a MapList as a member field. |
8097 class PolymorphicCodeCacheHashTableKey : public HashTableKey { | 8085 class PolymorphicCodeCacheHashTableKey : public HashTableKey { |
8098 public: | 8086 public: |
8099 // Callers must ensure that |maps| outlives the newly constructed object. | 8087 // Callers must ensure that |maps| outlives the newly constructed object. |
8100 PolymorphicCodeCacheHashTableKey( | 8088 PolymorphicCodeCacheHashTableKey(MapHandleList* maps, int code_flags) |
8101 Isolate* isolate, MapHandleList* maps, int code_flags) | 8089 : maps_(maps), |
8102 : isolate_(isolate), | |
8103 maps_(maps), | |
8104 code_flags_(code_flags) {} | 8090 code_flags_(code_flags) {} |
8105 | 8091 |
8106 bool IsMatch(Object* other) { | 8092 bool IsMatch(Object* other) V8_OVERRIDE { |
8107 MapHandleList other_maps(kDefaultListAllocationSize); | 8093 MapHandleList other_maps(kDefaultListAllocationSize); |
8108 int other_flags; | 8094 int other_flags; |
8109 FromObject(other, &other_flags, &other_maps); | 8095 FromObject(other, &other_flags, &other_maps); |
8110 if (code_flags_ != other_flags) return false; | 8096 if (code_flags_ != other_flags) return false; |
8111 if (maps_->length() != other_maps.length()) return false; | 8097 if (maps_->length() != other_maps.length()) return false; |
8112 // Compare just the hashes first because it's faster. | 8098 // Compare just the hashes first because it's faster. |
8113 int this_hash = MapsHashHelper(maps_, code_flags_); | 8099 int this_hash = MapsHashHelper(maps_, code_flags_); |
8114 int other_hash = MapsHashHelper(&other_maps, other_flags); | 8100 int other_hash = MapsHashHelper(&other_maps, other_flags); |
8115 if (this_hash != other_hash) return false; | 8101 if (this_hash != other_hash) return false; |
8116 | 8102 |
(...skipping 14 matching lines...) Expand all Loading... |
8131 } | 8117 } |
8132 | 8118 |
8133 static uint32_t MapsHashHelper(MapHandleList* maps, int code_flags) { | 8119 static uint32_t MapsHashHelper(MapHandleList* maps, int code_flags) { |
8134 uint32_t hash = code_flags; | 8120 uint32_t hash = code_flags; |
8135 for (int i = 0; i < maps->length(); ++i) { | 8121 for (int i = 0; i < maps->length(); ++i) { |
8136 hash ^= maps->at(i)->Hash(); | 8122 hash ^= maps->at(i)->Hash(); |
8137 } | 8123 } |
8138 return hash; | 8124 return hash; |
8139 } | 8125 } |
8140 | 8126 |
8141 uint32_t Hash() { | 8127 uint32_t Hash() V8_OVERRIDE { |
8142 return MapsHashHelper(maps_, code_flags_); | 8128 return MapsHashHelper(maps_, code_flags_); |
8143 } | 8129 } |
8144 | 8130 |
8145 uint32_t HashForObject(Object* obj) { | 8131 uint32_t HashForObject(Object* obj) V8_OVERRIDE { |
8146 MapHandleList other_maps(kDefaultListAllocationSize); | 8132 MapHandleList other_maps(kDefaultListAllocationSize); |
8147 int other_flags; | 8133 int other_flags; |
8148 FromObject(obj, &other_flags, &other_maps); | 8134 FromObject(obj, &other_flags, &other_maps); |
8149 return MapsHashHelper(&other_maps, other_flags); | 8135 return MapsHashHelper(&other_maps, other_flags); |
8150 } | 8136 } |
8151 | 8137 |
8152 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { | 8138 MUST_USE_RESULT Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
8153 Object* obj; | |
8154 // The maps in |maps_| must be copied to a newly allocated FixedArray, | 8139 // The maps in |maps_| must be copied to a newly allocated FixedArray, |
8155 // both because the referenced MapList is short-lived, and because C++ | 8140 // both because the referenced MapList is short-lived, and because C++ |
8156 // objects can't be stored in the heap anyway. | 8141 // objects can't be stored in the heap anyway. |
8157 { MaybeObject* maybe_obj = | 8142 Handle<FixedArray> list = |
8158 heap->AllocateUninitializedFixedArray(maps_->length() + 1); | 8143 isolate->factory()->NewUninitializedFixedArray(maps_->length() + 1); |
8159 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
8160 } | |
8161 FixedArray* list = FixedArray::cast(obj); | |
8162 list->set(0, Smi::FromInt(code_flags_)); | 8144 list->set(0, Smi::FromInt(code_flags_)); |
8163 for (int i = 0; i < maps_->length(); ++i) { | 8145 for (int i = 0; i < maps_->length(); ++i) { |
8164 list->set(i + 1, *maps_->at(i)); | 8146 list->set(i + 1, *maps_->at(i)); |
8165 } | 8147 } |
8166 return list; | 8148 return list; |
8167 } | 8149 } |
8168 | 8150 |
8169 Handle<FixedArray> AsHandle() { | |
8170 CALL_HEAP_FUNCTION(isolate_, | |
8171 AsObject(isolate_->heap()), | |
8172 FixedArray); | |
8173 } | |
8174 | |
8175 private: | 8151 private: |
8176 static MapHandleList* FromObject(Object* obj, | 8152 static MapHandleList* FromObject(Object* obj, |
8177 int* code_flags, | 8153 int* code_flags, |
8178 MapHandleList* maps) { | 8154 MapHandleList* maps) { |
8179 FixedArray* list = FixedArray::cast(obj); | 8155 FixedArray* list = FixedArray::cast(obj); |
8180 maps->Rewind(0); | 8156 maps->Rewind(0); |
8181 *code_flags = Smi::cast(list->get(0))->value(); | 8157 *code_flags = Smi::cast(list->get(0))->value(); |
8182 for (int i = 1; i < list->length(); ++i) { | 8158 for (int i = 1; i < list->length(); ++i) { |
8183 maps->Add(Handle<Map>(Map::cast(list->get(i)))); | 8159 maps->Add(Handle<Map>(Map::cast(list->get(i)))); |
8184 } | 8160 } |
8185 return maps; | 8161 return maps; |
8186 } | 8162 } |
8187 | 8163 |
8188 Isolate* isolate_; | |
8189 MapHandleList* maps_; // weak. | 8164 MapHandleList* maps_; // weak. |
8190 int code_flags_; | 8165 int code_flags_; |
8191 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; | 8166 static const int kDefaultListAllocationSize = kMaxKeyedPolymorphism + 1; |
8192 }; | 8167 }; |
8193 | 8168 |
8194 | 8169 |
8195 Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps, | 8170 Object* PolymorphicCodeCacheHashTable::Lookup(MapHandleList* maps, |
8196 int code_kind) { | 8171 int code_kind) { |
8197 DisallowHeapAllocation no_alloc; | 8172 DisallowHeapAllocation no_alloc; |
8198 PolymorphicCodeCacheHashTableKey key(GetIsolate(), maps, code_kind); | 8173 PolymorphicCodeCacheHashTableKey key(maps, code_kind); |
8199 int entry = FindEntry(&key); | 8174 int entry = FindEntry(&key); |
8200 if (entry == kNotFound) return GetHeap()->undefined_value(); | 8175 if (entry == kNotFound) return GetHeap()->undefined_value(); |
8201 return get(EntryToIndex(entry) + 1); | 8176 return get(EntryToIndex(entry) + 1); |
8202 } | 8177 } |
8203 | 8178 |
8204 | 8179 |
8205 Handle<PolymorphicCodeCacheHashTable> PolymorphicCodeCacheHashTable::Put( | 8180 Handle<PolymorphicCodeCacheHashTable> PolymorphicCodeCacheHashTable::Put( |
8206 Handle<PolymorphicCodeCacheHashTable> hash_table, | 8181 Handle<PolymorphicCodeCacheHashTable> hash_table, |
8207 MapHandleList* maps, | 8182 MapHandleList* maps, |
8208 int code_kind, | 8183 int code_kind, |
8209 Handle<Code> code) { | 8184 Handle<Code> code) { |
8210 PolymorphicCodeCacheHashTableKey key( | 8185 PolymorphicCodeCacheHashTableKey key(maps, code_kind); |
8211 hash_table->GetIsolate(), maps, code_kind); | |
8212 Handle<PolymorphicCodeCacheHashTable> cache = | 8186 Handle<PolymorphicCodeCacheHashTable> cache = |
8213 EnsureCapacity(hash_table, 1, &key); | 8187 EnsureCapacity(hash_table, 1, &key); |
8214 int entry = cache->FindInsertionEntry(key.Hash()); | 8188 int entry = cache->FindInsertionEntry(key.Hash()); |
8215 | 8189 |
8216 Handle<FixedArray> obj = key.AsHandle(); | 8190 Handle<Object> obj = key.AsHandle(hash_table->GetIsolate()); |
8217 cache->set(EntryToIndex(entry), *obj); | 8191 cache->set(EntryToIndex(entry), *obj); |
8218 cache->set(EntryToIndex(entry) + 1, *code); | 8192 cache->set(EntryToIndex(entry) + 1, *code); |
8219 cache->ElementAdded(); | 8193 cache->ElementAdded(); |
8220 return cache; | 8194 return cache; |
8221 } | 8195 } |
8222 | 8196 |
8223 | 8197 |
8224 void FixedArray::Shrink(int new_length) { | 8198 void FixedArray::Shrink(int new_length) { |
8225 ASSERT(0 <= new_length && new_length <= length()); | 8199 ASSERT(0 <= new_length && new_length <= length()); |
8226 if (new_length < length()) { | 8200 if (new_length < length()) { |
(...skipping 6121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14348 public: | 14322 public: |
14349 StringSharedKey(Handle<String> source, | 14323 StringSharedKey(Handle<String> source, |
14350 Handle<SharedFunctionInfo> shared, | 14324 Handle<SharedFunctionInfo> shared, |
14351 StrictMode strict_mode, | 14325 StrictMode strict_mode, |
14352 int scope_position) | 14326 int scope_position) |
14353 : source_(source), | 14327 : source_(source), |
14354 shared_(shared), | 14328 shared_(shared), |
14355 strict_mode_(strict_mode), | 14329 strict_mode_(strict_mode), |
14356 scope_position_(scope_position) { } | 14330 scope_position_(scope_position) { } |
14357 | 14331 |
14358 bool IsMatch(Object* other) { | 14332 bool IsMatch(Object* other) V8_OVERRIDE { |
14359 DisallowHeapAllocation no_allocation; | 14333 DisallowHeapAllocation no_allocation; |
14360 if (!other->IsFixedArray()) return false; | 14334 if (!other->IsFixedArray()) return false; |
14361 FixedArray* other_array = FixedArray::cast(other); | 14335 FixedArray* other_array = FixedArray::cast(other); |
14362 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 14336 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
14363 if (shared != *shared_) return false; | 14337 if (shared != *shared_) return false; |
14364 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 14338 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
14365 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 14339 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
14366 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 14340 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
14367 if (strict_mode != strict_mode_) return false; | 14341 if (strict_mode != strict_mode_) return false; |
14368 int scope_position = Smi::cast(other_array->get(3))->value(); | 14342 int scope_position = Smi::cast(other_array->get(3))->value(); |
(...skipping 14 matching lines...) Expand all Loading... |
14383 // We do this to ensure that the cache entries can survive garbage | 14357 // We do this to ensure that the cache entries can survive garbage |
14384 // collection. | 14358 // collection. |
14385 Script* script(Script::cast(shared->script())); | 14359 Script* script(Script::cast(shared->script())); |
14386 hash ^= String::cast(script->source())->Hash(); | 14360 hash ^= String::cast(script->source())->Hash(); |
14387 if (strict_mode == STRICT) hash ^= 0x8000; | 14361 if (strict_mode == STRICT) hash ^= 0x8000; |
14388 hash += scope_position; | 14362 hash += scope_position; |
14389 } | 14363 } |
14390 return hash; | 14364 return hash; |
14391 } | 14365 } |
14392 | 14366 |
14393 uint32_t Hash() { | 14367 uint32_t Hash() V8_OVERRIDE { |
14394 return StringSharedHashHelper(*source_, *shared_, strict_mode_, | 14368 return StringSharedHashHelper(*source_, *shared_, strict_mode_, |
14395 scope_position_); | 14369 scope_position_); |
14396 } | 14370 } |
14397 | 14371 |
14398 uint32_t HashForObject(Object* obj) { | 14372 uint32_t HashForObject(Object* obj) V8_OVERRIDE { |
14399 DisallowHeapAllocation no_allocation; | 14373 DisallowHeapAllocation no_allocation; |
14400 FixedArray* other_array = FixedArray::cast(obj); | 14374 FixedArray* other_array = FixedArray::cast(obj); |
14401 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 14375 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
14402 String* source = String::cast(other_array->get(1)); | 14376 String* source = String::cast(other_array->get(1)); |
14403 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 14377 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
14404 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 14378 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
14405 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 14379 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
14406 int scope_position = Smi::cast(other_array->get(3))->value(); | 14380 int scope_position = Smi::cast(other_array->get(3))->value(); |
14407 return StringSharedHashHelper( | 14381 return StringSharedHashHelper( |
14408 source, shared, strict_mode, scope_position); | 14382 source, shared, strict_mode, scope_position); |
14409 } | 14383 } |
14410 | 14384 |
14411 | 14385 |
14412 Object* AsObject(Heap* heap) { | 14386 Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
14413 UNREACHABLE(); | 14387 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); |
14414 return NULL; | |
14415 } | |
14416 | |
14417 | |
14418 Handle<Object> AsObject(Factory* factory) { | |
14419 Handle<FixedArray> array = factory->NewFixedArray(4); | |
14420 array->set(0, *shared_); | 14388 array->set(0, *shared_); |
14421 array->set(1, *source_); | 14389 array->set(1, *source_); |
14422 array->set(2, Smi::FromInt(strict_mode_)); | 14390 array->set(2, Smi::FromInt(strict_mode_)); |
14423 array->set(3, Smi::FromInt(scope_position_)); | 14391 array->set(3, Smi::FromInt(scope_position_)); |
14424 return array; | 14392 return array; |
14425 } | 14393 } |
14426 | 14394 |
14427 private: | 14395 private: |
14428 Handle<String> source_; | 14396 Handle<String> source_; |
14429 Handle<SharedFunctionInfo> shared_; | 14397 Handle<SharedFunctionInfo> shared_; |
14430 StrictMode strict_mode_; | 14398 StrictMode strict_mode_; |
14431 int scope_position_; | 14399 int scope_position_; |
14432 }; | 14400 }; |
14433 | 14401 |
14434 | 14402 |
14435 // RegExpKey carries the source and flags of a regular expression as key. | 14403 // RegExpKey carries the source and flags of a regular expression as key. |
14436 class RegExpKey : public HashTableKey { | 14404 class RegExpKey : public HashTableKey { |
14437 public: | 14405 public: |
14438 RegExpKey(Handle<String> string, JSRegExp::Flags flags) | 14406 RegExpKey(Handle<String> string, JSRegExp::Flags flags) |
14439 : string_(string), | 14407 : string_(string), |
14440 flags_(Smi::FromInt(flags.value())) { } | 14408 flags_(Smi::FromInt(flags.value())) { } |
14441 | 14409 |
14442 // Rather than storing the key in the hash table, a pointer to the | 14410 // Rather than storing the key in the hash table, a pointer to the |
14443 // stored value is stored where the key should be. IsMatch then | 14411 // stored value is stored where the key should be. IsMatch then |
14444 // compares the search key to the found object, rather than comparing | 14412 // compares the search key to the found object, rather than comparing |
14445 // a key to a key. | 14413 // a key to a key. |
14446 bool IsMatch(Object* obj) { | 14414 bool IsMatch(Object* obj) V8_OVERRIDE { |
14447 FixedArray* val = FixedArray::cast(obj); | 14415 FixedArray* val = FixedArray::cast(obj); |
14448 return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex))) | 14416 return string_->Equals(String::cast(val->get(JSRegExp::kSourceIndex))) |
14449 && (flags_ == val->get(JSRegExp::kFlagsIndex)); | 14417 && (flags_ == val->get(JSRegExp::kFlagsIndex)); |
14450 } | 14418 } |
14451 | 14419 |
14452 uint32_t Hash() { return RegExpHash(*string_, flags_); } | 14420 uint32_t Hash() V8_OVERRIDE { return RegExpHash(*string_, flags_); } |
14453 | 14421 |
14454 Object* AsObject(Heap* heap) { | 14422 Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
14455 // Plain hash maps, which is where regexp keys are used, don't | 14423 // Plain hash maps, which is where regexp keys are used, don't |
14456 // use this function. | 14424 // use this function. |
14457 UNREACHABLE(); | 14425 UNREACHABLE(); |
14458 return NULL; | 14426 return MaybeHandle<Object>().ToHandleChecked(); |
14459 } | 14427 } |
14460 | 14428 |
14461 uint32_t HashForObject(Object* obj) { | 14429 uint32_t HashForObject(Object* obj) V8_OVERRIDE { |
14462 FixedArray* val = FixedArray::cast(obj); | 14430 FixedArray* val = FixedArray::cast(obj); |
14463 return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)), | 14431 return RegExpHash(String::cast(val->get(JSRegExp::kSourceIndex)), |
14464 Smi::cast(val->get(JSRegExp::kFlagsIndex))); | 14432 Smi::cast(val->get(JSRegExp::kFlagsIndex))); |
14465 } | 14433 } |
14466 | 14434 |
14467 static uint32_t RegExpHash(String* string, Smi* flags) { | 14435 static uint32_t RegExpHash(String* string, Smi* flags) { |
14468 return string->Hash() + flags->value(); | 14436 return string->Hash() + flags->value(); |
14469 } | 14437 } |
14470 | 14438 |
14471 Handle<String> string_; | 14439 Handle<String> string_; |
14472 Smi* flags_; | 14440 Smi* flags_; |
14473 }; | 14441 }; |
14474 | 14442 |
14475 | 14443 |
14476 MaybeObject* OneByteStringKey::AsObject(Heap* heap) { | 14444 Handle<Object> OneByteStringKey::AsHandle(Isolate* isolate) { |
14477 if (hash_field_ == 0) Hash(); | 14445 if (hash_field_ == 0) Hash(); |
14478 return heap->AllocateOneByteInternalizedString(string_, hash_field_); | 14446 return isolate->factory()->NewOneByteInternalizedString(string_, hash_field_); |
14479 } | 14447 } |
14480 | 14448 |
14481 | 14449 |
14482 MaybeObject* TwoByteStringKey::AsObject(Heap* heap) { | 14450 Handle<Object> TwoByteStringKey::AsHandle(Isolate* isolate) { |
14483 if (hash_field_ == 0) Hash(); | 14451 if (hash_field_ == 0) Hash(); |
14484 return heap->AllocateTwoByteInternalizedString(string_, hash_field_); | 14452 return isolate->factory()->NewTwoByteInternalizedString(string_, hash_field_); |
14485 } | 14453 } |
14486 | 14454 |
14487 | 14455 |
14488 template<> | 14456 template<> |
14489 const uint8_t* SubStringKey<uint8_t>::GetChars() { | 14457 const uint8_t* SubStringKey<uint8_t>::GetChars() { |
14490 return string_->IsSeqOneByteString() | 14458 return string_->IsSeqOneByteString() |
14491 ? SeqOneByteString::cast(*string_)->GetChars() | 14459 ? SeqOneByteString::cast(*string_)->GetChars() |
14492 : ExternalAsciiString::cast(*string_)->GetChars(); | 14460 : ExternalAsciiString::cast(*string_)->GetChars(); |
14493 } | 14461 } |
14494 | 14462 |
14495 | 14463 |
14496 template<> | 14464 template<> |
14497 const uint16_t* SubStringKey<uint16_t>::GetChars() { | 14465 const uint16_t* SubStringKey<uint16_t>::GetChars() { |
14498 return string_->IsSeqTwoByteString() | 14466 return string_->IsSeqTwoByteString() |
14499 ? SeqTwoByteString::cast(*string_)->GetChars() | 14467 ? SeqTwoByteString::cast(*string_)->GetChars() |
14500 : ExternalTwoByteString::cast(*string_)->GetChars(); | 14468 : ExternalTwoByteString::cast(*string_)->GetChars(); |
14501 } | 14469 } |
14502 | 14470 |
14503 | 14471 |
14504 template<> | 14472 template<> |
14505 MaybeObject* SubStringKey<uint8_t>::AsObject(Heap* heap) { | 14473 Handle<Object> SubStringKey<uint8_t>::AsHandle(Isolate* isolate) { |
14506 if (hash_field_ == 0) Hash(); | 14474 if (hash_field_ == 0) Hash(); |
14507 Vector<const uint8_t> chars(GetChars() + from_, length_); | 14475 Vector<const uint8_t> chars(GetChars() + from_, length_); |
14508 return heap->AllocateOneByteInternalizedString(chars, hash_field_); | 14476 return isolate->factory()->NewOneByteInternalizedString(chars, hash_field_); |
14509 } | 14477 } |
14510 | 14478 |
14511 | 14479 |
14512 template<> | 14480 template<> |
14513 MaybeObject* SubStringKey<uint16_t>::AsObject( | 14481 Handle<Object> SubStringKey<uint16_t>::AsHandle(Isolate* isolate) { |
14514 Heap* heap) { | |
14515 if (hash_field_ == 0) Hash(); | 14482 if (hash_field_ == 0) Hash(); |
14516 Vector<const uint16_t> chars(GetChars() + from_, length_); | 14483 Vector<const uint16_t> chars(GetChars() + from_, length_); |
14517 return heap->AllocateTwoByteInternalizedString(chars, hash_field_); | 14484 return isolate->factory()->NewTwoByteInternalizedString(chars, hash_field_); |
14518 } | 14485 } |
14519 | 14486 |
14520 | 14487 |
14521 template<> | 14488 template<> |
14522 bool SubStringKey<uint8_t>::IsMatch(Object* string) { | 14489 bool SubStringKey<uint8_t>::IsMatch(Object* string) { |
14523 Vector<const uint8_t> chars(GetChars() + from_, length_); | 14490 Vector<const uint8_t> chars(GetChars() + from_, length_); |
14524 return String::cast(string)->IsOneByteEqualTo(chars); | 14491 return String::cast(string)->IsOneByteEqualTo(chars); |
14525 } | 14492 } |
14526 | 14493 |
14527 | 14494 |
(...skipping 17 matching lines...) Expand all Loading... |
14545 virtual bool IsMatch(Object* string) V8_OVERRIDE { | 14512 virtual bool IsMatch(Object* string) V8_OVERRIDE { |
14546 return String::cast(string)->Equals(*string_); | 14513 return String::cast(string)->Equals(*string_); |
14547 } | 14514 } |
14548 | 14515 |
14549 virtual uint32_t Hash() V8_OVERRIDE { return string_->Hash(); } | 14516 virtual uint32_t Hash() V8_OVERRIDE { return string_->Hash(); } |
14550 | 14517 |
14551 virtual uint32_t HashForObject(Object* other) V8_OVERRIDE { | 14518 virtual uint32_t HashForObject(Object* other) V8_OVERRIDE { |
14552 return String::cast(other)->Hash(); | 14519 return String::cast(other)->Hash(); |
14553 } | 14520 } |
14554 | 14521 |
14555 virtual MaybeObject* AsObject(Heap* heap) V8_OVERRIDE { | 14522 virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
14556 // Internalize the string if possible. | 14523 // Internalize the string if possible. |
14557 Map* map = heap->InternalizedStringMapForString(*string_); | 14524 MaybeHandle<Map> maybe_map = |
14558 if (map != NULL) { | 14525 isolate->factory()->InternalizedStringMapForString(string_); |
14559 string_->set_map_no_write_barrier(map); | 14526 Handle<Map> map; |
| 14527 if (maybe_map.ToHandle(&map)) { |
| 14528 string_->set_map_no_write_barrier(*map); |
14560 ASSERT(string_->IsInternalizedString()); | 14529 ASSERT(string_->IsInternalizedString()); |
14561 return *string_; | 14530 return string_; |
14562 } | 14531 } |
14563 // Otherwise allocate a new internalized string. | 14532 // Otherwise allocate a new internalized string. |
14564 return heap->AllocateInternalizedStringImpl( | 14533 return isolate->factory()->NewInternalizedStringImpl( |
14565 *string_, string_->length(), string_->hash_field()); | 14534 *string_, string_->length(), string_->hash_field()); |
14566 } | 14535 } |
14567 | 14536 |
14568 static uint32_t StringHash(Object* obj) { | 14537 static uint32_t StringHash(Object* obj) { |
14569 return String::cast(obj)->Hash(); | 14538 return String::cast(obj)->Hash(); |
14570 } | 14539 } |
14571 | 14540 |
14572 Handle<String> string_; | 14541 Handle<String> string_; |
14573 }; | 14542 }; |
14574 | 14543 |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15480 // version of the string hashing algorithm above. One reason could be | 15449 // version of the string hashing algorithm above. One reason could be |
15481 // that we were passed two digits as characters, since the hash | 15450 // that we were passed two digits as characters, since the hash |
15482 // algorithm is different in that case. | 15451 // algorithm is different in that case. |
15483 uint16_t chars[2] = {c1, c2}; | 15452 uint16_t chars[2] = {c1, c2}; |
15484 uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed); | 15453 uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed); |
15485 hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask; | 15454 hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask; |
15486 ASSERT_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash)); | 15455 ASSERT_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash)); |
15487 #endif | 15456 #endif |
15488 } | 15457 } |
15489 | 15458 |
15490 bool IsMatch(Object* o) { | 15459 bool IsMatch(Object* o) V8_OVERRIDE { |
15491 if (!o->IsString()) return false; | 15460 if (!o->IsString()) return false; |
15492 String* other = String::cast(o); | 15461 String* other = String::cast(o); |
15493 if (other->length() != 2) return false; | 15462 if (other->length() != 2) return false; |
15494 if (other->Get(0) != c1_) return false; | 15463 if (other->Get(0) != c1_) return false; |
15495 return other->Get(1) == c2_; | 15464 return other->Get(1) == c2_; |
15496 } | 15465 } |
15497 | 15466 |
15498 uint32_t Hash() { return hash_; } | 15467 uint32_t Hash() V8_OVERRIDE { return hash_; } |
15499 uint32_t HashForObject(Object* key) { | 15468 uint32_t HashForObject(Object* key) V8_OVERRIDE { |
15500 if (!key->IsString()) return 0; | 15469 if (!key->IsString()) return 0; |
15501 return String::cast(key)->Hash(); | 15470 return String::cast(key)->Hash(); |
15502 } | 15471 } |
15503 | 15472 |
15504 Object* AsObject(Heap* heap) { | 15473 Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
15505 // The TwoCharHashTableKey is only used for looking in the string | 15474 // The TwoCharHashTableKey is only used for looking in the string |
15506 // table, not for adding to it. | 15475 // table, not for adding to it. |
15507 UNREACHABLE(); | 15476 UNREACHABLE(); |
15508 return NULL; | 15477 return MaybeHandle<Object>().ToHandleChecked(); |
15509 } | 15478 } |
15510 | 15479 |
15511 private: | 15480 private: |
15512 uint16_t c1_; | 15481 uint16_t c1_; |
15513 uint16_t c2_; | 15482 uint16_t c2_; |
15514 uint32_t hash_; | 15483 uint32_t hash_; |
15515 }; | 15484 }; |
15516 | 15485 |
15517 | 15486 |
15518 bool StringTable::LookupStringIfExists(String* string, String** result) { | 15487 bool StringTable::LookupStringIfExists(String* string, String** result) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15620 | 15589 |
15621 | 15590 |
15622 Handle<CompilationCacheTable> CompilationCacheTable::Put( | 15591 Handle<CompilationCacheTable> CompilationCacheTable::Put( |
15623 Handle<CompilationCacheTable> cache, Handle<String> src, | 15592 Handle<CompilationCacheTable> cache, Handle<String> src, |
15624 Handle<Context> context, Handle<Object> value) { | 15593 Handle<Context> context, Handle<Object> value) { |
15625 Isolate* isolate = cache->GetIsolate(); | 15594 Isolate* isolate = cache->GetIsolate(); |
15626 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 15595 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
15627 StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, | 15596 StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, |
15628 RelocInfo::kNoPosition); | 15597 RelocInfo::kNoPosition); |
15629 cache = EnsureCapacity(cache, 1, &key); | 15598 cache = EnsureCapacity(cache, 1, &key); |
15630 Handle<Object> k = key.AsObject(isolate->factory()); | 15599 Handle<Object> k = key.AsHandle(isolate); |
15631 int entry = cache->FindInsertionEntry(key.Hash()); | 15600 int entry = cache->FindInsertionEntry(key.Hash()); |
15632 cache->set(EntryToIndex(entry), *k); | 15601 cache->set(EntryToIndex(entry), *k); |
15633 cache->set(EntryToIndex(entry) + 1, *value); | 15602 cache->set(EntryToIndex(entry) + 1, *value); |
15634 cache->ElementAdded(); | 15603 cache->ElementAdded(); |
15635 return cache; | 15604 return cache; |
15636 } | 15605 } |
15637 | 15606 |
15638 | 15607 |
15639 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( | 15608 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( |
15640 Handle<CompilationCacheTable> cache, Handle<String> src, | 15609 Handle<CompilationCacheTable> cache, Handle<String> src, |
15641 Handle<Context> context, Handle<SharedFunctionInfo> value, | 15610 Handle<Context> context, Handle<SharedFunctionInfo> value, |
15642 int scope_position) { | 15611 int scope_position) { |
15643 Isolate* isolate = cache->GetIsolate(); | 15612 Isolate* isolate = cache->GetIsolate(); |
15644 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 15613 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
15645 StringSharedKey key(src, shared, value->strict_mode(), scope_position); | 15614 StringSharedKey key(src, shared, value->strict_mode(), scope_position); |
15646 cache = EnsureCapacity(cache, 1, &key); | 15615 cache = EnsureCapacity(cache, 1, &key); |
15647 Handle<Object> k = key.AsObject(isolate->factory()); | 15616 Handle<Object> k = key.AsHandle(isolate); |
15648 int entry = cache->FindInsertionEntry(key.Hash()); | 15617 int entry = cache->FindInsertionEntry(key.Hash()); |
15649 cache->set(EntryToIndex(entry), *k); | 15618 cache->set(EntryToIndex(entry), *k); |
15650 cache->set(EntryToIndex(entry) + 1, *value); | 15619 cache->set(EntryToIndex(entry) + 1, *value); |
15651 cache->ElementAdded(); | 15620 cache->ElementAdded(); |
15652 return cache; | 15621 return cache; |
15653 } | 15622 } |
15654 | 15623 |
15655 | 15624 |
15656 Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp( | 15625 Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp( |
15657 Handle<CompilationCacheTable> cache, Handle<String> src, | 15626 Handle<CompilationCacheTable> cache, Handle<String> src, |
(...skipping 24 matching lines...) Expand all Loading... |
15682 } | 15651 } |
15683 return; | 15652 return; |
15684 } | 15653 } |
15685 | 15654 |
15686 | 15655 |
15687 // StringsKey used for HashTable where key is array of internalized strings. | 15656 // StringsKey used for HashTable where key is array of internalized strings. |
15688 class StringsKey : public HashTableKey { | 15657 class StringsKey : public HashTableKey { |
15689 public: | 15658 public: |
15690 explicit StringsKey(Handle<FixedArray> strings) : strings_(strings) { } | 15659 explicit StringsKey(Handle<FixedArray> strings) : strings_(strings) { } |
15691 | 15660 |
15692 bool IsMatch(Object* strings) { | 15661 bool IsMatch(Object* strings) V8_OVERRIDE { |
15693 FixedArray* o = FixedArray::cast(strings); | 15662 FixedArray* o = FixedArray::cast(strings); |
15694 int len = strings_->length(); | 15663 int len = strings_->length(); |
15695 if (o->length() != len) return false; | 15664 if (o->length() != len) return false; |
15696 for (int i = 0; i < len; i++) { | 15665 for (int i = 0; i < len; i++) { |
15697 if (o->get(i) != strings_->get(i)) return false; | 15666 if (o->get(i) != strings_->get(i)) return false; |
15698 } | 15667 } |
15699 return true; | 15668 return true; |
15700 } | 15669 } |
15701 | 15670 |
15702 uint32_t Hash() { return HashForObject(*strings_); } | 15671 uint32_t Hash() V8_OVERRIDE { return HashForObject(*strings_); } |
15703 | 15672 |
15704 uint32_t HashForObject(Object* obj) { | 15673 uint32_t HashForObject(Object* obj) V8_OVERRIDE { |
15705 FixedArray* strings = FixedArray::cast(obj); | 15674 FixedArray* strings = FixedArray::cast(obj); |
15706 int len = strings->length(); | 15675 int len = strings->length(); |
15707 uint32_t hash = 0; | 15676 uint32_t hash = 0; |
15708 for (int i = 0; i < len; i++) { | 15677 for (int i = 0; i < len; i++) { |
15709 hash ^= String::cast(strings->get(i))->Hash(); | 15678 hash ^= String::cast(strings->get(i))->Hash(); |
15710 } | 15679 } |
15711 return hash; | 15680 return hash; |
15712 } | 15681 } |
15713 | 15682 |
15714 Object* AsObject(Heap* heap) { return *strings_; } | 15683 Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { return strings_; } |
15715 | 15684 |
15716 private: | 15685 private: |
15717 Handle<FixedArray> strings_; | 15686 Handle<FixedArray> strings_; |
15718 }; | 15687 }; |
15719 | 15688 |
15720 | 15689 |
15721 Object* MapCache::Lookup(FixedArray* array) { | 15690 Object* MapCache::Lookup(FixedArray* array) { |
15722 DisallowHeapAllocation no_alloc; | 15691 DisallowHeapAllocation no_alloc; |
15723 StringsKey key(handle(array)); | 15692 StringsKey key(handle(array)); |
15724 int entry = FindEntry(&key); | 15693 int entry = FindEntry(&key); |
(...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17338 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17307 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17339 static const char* error_messages_[] = { | 17308 static const char* error_messages_[] = { |
17340 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17309 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17341 }; | 17310 }; |
17342 #undef ERROR_MESSAGES_TEXTS | 17311 #undef ERROR_MESSAGES_TEXTS |
17343 return error_messages_[reason]; | 17312 return error_messages_[reason]; |
17344 } | 17313 } |
17345 | 17314 |
17346 | 17315 |
17347 } } // namespace v8::internal | 17316 } } // namespace v8::internal |
OLD | NEW |