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 7912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7923 } | 7923 } |
7924 } | 7924 } |
7925 | 7925 |
7926 | 7926 |
7927 // The key in the code cache hash table consists of the property name and the | 7927 // The key in the code cache hash table consists of the property name and the |
7928 // code object. The actual match is on the name and the code flags. If a key | 7928 // code object. The actual match is on the name and the code flags. If a key |
7929 // is created using the flags and not a code object it can only be used for | 7929 // is created using the flags and not a code object it can only be used for |
7930 // lookup not to create a new entry. | 7930 // lookup not to create a new entry. |
7931 class CodeCacheHashTableKey : public HashTableKey { | 7931 class CodeCacheHashTableKey : public HashTableKey { |
7932 public: | 7932 public: |
7933 CodeCacheHashTableKey(Name* name, Code::Flags flags) | 7933 CodeCacheHashTableKey(Handle<Name> name, Code::Flags flags) |
7934 : name_(name), flags_(flags), code_(NULL) { } | 7934 : name_(name), flags_(flags), code_() { } |
7935 | 7935 |
7936 CodeCacheHashTableKey(Name* name, Code* code) | 7936 CodeCacheHashTableKey(Handle<Name> name, Handle<Code> code) |
7937 : name_(name), flags_(code->flags()), code_(code) { } | 7937 : name_(name), flags_(code->flags()), code_(code) { } |
7938 | 7938 |
7939 | 7939 |
7940 bool IsMatch(Object* other) { | 7940 bool IsMatch(Object* other) { |
7941 if (!other->IsFixedArray()) return false; | 7941 if (!other->IsFixedArray()) return false; |
7942 FixedArray* pair = FixedArray::cast(other); | 7942 FixedArray* pair = FixedArray::cast(other); |
7943 Name* name = Name::cast(pair->get(0)); | 7943 Name* name = Name::cast(pair->get(0)); |
7944 Code::Flags flags = Code::cast(pair->get(1))->flags(); | 7944 Code::Flags flags = Code::cast(pair->get(1))->flags(); |
7945 if (flags != flags_) { | 7945 if (flags != flags_) { |
7946 return false; | 7946 return false; |
7947 } | 7947 } |
7948 return name_->Equals(name); | 7948 return name_->Equals(name); |
7949 } | 7949 } |
7950 | 7950 |
7951 static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) { | 7951 static uint32_t NameFlagsHashHelper(Name* name, Code::Flags flags) { |
7952 return name->Hash() ^ flags; | 7952 return name->Hash() ^ flags; |
7953 } | 7953 } |
7954 | 7954 |
7955 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); } | 7955 uint32_t Hash() { return NameFlagsHashHelper(*name_, flags_); } |
7956 | 7956 |
7957 uint32_t HashForObject(Object* obj) { | 7957 uint32_t HashForObject(Object* obj) { |
7958 FixedArray* pair = FixedArray::cast(obj); | 7958 FixedArray* pair = FixedArray::cast(obj); |
7959 Name* name = Name::cast(pair->get(0)); | 7959 Name* name = Name::cast(pair->get(0)); |
7960 Code* code = Code::cast(pair->get(1)); | 7960 Code* code = Code::cast(pair->get(1)); |
7961 return NameFlagsHashHelper(name, code->flags()); | 7961 return NameFlagsHashHelper(name, code->flags()); |
7962 } | 7962 } |
7963 | 7963 |
7964 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { | 7964 MUST_USE_RESULT MaybeObject* AsObject(Heap* heap) { |
7965 ASSERT(code_ != NULL); | 7965 Handle<Code> code = code_.ToHandleChecked(); |
7966 Object* obj; | 7966 Object* obj; |
7967 { MaybeObject* maybe_obj = heap->AllocateFixedArray(2); | 7967 { MaybeObject* maybe_obj = heap->AllocateFixedArray(2); |
7968 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7968 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7969 } | 7969 } |
7970 FixedArray* pair = FixedArray::cast(obj); | 7970 FixedArray* pair = FixedArray::cast(obj); |
7971 pair->set(0, name_); | 7971 pair->set(0, *name_); |
7972 pair->set(1, code_); | 7972 pair->set(1, *code); |
7973 return pair; | 7973 return pair; |
7974 } | 7974 } |
7975 | 7975 |
| 7976 Handle<FixedArray> AsHandle() { |
| 7977 Isolate* isolate = name_->GetIsolate(); |
| 7978 CALL_HEAP_FUNCTION(isolate, |
| 7979 AsObject(isolate->heap()), |
| 7980 FixedArray); |
| 7981 } |
| 7982 |
7976 private: | 7983 private: |
7977 Name* name_; | 7984 Handle<Name> name_; |
7978 Code::Flags flags_; | 7985 Code::Flags flags_; |
7979 // TODO(jkummerow): We should be able to get by without this. | 7986 // TODO(jkummerow): We should be able to get by without this. |
7980 Code* code_; | 7987 MaybeHandle<Code> code_; |
7981 }; | 7988 }; |
7982 | 7989 |
7983 | 7990 |
7984 Object* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) { | 7991 Object* CodeCacheHashTable::Lookup(Name* name, Code::Flags flags) { |
7985 CodeCacheHashTableKey key(name, flags); | 7992 DisallowHeapAllocation no_alloc; |
| 7993 CodeCacheHashTableKey key(handle(name), flags); |
7986 int entry = FindEntry(&key); | 7994 int entry = FindEntry(&key); |
7987 if (entry == kNotFound) return GetHeap()->undefined_value(); | 7995 if (entry == kNotFound) return GetHeap()->undefined_value(); |
7988 return get(EntryToIndex(entry) + 1); | 7996 return get(EntryToIndex(entry) + 1); |
7989 } | 7997 } |
7990 | 7998 |
7991 | 7999 |
7992 MaybeObject* CodeCacheHashTable::Put(Name* name, Code* code) { | |
7993 CodeCacheHashTableKey key(name, code); | |
7994 Object* obj; | |
7995 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | |
7996 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
7997 } | |
7998 | |
7999 // Don't use |this|, as the table might have grown. | |
8000 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj); | |
8001 | |
8002 int entry = cache->FindInsertionEntry(key.Hash()); | |
8003 Object* k; | |
8004 { MaybeObject* maybe_k = key.AsObject(GetHeap()); | |
8005 if (!maybe_k->ToObject(&k)) return maybe_k; | |
8006 } | |
8007 | |
8008 cache->set(EntryToIndex(entry), k); | |
8009 cache->set(EntryToIndex(entry) + 1, code); | |
8010 cache->ElementAdded(); | |
8011 return cache; | |
8012 } | |
8013 | |
8014 | |
8015 Handle<CodeCacheHashTable> CodeCacheHashTable::Put( | 8000 Handle<CodeCacheHashTable> CodeCacheHashTable::Put( |
8016 Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) { | 8001 Handle<CodeCacheHashTable> cache, Handle<Name> name, Handle<Code> code) { |
8017 Isolate* isolate = cache->GetIsolate(); | 8002 CodeCacheHashTableKey key(name, code); |
8018 CALL_HEAP_FUNCTION(isolate, | 8003 |
8019 cache->Put(*name, *code), | 8004 Handle<CodeCacheHashTable> new_cache = EnsureCapacity(cache, 1, &key); |
8020 CodeCacheHashTable); | 8005 |
| 8006 int entry = new_cache->FindInsertionEntry(key.Hash()); |
| 8007 Handle<Object> k = key.AsHandle(); |
| 8008 |
| 8009 new_cache->set(EntryToIndex(entry), *k); |
| 8010 new_cache->set(EntryToIndex(entry) + 1, *code); |
| 8011 new_cache->ElementAdded(); |
| 8012 return new_cache; |
8021 } | 8013 } |
8022 | 8014 |
8023 | 8015 |
8024 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { | 8016 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { |
8025 CodeCacheHashTableKey key(name, flags); | 8017 DisallowHeapAllocation no_alloc; |
| 8018 CodeCacheHashTableKey key(handle(name), flags); |
8026 int entry = FindEntry(&key); | 8019 int entry = FindEntry(&key); |
8027 return (entry == kNotFound) ? -1 : entry; | 8020 return (entry == kNotFound) ? -1 : entry; |
8028 } | 8021 } |
8029 | 8022 |
8030 | 8023 |
8031 void CodeCacheHashTable::RemoveByIndex(int index) { | 8024 void CodeCacheHashTable::RemoveByIndex(int index) { |
8032 ASSERT(index >= 0); | 8025 ASSERT(index >= 0); |
8033 Heap* heap = GetHeap(); | 8026 Heap* heap = GetHeap(); |
8034 set(EntryToIndex(index), heap->the_hole_value()); | 8027 set(EntryToIndex(index), heap->the_hole_value()); |
8035 set(EntryToIndex(index) + 1, heap->the_hole_value()); | 8028 set(EntryToIndex(index) + 1, heap->the_hole_value()); |
(...skipping 6745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14781 should_pretenure ? TENURED : NOT_TENURED); | 14774 should_pretenure ? TENURED : NOT_TENURED); |
14782 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 14775 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
14783 } | 14776 } |
14784 | 14777 |
14785 Rehash(Derived::cast(obj), key); | 14778 Rehash(Derived::cast(obj), key); |
14786 return Derived::cast(obj); | 14779 return Derived::cast(obj); |
14787 } | 14780 } |
14788 | 14781 |
14789 | 14782 |
14790 template<typename Derived, typename Shape, typename Key> | 14783 template<typename Derived, typename Shape, typename Key> |
| 14784 Handle<Derived> HashTable<Derived, Shape, Key>::EnsureCapacity( |
| 14785 Handle<Derived> table, |
| 14786 int n, |
| 14787 Key key, |
| 14788 PretenureFlag pretenure) { |
| 14789 Isolate* isolate = table->GetIsolate(); |
| 14790 CALL_HEAP_FUNCTION(isolate, |
| 14791 table->EnsureCapacity(n, key, pretenure), |
| 14792 Derived); |
| 14793 } |
| 14794 |
| 14795 |
| 14796 template<typename Derived, typename Shape, typename Key> |
14791 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, | 14797 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, |
14792 Key key) { | 14798 Key key) { |
14793 int capacity = table->Capacity(); | 14799 int capacity = table->Capacity(); |
14794 int nof = table->NumberOfElements(); | 14800 int nof = table->NumberOfElements(); |
14795 | 14801 |
14796 // Shrink to fit the number of elements if only a quarter of the | 14802 // Shrink to fit the number of elements if only a quarter of the |
14797 // capacity is filled with elements. | 14803 // capacity is filled with elements. |
14798 if (nof > (capacity >> 2)) return table; | 14804 if (nof > (capacity >> 2)) return table; |
14799 // Allocate a new dictionary with room for at least the current | 14805 // Allocate a new dictionary with room for at least the current |
14800 // number of elements. The allocation method will make sure that | 14806 // number of elements. The allocation method will make sure that |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15640 } | 15646 } |
15641 | 15647 |
15642 | 15648 |
15643 Handle<CompilationCacheTable> CompilationCacheTable::Put( | 15649 Handle<CompilationCacheTable> CompilationCacheTable::Put( |
15644 Handle<CompilationCacheTable> cache, Handle<String> src, | 15650 Handle<CompilationCacheTable> cache, Handle<String> src, |
15645 Handle<Context> context, Handle<Object> value) { | 15651 Handle<Context> context, Handle<Object> value) { |
15646 Isolate* isolate = cache->GetIsolate(); | 15652 Isolate* isolate = cache->GetIsolate(); |
15647 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 15653 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
15648 StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, | 15654 StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, |
15649 RelocInfo::kNoPosition); | 15655 RelocInfo::kNoPosition); |
15650 cache = EnsureCapacityFor(cache, 1, &key); | 15656 cache = EnsureCapacity(cache, 1, &key); |
15651 Handle<Object> k = key.AsObject(isolate->factory()); | 15657 Handle<Object> k = key.AsObject(isolate->factory()); |
15652 int entry = cache->FindInsertionEntry(key.Hash()); | 15658 int entry = cache->FindInsertionEntry(key.Hash()); |
15653 cache->set(EntryToIndex(entry), *k); | 15659 cache->set(EntryToIndex(entry), *k); |
15654 cache->set(EntryToIndex(entry) + 1, *value); | 15660 cache->set(EntryToIndex(entry) + 1, *value); |
15655 cache->ElementAdded(); | 15661 cache->ElementAdded(); |
15656 return cache; | 15662 return cache; |
15657 } | 15663 } |
15658 | 15664 |
15659 | 15665 |
15660 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( | 15666 Handle<CompilationCacheTable> CompilationCacheTable::PutEval( |
15661 Handle<CompilationCacheTable> cache, Handle<String> src, | 15667 Handle<CompilationCacheTable> cache, Handle<String> src, |
15662 Handle<Context> context, Handle<SharedFunctionInfo> value, | 15668 Handle<Context> context, Handle<SharedFunctionInfo> value, |
15663 int scope_position) { | 15669 int scope_position) { |
15664 Isolate* isolate = cache->GetIsolate(); | 15670 Isolate* isolate = cache->GetIsolate(); |
15665 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 15671 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
15666 StringSharedKey key(src, shared, value->strict_mode(), scope_position); | 15672 StringSharedKey key(src, shared, value->strict_mode(), scope_position); |
15667 cache = EnsureCapacityFor(cache, 1, &key); | 15673 cache = EnsureCapacity(cache, 1, &key); |
15668 Handle<Object> k = key.AsObject(isolate->factory()); | 15674 Handle<Object> k = key.AsObject(isolate->factory()); |
15669 int entry = cache->FindInsertionEntry(key.Hash()); | 15675 int entry = cache->FindInsertionEntry(key.Hash()); |
15670 cache->set(EntryToIndex(entry), *k); | 15676 cache->set(EntryToIndex(entry), *k); |
15671 cache->set(EntryToIndex(entry) + 1, *value); | 15677 cache->set(EntryToIndex(entry) + 1, *value); |
15672 cache->ElementAdded(); | 15678 cache->ElementAdded(); |
15673 return cache; | 15679 return cache; |
15674 } | 15680 } |
15675 | 15681 |
15676 | 15682 |
15677 Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp( | 15683 Handle<CompilationCacheTable> CompilationCacheTable::PutRegExp( |
15678 Handle<CompilationCacheTable> cache, Handle<String> src, | 15684 Handle<CompilationCacheTable> cache, Handle<String> src, |
15679 JSRegExp::Flags flags, Handle<FixedArray> value) { | 15685 JSRegExp::Flags flags, Handle<FixedArray> value) { |
15680 RegExpKey key(src, flags); | 15686 RegExpKey key(src, flags); |
15681 cache = EnsureCapacityFor(cache, 1, &key); | 15687 cache = EnsureCapacity(cache, 1, &key); |
15682 int entry = cache->FindInsertionEntry(key.Hash()); | 15688 int entry = cache->FindInsertionEntry(key.Hash()); |
15683 // We store the value in the key slot, and compare the search key | 15689 // We store the value in the key slot, and compare the search key |
15684 // to the stored value with a custon IsMatch function during lookups. | 15690 // to the stored value with a custon IsMatch function during lookups. |
15685 cache->set(EntryToIndex(entry), *value); | 15691 cache->set(EntryToIndex(entry), *value); |
15686 cache->set(EntryToIndex(entry) + 1, *value); | 15692 cache->set(EntryToIndex(entry) + 1, *value); |
15687 cache->ElementAdded(); | 15693 cache->ElementAdded(); |
15688 return cache; | 15694 return cache; |
15689 } | 15695 } |
15690 | 15696 |
15691 | 15697 |
15692 Handle<CompilationCacheTable> CompilationCacheTable::EnsureCapacityFor( | |
15693 Handle<CompilationCacheTable> cache, int n, HashTableKey* key) { | |
15694 CALL_HEAP_FUNCTION(cache->GetIsolate(), | |
15695 cache->EnsureCapacity(n, key), | |
15696 CompilationCacheTable); | |
15697 } | |
15698 | |
15699 | |
15700 void CompilationCacheTable::Remove(Object* value) { | 15698 void CompilationCacheTable::Remove(Object* value) { |
15701 DisallowHeapAllocation no_allocation; | 15699 DisallowHeapAllocation no_allocation; |
15702 Object* the_hole_value = GetHeap()->the_hole_value(); | 15700 Object* the_hole_value = GetHeap()->the_hole_value(); |
15703 for (int entry = 0, size = Capacity(); entry < size; entry++) { | 15701 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
15704 int entry_index = EntryToIndex(entry); | 15702 int entry_index = EntryToIndex(entry); |
15705 int value_index = entry_index + 1; | 15703 int value_index = entry_index + 1; |
15706 if (get(value_index) == value) { | 15704 if (get(value_index) == value) { |
15707 NoWriteBarrierSet(this, entry_index, the_hole_value); | 15705 NoWriteBarrierSet(this, entry_index, the_hole_value); |
15708 NoWriteBarrierSet(this, value_index, the_hole_value); | 15706 NoWriteBarrierSet(this, value_index, the_hole_value); |
15709 ElementRemoved(); | 15707 ElementRemoved(); |
15710 } | 15708 } |
15711 } | 15709 } |
15712 return; | 15710 return; |
15713 } | 15711 } |
15714 | 15712 |
15715 | 15713 |
15716 // StringsKey used for HashTable where key is array of internalized strings. | 15714 // StringsKey used for HashTable where key is array of internalized strings. |
15717 class StringsKey : public HashTableKey { | 15715 class StringsKey : public HashTableKey { |
15718 public: | 15716 public: |
15719 explicit StringsKey(FixedArray* strings) : strings_(strings) { } | 15717 explicit StringsKey(Handle<FixedArray> strings) : strings_(strings) { } |
15720 | 15718 |
15721 bool IsMatch(Object* strings) { | 15719 bool IsMatch(Object* strings) { |
15722 FixedArray* o = FixedArray::cast(strings); | 15720 FixedArray* o = FixedArray::cast(strings); |
15723 int len = strings_->length(); | 15721 int len = strings_->length(); |
15724 if (o->length() != len) return false; | 15722 if (o->length() != len) return false; |
15725 for (int i = 0; i < len; i++) { | 15723 for (int i = 0; i < len; i++) { |
15726 if (o->get(i) != strings_->get(i)) return false; | 15724 if (o->get(i) != strings_->get(i)) return false; |
15727 } | 15725 } |
15728 return true; | 15726 return true; |
15729 } | 15727 } |
15730 | 15728 |
15731 uint32_t Hash() { return HashForObject(strings_); } | 15729 uint32_t Hash() { return HashForObject(*strings_); } |
15732 | 15730 |
15733 uint32_t HashForObject(Object* obj) { | 15731 uint32_t HashForObject(Object* obj) { |
15734 FixedArray* strings = FixedArray::cast(obj); | 15732 FixedArray* strings = FixedArray::cast(obj); |
15735 int len = strings->length(); | 15733 int len = strings->length(); |
15736 uint32_t hash = 0; | 15734 uint32_t hash = 0; |
15737 for (int i = 0; i < len; i++) { | 15735 for (int i = 0; i < len; i++) { |
15738 hash ^= String::cast(strings->get(i))->Hash(); | 15736 hash ^= String::cast(strings->get(i))->Hash(); |
15739 } | 15737 } |
15740 return hash; | 15738 return hash; |
15741 } | 15739 } |
15742 | 15740 |
15743 Object* AsObject(Heap* heap) { return strings_; } | 15741 Object* AsObject(Heap* heap) { return *strings_; } |
15744 | 15742 |
15745 private: | 15743 private: |
15746 FixedArray* strings_; | 15744 Handle<FixedArray> strings_; |
15747 }; | 15745 }; |
15748 | 15746 |
15749 | 15747 |
15750 Object* MapCache::Lookup(FixedArray* array) { | 15748 Object* MapCache::Lookup(FixedArray* array) { |
15751 StringsKey key(array); | 15749 DisallowHeapAllocation no_alloc; |
| 15750 StringsKey key(handle(array)); |
15752 int entry = FindEntry(&key); | 15751 int entry = FindEntry(&key); |
15753 if (entry == kNotFound) return GetHeap()->undefined_value(); | 15752 if (entry == kNotFound) return GetHeap()->undefined_value(); |
15754 return get(EntryToIndex(entry) + 1); | 15753 return get(EntryToIndex(entry) + 1); |
15755 } | 15754 } |
15756 | 15755 |
15757 | 15756 |
15758 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { | 15757 Handle<MapCache> MapCache::Put( |
| 15758 Handle<MapCache> map_cache, Handle<FixedArray> array, Handle<Map> value) { |
15759 StringsKey key(array); | 15759 StringsKey key(array); |
15760 Object* obj; | |
15761 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | |
15762 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
15763 } | |
15764 | 15760 |
15765 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 15761 Handle<MapCache> new_cache = EnsureCapacity(map_cache, 1, &key); |
15766 int entry = cache->FindInsertionEntry(key.Hash()); | 15762 int entry = new_cache->FindInsertionEntry(key.Hash()); |
15767 cache->set(EntryToIndex(entry), array); | 15763 new_cache->set(EntryToIndex(entry), *array); |
15768 cache->set(EntryToIndex(entry) + 1, value); | 15764 new_cache->set(EntryToIndex(entry) + 1, *value); |
15769 cache->ElementAdded(); | 15765 new_cache->ElementAdded(); |
15770 return cache; | 15766 return new_cache; |
15771 } | 15767 } |
15772 | 15768 |
15773 | 15769 |
15774 template<typename Derived, typename Shape, typename Key> | 15770 template<typename Derived, typename Shape, typename Key> |
15775 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( | 15771 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( |
15776 Heap* heap, | 15772 Heap* heap, |
15777 int at_least_space_for, | 15773 int at_least_space_for, |
15778 PretenureFlag pretenure) { | 15774 PretenureFlag pretenure) { |
15779 Object* obj; | 15775 Object* obj; |
15780 { MaybeObject* maybe_obj = | 15776 { MaybeObject* maybe_obj = |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15882 // If not, we generate new indices for the properties. | 15878 // If not, we generate new indices for the properties. |
15883 Object* result; | 15879 Object* result; |
15884 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15880 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
15885 if (!maybe_result->ToObject(&result)) return maybe_result; | 15881 if (!maybe_result->ToObject(&result)) return maybe_result; |
15886 } | 15882 } |
15887 } | 15883 } |
15888 return DerivedHashTable::EnsureCapacity(n, key); | 15884 return DerivedHashTable::EnsureCapacity(n, key); |
15889 } | 15885 } |
15890 | 15886 |
15891 | 15887 |
| 15888 |
| 15889 template<typename Derived, typename Shape, typename Key> |
| 15890 Handle<Derived> Dictionary<Derived, Shape, Key>::EnsureCapacity( |
| 15891 Handle<Derived> obj, int n, Key key) { |
| 15892 Isolate* isolate = obj->GetIsolate(); |
| 15893 CALL_HEAP_FUNCTION(isolate, |
| 15894 obj->EnsureCapacity(n, key), |
| 15895 Derived); |
| 15896 } |
| 15897 |
| 15898 |
15892 // TODO(ishell): Temporary wrapper until handlified. | 15899 // TODO(ishell): Temporary wrapper until handlified. |
15893 template<typename Derived, typename Shape, typename Key> | 15900 template<typename Derived, typename Shape, typename Key> |
15894 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( | 15901 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
15895 Handle<Dictionary<Derived, Shape, Key> > dictionary, | 15902 Handle<Dictionary<Derived, Shape, Key> > dictionary, |
15896 int entry, | 15903 int entry, |
15897 JSObject::DeleteMode mode) { | 15904 JSObject::DeleteMode mode) { |
15898 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 15905 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
15899 dictionary->DeleteProperty(entry, mode), | 15906 dictionary->DeleteProperty(entry, mode), |
15900 Object); | 15907 Object); |
15901 } | 15908 } |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16223 e = PropertyCell::cast(e)->value(); | 16230 e = PropertyCell::cast(e)->value(); |
16224 } | 16231 } |
16225 if (e == value) return k; | 16232 if (e == value) return k; |
16226 } | 16233 } |
16227 } | 16234 } |
16228 Heap* heap = Dictionary::GetHeap(); | 16235 Heap* heap = Dictionary::GetHeap(); |
16229 return heap->undefined_value(); | 16236 return heap->undefined_value(); |
16230 } | 16237 } |
16231 | 16238 |
16232 | 16239 |
16233 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | |
16234 Handle<ObjectHashTable> table, | |
16235 int n, | |
16236 Handle<Object> key, | |
16237 PretenureFlag pretenure) { | |
16238 Handle<HashTable<ObjectHashTable, | |
16239 ObjectHashTableShape, | |
16240 Object*> > table_base = table; | |
16241 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | |
16242 table_base->EnsureCapacity(n, *key, pretenure), | |
16243 ObjectHashTable); | |
16244 } | |
16245 | |
16246 | |
16247 Object* ObjectHashTable::Lookup(Object* key) { | 16240 Object* ObjectHashTable::Lookup(Object* key) { |
16248 ASSERT(IsKey(key)); | 16241 ASSERT(IsKey(key)); |
16249 | 16242 |
16250 // If the object does not have an identity hash, it was never used as a key. | 16243 // If the object does not have an identity hash, it was never used as a key. |
16251 Object* hash = key->GetHash(); | 16244 Object* hash = key->GetHash(); |
16252 if (hash->IsUndefined()) { | 16245 if (hash->IsUndefined()) { |
16253 return GetHeap()->the_hole_value(); | 16246 return GetHeap()->the_hole_value(); |
16254 } | 16247 } |
16255 int entry = FindEntry(key); | 16248 int entry = FindEntry(key); |
16256 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 16249 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
(...skipping 20 matching lines...) Expand all Loading... |
16277 return Shrink(table, key); | 16270 return Shrink(table, key); |
16278 } | 16271 } |
16279 | 16272 |
16280 // Key is already in table, just overwrite value. | 16273 // Key is already in table, just overwrite value. |
16281 if (entry != kNotFound) { | 16274 if (entry != kNotFound) { |
16282 table->set(EntryToIndex(entry) + 1, *value); | 16275 table->set(EntryToIndex(entry) + 1, *value); |
16283 return table; | 16276 return table; |
16284 } | 16277 } |
16285 | 16278 |
16286 // Check whether the hash table should be extended. | 16279 // Check whether the hash table should be extended. |
16287 table = EnsureCapacity(table, 1, key); | 16280 table = EnsureCapacity(table, 1, *key); |
16288 table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()), | 16281 table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()), |
16289 *key, | 16282 *key, |
16290 *value); | 16283 *value); |
16291 return table; | 16284 return table; |
16292 } | 16285 } |
16293 | 16286 |
16294 | 16287 |
16295 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { | 16288 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { |
16296 set(EntryToIndex(entry), key); | 16289 set(EntryToIndex(entry), key); |
16297 set(EntryToIndex(entry) + 1, value); | 16290 set(EntryToIndex(entry) + 1, value); |
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17118 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17111 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17119 static const char* error_messages_[] = { | 17112 static const char* error_messages_[] = { |
17120 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17113 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17121 }; | 17114 }; |
17122 #undef ERROR_MESSAGES_TEXTS | 17115 #undef ERROR_MESSAGES_TEXTS |
17123 return error_messages_[reason]; | 17116 return error_messages_[reason]; |
17124 } | 17117 } |
17125 | 17118 |
17126 | 17119 |
17127 } } // namespace v8::internal | 17120 } } // namespace v8::internal |
OLD | NEW |