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 13667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13678 Object* AsObject(Heap* heap) { return string_; } | 13678 Object* AsObject(Heap* heap) { return string_; } |
13679 | 13679 |
13680 String* string_; | 13680 String* string_; |
13681 uint32_t hash_; | 13681 uint32_t hash_; |
13682 }; | 13682 }; |
13683 | 13683 |
13684 | 13684 |
13685 // StringSharedKeys are used as keys in the eval cache. | 13685 // StringSharedKeys are used as keys in the eval cache. |
13686 class StringSharedKey : public HashTableKey { | 13686 class StringSharedKey : public HashTableKey { |
13687 public: | 13687 public: |
13688 StringSharedKey(String* source, | 13688 StringSharedKey(Handle<String> source, |
13689 SharedFunctionInfo* shared, | 13689 Handle<SharedFunctionInfo> shared, |
13690 StrictMode strict_mode, | 13690 StrictMode strict_mode, |
13691 int scope_position) | 13691 int scope_position) |
13692 : source_(source), | 13692 : source_(source), |
13693 shared_(shared), | 13693 shared_(shared), |
13694 strict_mode_(strict_mode), | 13694 strict_mode_(strict_mode), |
13695 scope_position_(scope_position) { } | 13695 scope_position_(scope_position) { } |
13696 | 13696 |
13697 bool IsMatch(Object* other) { | 13697 bool IsMatch(Object* other) { |
| 13698 DisallowHeapAllocation no_allocation; |
13698 if (!other->IsFixedArray()) return false; | 13699 if (!other->IsFixedArray()) return false; |
13699 FixedArray* other_array = FixedArray::cast(other); | 13700 FixedArray* other_array = FixedArray::cast(other); |
13700 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 13701 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
13701 if (shared != shared_) return false; | 13702 if (shared != *shared_) return false; |
13702 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 13703 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
13703 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 13704 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
13704 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 13705 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
13705 if (strict_mode != strict_mode_) return false; | 13706 if (strict_mode != strict_mode_) return false; |
13706 int scope_position = Smi::cast(other_array->get(3))->value(); | 13707 int scope_position = Smi::cast(other_array->get(3))->value(); |
13707 if (scope_position != scope_position_) return false; | 13708 if (scope_position != scope_position_) return false; |
13708 String* source = String::cast(other_array->get(1)); | 13709 String* source = String::cast(other_array->get(1)); |
13709 return source->Equals(source_); | 13710 return source->Equals(*source_); |
13710 } | 13711 } |
13711 | 13712 |
13712 static uint32_t StringSharedHashHelper(String* source, | 13713 static uint32_t StringSharedHashHelper(String* source, |
13713 SharedFunctionInfo* shared, | 13714 SharedFunctionInfo* shared, |
13714 StrictMode strict_mode, | 13715 StrictMode strict_mode, |
13715 int scope_position) { | 13716 int scope_position) { |
13716 uint32_t hash = source->Hash(); | 13717 uint32_t hash = source->Hash(); |
13717 if (shared->HasSourceCode()) { | 13718 if (shared->HasSourceCode()) { |
13718 // Instead of using the SharedFunctionInfo pointer in the hash | 13719 // Instead of using the SharedFunctionInfo pointer in the hash |
13719 // code computation, we use a combination of the hash of the | 13720 // code computation, we use a combination of the hash of the |
13720 // script source code and the start position of the calling scope. | 13721 // script source code and the start position of the calling scope. |
13721 // We do this to ensure that the cache entries can survive garbage | 13722 // We do this to ensure that the cache entries can survive garbage |
13722 // collection. | 13723 // collection. |
13723 Script* script = Script::cast(shared->script()); | 13724 Script* script(Script::cast(shared->script())); |
13724 hash ^= String::cast(script->source())->Hash(); | 13725 hash ^= String::cast(script->source())->Hash(); |
13725 if (strict_mode == STRICT) hash ^= 0x8000; | 13726 if (strict_mode == STRICT) hash ^= 0x8000; |
13726 hash += scope_position; | 13727 hash += scope_position; |
13727 } | 13728 } |
13728 return hash; | 13729 return hash; |
13729 } | 13730 } |
13730 | 13731 |
13731 uint32_t Hash() { | 13732 uint32_t Hash() { |
13732 return StringSharedHashHelper( | 13733 return StringSharedHashHelper(*source_, *shared_, strict_mode_, |
13733 source_, shared_, strict_mode_, scope_position_); | 13734 scope_position_); |
13734 } | 13735 } |
13735 | 13736 |
13736 uint32_t HashForObject(Object* obj) { | 13737 uint32_t HashForObject(Object* obj) { |
| 13738 DisallowHeapAllocation no_allocation; |
13737 FixedArray* other_array = FixedArray::cast(obj); | 13739 FixedArray* other_array = FixedArray::cast(obj); |
13738 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 13740 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
13739 String* source = String::cast(other_array->get(1)); | 13741 String* source = String::cast(other_array->get(1)); |
13740 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 13742 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
13741 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 13743 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
13742 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 13744 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
13743 int scope_position = Smi::cast(other_array->get(3))->value(); | 13745 int scope_position = Smi::cast(other_array->get(3))->value(); |
13744 return StringSharedHashHelper( | 13746 return StringSharedHashHelper( |
13745 source, shared, strict_mode, scope_position); | 13747 source, shared, strict_mode, scope_position); |
13746 } | 13748 } |
13747 | 13749 |
13748 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { | 13750 |
13749 Object* obj; | 13751 Object* AsObject(Heap* heap) { |
13750 { MaybeObject* maybe_obj = heap->AllocateFixedArray(4); | 13752 UNREACHABLE(); |
13751 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13753 return NULL; |
13752 } | 13754 } |
13753 FixedArray* other_array = FixedArray::cast(obj); | 13755 |
13754 other_array->set(0, shared_); | 13756 |
13755 other_array->set(1, source_); | 13757 Handle<Object> AsObject(Factory* factory) { |
13756 other_array->set(2, Smi::FromInt(strict_mode_)); | 13758 Handle<FixedArray> array = factory->NewFixedArray(4); |
13757 other_array->set(3, Smi::FromInt(scope_position_)); | 13759 array->set(0, *shared_); |
13758 return other_array; | 13760 array->set(1, *source_); |
| 13761 array->set(2, Smi::FromInt(strict_mode_)); |
| 13762 array->set(3, Smi::FromInt(scope_position_)); |
| 13763 return array; |
13759 } | 13764 } |
13760 | 13765 |
13761 private: | 13766 private: |
13762 String* source_; | 13767 Handle<String> source_; |
13763 SharedFunctionInfo* shared_; | 13768 Handle<SharedFunctionInfo> shared_; |
13764 StrictMode strict_mode_; | 13769 StrictMode strict_mode_; |
13765 int scope_position_; | 13770 int scope_position_; |
13766 }; | 13771 }; |
13767 | 13772 |
13768 | 13773 |
13769 // RegExpKey carries the source and flags of a regular expression as key. | 13774 // RegExpKey carries the source and flags of a regular expression as key. |
13770 class RegExpKey : public HashTableKey { | 13775 class RegExpKey : public HashTableKey { |
13771 public: | 13776 public: |
13772 RegExpKey(String* string, JSRegExp::Flags flags) | 13777 RegExpKey(String* string, JSRegExp::Flags flags) |
13773 : string_(string), | 13778 : string_(string), |
(...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14950 | 14955 |
14951 // Add the new string and return it along with the string table. | 14956 // Add the new string and return it along with the string table. |
14952 entry = table->FindInsertionEntry(key->Hash()); | 14957 entry = table->FindInsertionEntry(key->Hash()); |
14953 table->set(EntryToIndex(entry), string); | 14958 table->set(EntryToIndex(entry), string); |
14954 table->ElementAdded(); | 14959 table->ElementAdded(); |
14955 *s = string; | 14960 *s = string; |
14956 return table; | 14961 return table; |
14957 } | 14962 } |
14958 | 14963 |
14959 | 14964 |
14960 Object* CompilationCacheTable::Lookup(String* src, Context* context) { | 14965 Handle<Object> CompilationCacheTable::Lookup(Handle<String> src, |
14961 SharedFunctionInfo* shared = context->closure()->shared(); | 14966 Handle<Context> context) { |
14962 StringSharedKey key(src, | 14967 Isolate* isolate = GetIsolate(); |
14963 shared, | 14968 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
14964 FLAG_use_strict ? STRICT : SLOPPY, | 14969 StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, |
14965 RelocInfo::kNoPosition); | 14970 RelocInfo::kNoPosition); |
14966 int entry = FindEntry(&key); | 14971 int entry = FindEntry(&key); |
14967 if (entry == kNotFound) return GetHeap()->undefined_value(); | 14972 if (entry == kNotFound) return isolate->factory()->undefined_value(); |
14968 return get(EntryToIndex(entry) + 1); | 14973 return Handle<Object>(get(EntryToIndex(entry) + 1), isolate); |
14969 } | 14974 } |
14970 | 14975 |
14971 | 14976 |
14972 Object* CompilationCacheTable::LookupEval(String* src, | 14977 Handle<Object> CompilationCacheTable::LookupEval(Handle<String> src, |
14973 Context* context, | 14978 Handle<Context> context, |
14974 StrictMode strict_mode, | 14979 StrictMode strict_mode, |
14975 int scope_position) { | 14980 int scope_position) { |
14976 StringSharedKey key(src, | 14981 Isolate* isolate = GetIsolate(); |
14977 context->closure()->shared(), | 14982 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
14978 strict_mode, | 14983 StringSharedKey key(src, shared, strict_mode, scope_position); |
14979 scope_position); | |
14980 int entry = FindEntry(&key); | 14984 int entry = FindEntry(&key); |
14981 if (entry == kNotFound) return GetHeap()->undefined_value(); | 14985 if (entry == kNotFound) return isolate->factory()->undefined_value(); |
14982 return get(EntryToIndex(entry) + 1); | 14986 return Handle<Object>(get(EntryToIndex(entry) + 1), isolate); |
14983 } | 14987 } |
14984 | 14988 |
14985 | 14989 |
14986 Object* CompilationCacheTable::LookupRegExp(String* src, | 14990 Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src, |
14987 JSRegExp::Flags flags) { | 14991 JSRegExp::Flags flags) { |
14988 RegExpKey key(src, flags); | 14992 Isolate* isolate = GetIsolate(); |
| 14993 DisallowHeapAllocation no_allocation; |
| 14994 RegExpKey key(*src, flags); |
14989 int entry = FindEntry(&key); | 14995 int entry = FindEntry(&key); |
14990 if (entry == kNotFound) return GetHeap()->undefined_value(); | 14996 if (entry == kNotFound) return isolate->factory()->undefined_value(); |
14991 return get(EntryToIndex(entry) + 1); | 14997 return Handle<Object>(get(EntryToIndex(entry) + 1), isolate); |
14992 } | 14998 } |
14993 | 14999 |
14994 | 15000 |
14995 MaybeObject* CompilationCacheTable::Put(String* src, | 15001 Handle<CompilationCacheTable> CompilationCacheTable::Put( |
14996 Context* context, | 15002 Handle<CompilationCacheTable> cache, Handle<String> src, |
14997 Object* value) { | 15003 Handle<Context> context, Handle<Object> value) { |
14998 SharedFunctionInfo* shared = context->closure()->shared(); | 15004 Isolate* isolate = cache->GetIsolate(); |
14999 StringSharedKey key(src, | 15005 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
15000 shared, | 15006 StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, |
15001 FLAG_use_strict ? STRICT : SLOPPY, | |
15002 RelocInfo::kNoPosition); | 15007 RelocInfo::kNoPosition); |
15003 CompilationCacheTable* cache; | 15008 cache = EnsureCapacityFor(cache, 1, &key); |
15004 MaybeObject* maybe_cache = EnsureCapacity(1, &key); | 15009 Handle<Object> k = key.AsObject(isolate->factory()); |
15005 if (!maybe_cache->To(&cache)) return maybe_cache; | |
15006 | |
15007 Object* k; | |
15008 MaybeObject* maybe_k = key.AsObject(GetHeap()); | |
15009 if (!maybe_k->To(&k)) return maybe_k; | |
15010 | |
15011 int entry = cache->FindInsertionEntry(key.Hash()); | 15010 int entry = cache->FindInsertionEntry(key.Hash()); |
15012 cache->set(EntryToIndex(entry), k); | 15011 cache->set(EntryToIndex(entry), *k); |
15013 cache->set(EntryToIndex(entry) + 1, value); | 15012 cache->set(EntryToIndex(entry) + 1, *value); |
15014 cache->ElementAdded(); | 15013 cache->ElementAdded(); |
15015 return cache; | 15014 return cache; |
15016 } | 15015 } |
15017 | 15016 |
15018 | 15017 |
15019 MaybeObject* CompilationCacheTable::PutEval(String* src, | 15018 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( |
15020 Context* context, | 15019 Handle<CompilationCacheTable> cache, Handle<String> src, |
15021 SharedFunctionInfo* value, | 15020 Handle<Context> context, Handle<SharedFunctionInfo> value, |
15022 int scope_position) { | 15021 int scope_position) { |
15023 StringSharedKey key(src, | 15022 Isolate* isolate = cache->GetIsolate(); |
15024 context->closure()->shared(), | 15023 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
15025 value->strict_mode(), | 15024 StringSharedKey key(src, shared, value->strict_mode(), scope_position); |
15026 scope_position); | 15025 cache = EnsureCapacityFor(cache, 1, &key); |
15027 Object* obj; | 15026 Handle<Object> k = key.AsObject(isolate->factory()); |
15028 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | |
15029 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
15030 } | |
15031 | |
15032 CompilationCacheTable* cache = | |
15033 reinterpret_cast<CompilationCacheTable*>(obj); | |
15034 int entry = cache->FindInsertionEntry(key.Hash()); | 15027 int entry = cache->FindInsertionEntry(key.Hash()); |
15035 | 15028 cache->set(EntryToIndex(entry), *k); |
15036 Object* k; | 15029 cache->set(EntryToIndex(entry) + 1, *value); |
15037 { MaybeObject* maybe_k = key.AsObject(GetHeap()); | |
15038 if (!maybe_k->ToObject(&k)) return maybe_k; | |
15039 } | |
15040 | |
15041 cache->set(EntryToIndex(entry), k); | |
15042 cache->set(EntryToIndex(entry) + 1, value); | |
15043 cache->ElementAdded(); | 15030 cache->ElementAdded(); |
15044 return cache; | 15031 return cache; |
15045 } | 15032 } |
15046 | 15033 |
15047 | 15034 |
15048 MaybeObject* CompilationCacheTable::PutRegExp(String* src, | 15035 Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp( |
15049 JSRegExp::Flags flags, | 15036 Handle<CompilationCacheTable> cache, Handle<String> src, |
15050 FixedArray* value) { | 15037 JSRegExp::Flags flags, Handle<FixedArray> value) { |
15051 RegExpKey key(src, flags); | 15038 RegExpKey key(*src, flags); |
15052 Object* obj; | 15039 cache = EnsureCapacityFor(cache, 1, &key); |
15053 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | |
15054 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
15055 } | |
15056 | |
15057 CompilationCacheTable* cache = | |
15058 reinterpret_cast<CompilationCacheTable*>(obj); | |
15059 int entry = cache->FindInsertionEntry(key.Hash()); | 15040 int entry = cache->FindInsertionEntry(key.Hash()); |
15060 // We store the value in the key slot, and compare the search key | 15041 // We store the value in the key slot, and compare the search key |
15061 // to the stored value with a custon IsMatch function during lookups. | 15042 // to the stored value with a custon IsMatch function during lookups. |
15062 cache->set(EntryToIndex(entry), value); | 15043 cache->set(EntryToIndex(entry), *value); |
15063 cache->set(EntryToIndex(entry) + 1, value); | 15044 cache->set(EntryToIndex(entry) + 1, *value); |
15064 cache->ElementAdded(); | 15045 cache->ElementAdded(); |
15065 return cache; | 15046 return cache; |
15066 } | 15047 } |
15067 | 15048 |
15068 | 15049 |
| 15050 Handle<CompilationCacheTable> CompilationCacheTable::EnsureCapacityFor( |
| 15051 Handle<CompilationCacheTable> cache, int n, HashTableKey* key) { |
| 15052 CALL_HEAP_FUNCTION(cache->GetIsolate(), |
| 15053 cache->EnsureCapacity(n, key), |
| 15054 CompilationCacheTable); |
| 15055 } |
| 15056 |
| 15057 |
15069 void CompilationCacheTable::Remove(Object* value) { | 15058 void CompilationCacheTable::Remove(Object* value) { |
| 15059 DisallowHeapAllocation no_allocation; |
15070 Object* the_hole_value = GetHeap()->the_hole_value(); | 15060 Object* the_hole_value = GetHeap()->the_hole_value(); |
15071 for (int entry = 0, size = Capacity(); entry < size; entry++) { | 15061 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
15072 int entry_index = EntryToIndex(entry); | 15062 int entry_index = EntryToIndex(entry); |
15073 int value_index = entry_index + 1; | 15063 int value_index = entry_index + 1; |
15074 if (get(value_index) == value) { | 15064 if (get(value_index) == value) { |
15075 NoWriteBarrierSet(this, entry_index, the_hole_value); | 15065 NoWriteBarrierSet(this, entry_index, the_hole_value); |
15076 NoWriteBarrierSet(this, value_index, the_hole_value); | 15066 NoWriteBarrierSet(this, value_index, the_hole_value); |
15077 ElementRemoved(); | 15067 ElementRemoved(); |
15078 } | 15068 } |
15079 } | 15069 } |
(...skipping 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16682 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16672 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16683 static const char* error_messages_[] = { | 16673 static const char* error_messages_[] = { |
16684 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16674 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16685 }; | 16675 }; |
16686 #undef ERROR_MESSAGES_TEXTS | 16676 #undef ERROR_MESSAGES_TEXTS |
16687 return error_messages_[reason]; | 16677 return error_messages_[reason]; |
16688 } | 16678 } |
16689 | 16679 |
16690 | 16680 |
16691 } } // namespace v8::internal | 16681 } } // namespace v8::internal |
OLD | NEW |