| 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 |