Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: src/objects.cc

Issue 8343056: Fix Harmony sets and maps to allow null as key. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 5172 matching lines...) Expand 10 before | Expand all | Expand 10 after
5183 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { 5183 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) {
5184 CodeCacheHashTableKey key(name, flags); 5184 CodeCacheHashTableKey key(name, flags);
5185 int entry = FindEntry(&key); 5185 int entry = FindEntry(&key);
5186 return (entry == kNotFound) ? -1 : entry; 5186 return (entry == kNotFound) ? -1 : entry;
5187 } 5187 }
5188 5188
5189 5189
5190 void CodeCacheHashTable::RemoveByIndex(int index) { 5190 void CodeCacheHashTable::RemoveByIndex(int index) {
5191 ASSERT(index >= 0); 5191 ASSERT(index >= 0);
5192 Heap* heap = GetHeap(); 5192 Heap* heap = GetHeap();
5193 set(EntryToIndex(index), heap->null_value()); 5193 set(EntryToIndex(index), heap->the_hole_value());
5194 set(EntryToIndex(index) + 1, heap->null_value()); 5194 set(EntryToIndex(index) + 1, heap->the_hole_value());
5195 ElementRemoved(); 5195 ElementRemoved();
5196 } 5196 }
5197 5197
5198 5198
5199 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache, 5199 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> cache,
5200 MapHandleList* maps, 5200 MapHandleList* maps,
5201 Code::Flags flags, 5201 Code::Flags flags,
5202 Handle<Code> code) { 5202 Handle<Code> code) {
5203 Isolate* isolate = cache->GetIsolate(); 5203 Isolate* isolate = cache->GetIsolate();
5204 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code)); 5204 CALL_HEAP_FUNCTION_VOID(isolate, cache->Update(maps, flags, *code));
(...skipping 5697 matching lines...) Expand 10 before | Expand all | Expand 10 after
10902 uint32_t capacity = Capacity(); 10902 uint32_t capacity = Capacity();
10903 uint32_t entry = FirstProbe(key->Hash(), capacity); 10903 uint32_t entry = FirstProbe(key->Hash(), capacity);
10904 uint32_t count = 1; 10904 uint32_t count = 1;
10905 10905
10906 while (true) { 10906 while (true) {
10907 int index = EntryToIndex(entry); 10907 int index = EntryToIndex(entry);
10908 Object* element = get(index); 10908 Object* element = get(index);
10909 if (element->IsUndefined()) break; // Empty entry. 10909 if (element->IsUndefined()) break; // Empty entry.
10910 if (key == element) return entry; 10910 if (key == element) return entry;
10911 if (!element->IsSymbol() && 10911 if (!element->IsSymbol() &&
10912 !element->IsNull() && 10912 !element->IsTheHole() &&
10913 String::cast(element)->Equals(key)) { 10913 String::cast(element)->Equals(key)) {
10914 // Replace a non-symbol key by the equivalent symbol for faster further 10914 // Replace a non-symbol key by the equivalent symbol for faster further
10915 // lookups. 10915 // lookups.
10916 set(index, key); 10916 set(index, key);
10917 return entry; 10917 return entry;
10918 } 10918 }
10919 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); 10919 ASSERT(element->IsTheHole() || !String::cast(element)->Equals(key));
10920 entry = NextProbe(entry, count++, capacity); 10920 entry = NextProbe(entry, count++, capacity);
10921 } 10921 }
10922 return kNotFound; 10922 return kNotFound;
10923 } 10923 }
10924 10924
10925 10925
10926 template<typename Shape, typename Key> 10926 template<typename Shape, typename Key>
10927 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { 10927 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) {
10928 ASSERT(NumberOfElements() < new_table->Capacity()); 10928 ASSERT(NumberOfElements() < new_table->Capacity());
10929 10929
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
11013 11013
11014 11014
11015 template<typename Shape, typename Key> 11015 template<typename Shape, typename Key>
11016 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { 11016 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) {
11017 uint32_t capacity = Capacity(); 11017 uint32_t capacity = Capacity();
11018 uint32_t entry = FirstProbe(hash, capacity); 11018 uint32_t entry = FirstProbe(hash, capacity);
11019 uint32_t count = 1; 11019 uint32_t count = 1;
11020 // EnsureCapacity will guarantee the hash table is never full. 11020 // EnsureCapacity will guarantee the hash table is never full.
11021 while (true) { 11021 while (true) {
11022 Object* element = KeyAt(entry); 11022 Object* element = KeyAt(entry);
11023 if (element->IsUndefined() || element->IsNull()) break; 11023 if (element->IsUndefined() || element->IsTheHole()) break;
11024 entry = NextProbe(entry, count++, capacity); 11024 entry = NextProbe(entry, count++, capacity);
11025 } 11025 }
11026 return entry; 11026 return entry;
11027 } 11027 }
11028 11028
11029 // Force instantiation of template instances class. 11029 // Force instantiation of template instances class.
11030 // Please note this list is compiler dependent. 11030 // Please note this list is compiler dependent.
11031 11031
11032 template class HashTable<SymbolTableShape, HashTableKey*>; 11032 template class HashTable<SymbolTableShape, HashTableKey*>;
11033 11033
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
11812 // We store the value in the key slot, and compare the search key 11812 // We store the value in the key slot, and compare the search key
11813 // to the stored value with a custon IsMatch function during lookups. 11813 // to the stored value with a custon IsMatch function during lookups.
11814 cache->set(EntryToIndex(entry), value); 11814 cache->set(EntryToIndex(entry), value);
11815 cache->set(EntryToIndex(entry) + 1, value); 11815 cache->set(EntryToIndex(entry) + 1, value);
11816 cache->ElementAdded(); 11816 cache->ElementAdded();
11817 return cache; 11817 return cache;
11818 } 11818 }
11819 11819
11820 11820
11821 void CompilationCacheTable::Remove(Object* value) { 11821 void CompilationCacheTable::Remove(Object* value) {
11822 Object* null_value = GetHeap()->null_value(); 11822 Object* the_hole_value = GetHeap()->the_hole_value();
11823 for (int entry = 0, size = Capacity(); entry < size; entry++) { 11823 for (int entry = 0, size = Capacity(); entry < size; entry++) {
11824 int entry_index = EntryToIndex(entry); 11824 int entry_index = EntryToIndex(entry);
11825 int value_index = entry_index + 1; 11825 int value_index = entry_index + 1;
11826 if (get(value_index) == value) { 11826 if (get(value_index) == value) {
11827 NoWriteBarrierSet(this, entry_index, null_value); 11827 NoWriteBarrierSet(this, entry_index, the_hole_value);
11828 NoWriteBarrierSet(this, value_index, null_value); 11828 NoWriteBarrierSet(this, value_index, the_hole_value);
11829 ElementRemoved(); 11829 ElementRemoved();
11830 } 11830 }
11831 } 11831 }
11832 return; 11832 return;
11833 } 11833 }
11834 11834
11835 11835
11836 // SymbolsKey used for HashTable where key is array of symbols. 11836 // SymbolsKey used for HashTable where key is array of symbols.
11837 class SymbolsKey : public HashTableKey { 11837 class SymbolsKey : public HashTableKey {
11838 public: 11838 public:
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
11977 return HashTable<Shape, Key>::EnsureCapacity(n, key); 11977 return HashTable<Shape, Key>::EnsureCapacity(n, key);
11978 } 11978 }
11979 11979
11980 11980
11981 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { 11981 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) {
11982 // Do nothing if the interval [from, to) is empty. 11982 // Do nothing if the interval [from, to) is empty.
11983 if (from >= to) return; 11983 if (from >= to) return;
11984 11984
11985 Heap* heap = GetHeap(); 11985 Heap* heap = GetHeap();
11986 int removed_entries = 0; 11986 int removed_entries = 0;
11987 Object* sentinel = heap->null_value(); 11987 Object* the_hole_value = heap->the_hole_value();
11988 int capacity = Capacity(); 11988 int capacity = Capacity();
11989 for (int i = 0; i < capacity; i++) { 11989 for (int i = 0; i < capacity; i++) {
11990 Object* key = KeyAt(i); 11990 Object* key = KeyAt(i);
11991 if (key->IsNumber()) { 11991 if (key->IsNumber()) {
11992 uint32_t number = static_cast<uint32_t>(key->Number()); 11992 uint32_t number = static_cast<uint32_t>(key->Number());
11993 if (from <= number && number < to) { 11993 if (from <= number && number < to) {
11994 SetEntry(i, sentinel, sentinel); 11994 SetEntry(i, the_hole_value, the_hole_value);
11995 removed_entries++; 11995 removed_entries++;
11996 } 11996 }
11997 } 11997 }
11998 } 11998 }
11999 11999
12000 // Update the number of elements. 12000 // Update the number of elements.
12001 ElementsRemoved(removed_entries); 12001 ElementsRemoved(removed_entries);
12002 } 12002 }
12003 12003
12004 12004
12005 template<typename Shape, typename Key> 12005 template<typename Shape, typename Key>
12006 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, 12006 Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
12007 JSReceiver::DeleteMode mode) { 12007 JSReceiver::DeleteMode mode) {
12008 Heap* heap = Dictionary<Shape, Key>::GetHeap(); 12008 Heap* heap = Dictionary<Shape, Key>::GetHeap();
12009 PropertyDetails details = DetailsAt(entry); 12009 PropertyDetails details = DetailsAt(entry);
12010 // Ignore attributes if forcing a deletion. 12010 // Ignore attributes if forcing a deletion.
12011 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { 12011 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) {
12012 return heap->false_value(); 12012 return heap->false_value();
12013 } 12013 }
12014 SetEntry(entry, heap->null_value(), heap->null_value()); 12014 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value());
12015 HashTable<Shape, Key>::ElementRemoved(); 12015 HashTable<Shape, Key>::ElementRemoved();
12016 return heap->true_value(); 12016 return heap->true_value();
12017 } 12017 }
12018 12018
12019 12019
12020 template<typename Shape, typename Key> 12020 template<typename Shape, typename Key>
12021 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { 12021 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) {
12022 return HashTable<Shape, Key>::Shrink(key); 12022 return HashTable<Shape, Key>::Shrink(key);
12023 } 12023 }
12024 12024
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
12388 12388
12389 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 12389 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
12390 // Check that it really works. 12390 // Check that it really works.
12391 ASSERT(obj->HasFastProperties()); 12391 ASSERT(obj->HasFastProperties());
12392 12392
12393 return obj; 12393 return obj;
12394 } 12394 }
12395 12395
12396 12396
12397 bool ObjectHashSet::Contains(Object* key) { 12397 bool ObjectHashSet::Contains(Object* key) {
12398 ASSERT(IsKey(key));
12399
12398 // If the object does not have an identity hash, it was never used as a key. 12400 // If the object does not have an identity hash, it was never used as a key.
12399 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 12401 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12400 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false; 12402 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false;
12401 } 12403 }
12402 return (FindEntry(key) != kNotFound); 12404 return (FindEntry(key) != kNotFound);
12403 } 12405 }
12404 12406
12405 12407
12406 MaybeObject* ObjectHashSet::Add(Object* key) { 12408 MaybeObject* ObjectHashSet::Add(Object* key) {
12409 ASSERT(IsKey(key));
12410
12407 // Make sure the key object has an identity hash code. 12411 // Make sure the key object has an identity hash code.
12408 int hash; 12412 int hash;
12409 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 12413 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
12410 if (maybe_hash->IsFailure()) return maybe_hash; 12414 if (maybe_hash->IsFailure()) return maybe_hash;
12411 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); 12415 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
12412 } 12416 }
12413 int entry = FindEntry(key); 12417 int entry = FindEntry(key);
12414 12418
12415 // Check whether key is already present. 12419 // Check whether key is already present.
12416 if (entry != kNotFound) return this; 12420 if (entry != kNotFound) return this;
12417 12421
12418 // Check whether the hash set should be extended and add entry. 12422 // Check whether the hash set should be extended and add entry.
12419 Object* obj; 12423 Object* obj;
12420 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 12424 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
12421 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 12425 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
12422 } 12426 }
12423 ObjectHashSet* table = ObjectHashSet::cast(obj); 12427 ObjectHashSet* table = ObjectHashSet::cast(obj);
12424 entry = table->FindInsertionEntry(hash); 12428 entry = table->FindInsertionEntry(hash);
12425 table->set(EntryToIndex(entry), key); 12429 table->set(EntryToIndex(entry), key);
12426 table->ElementAdded(); 12430 table->ElementAdded();
12427 return table; 12431 return table;
12428 } 12432 }
12429 12433
12430 12434
12431 MaybeObject* ObjectHashSet::Remove(Object* key) { 12435 MaybeObject* ObjectHashSet::Remove(Object* key) {
12436 ASSERT(IsKey(key));
12437
12432 // If the object does not have an identity hash, it was never used as a key. 12438 // If the object does not have an identity hash, it was never used as a key.
12433 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 12439 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12434 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this; 12440 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this;
12435 } 12441 }
12436 int entry = FindEntry(key); 12442 int entry = FindEntry(key);
12437 12443
12438 // Check whether key is actually present. 12444 // Check whether key is actually present.
12439 if (entry == kNotFound) return this; 12445 if (entry == kNotFound) return this;
12440 12446
12441 // Remove entry and try to shrink this hash set. 12447 // Remove entry and try to shrink this hash set.
12442 set_null(EntryToIndex(entry)); 12448 set_the_hole(EntryToIndex(entry));
12443 ElementRemoved(); 12449 ElementRemoved();
12444 return Shrink(key); 12450 return Shrink(key);
12445 } 12451 }
12446 12452
12447 12453
12448 Object* ObjectHashTable::Lookup(Object* key) { 12454 Object* ObjectHashTable::Lookup(Object* key) {
12455 ASSERT(IsKey(key));
12456
12449 // If the object does not have an identity hash, it was never used as a key. 12457 // If the object does not have an identity hash, it was never used as a key.
12450 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 12458 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12451 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { 12459 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) {
12452 return GetHeap()->undefined_value(); 12460 return GetHeap()->undefined_value();
12453 } 12461 }
12454 } 12462 }
12455 int entry = FindEntry(key); 12463 int entry = FindEntry(key);
12456 if (entry == kNotFound) return GetHeap()->undefined_value(); 12464 if (entry == kNotFound) return GetHeap()->undefined_value();
12457 return get(EntryToIndex(entry) + 1); 12465 return get(EntryToIndex(entry) + 1);
12458 } 12466 }
12459 12467
12460 12468
12461 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { 12469 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
12470 ASSERT(IsKey(key));
12471
12462 // Make sure the key object has an identity hash code. 12472 // Make sure the key object has an identity hash code.
12463 int hash; 12473 int hash;
12464 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 12474 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
12465 if (maybe_hash->IsFailure()) return maybe_hash; 12475 if (maybe_hash->IsFailure()) return maybe_hash;
12466 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); 12476 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
12467 } 12477 }
12468 int entry = FindEntry(key); 12478 int entry = FindEntry(key);
12469 12479
12470 // Check whether to perform removal operation. 12480 // Check whether to perform removal operation.
12471 if (value->IsUndefined()) { 12481 if (value->IsUndefined()) {
(...skipping 19 matching lines...) Expand all
12491 } 12501 }
12492 12502
12493 12503
12494 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { 12504 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
12495 set(EntryToIndex(entry), key); 12505 set(EntryToIndex(entry), key);
12496 set(EntryToIndex(entry) + 1, value); 12506 set(EntryToIndex(entry) + 1, value);
12497 ElementAdded(); 12507 ElementAdded();
12498 } 12508 }
12499 12509
12500 12510
12501 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) { 12511 void ObjectHashTable::RemoveEntry(int entry) {
12502 set_null(heap, EntryToIndex(entry)); 12512 set_the_hole(EntryToIndex(entry));
12503 set_null(heap, EntryToIndex(entry) + 1); 12513 set_the_hole(EntryToIndex(entry) + 1);
12504 ElementRemoved(); 12514 ElementRemoved();
12505 } 12515 }
12506 12516
12507 12517
12508 #ifdef ENABLE_DEBUGGER_SUPPORT 12518 #ifdef ENABLE_DEBUGGER_SUPPORT
12509 // Check if there is a break point at this code position. 12519 // Check if there is a break point at this code position.
12510 bool DebugInfo::HasBreakPoint(int code_position) { 12520 bool DebugInfo::HasBreakPoint(int code_position) {
12511 // Get the break point info object for this code position. 12521 // Get the break point info object for this code position.
12512 Object* break_point_info = GetBreakPointInfo(code_position); 12522 Object* break_point_info = GetBreakPointInfo(code_position);
12513 12523
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
12752 if (break_point_objects()->IsUndefined()) return 0; 12762 if (break_point_objects()->IsUndefined()) return 0;
12753 // Single break point. 12763 // Single break point.
12754 if (!break_point_objects()->IsFixedArray()) return 1; 12764 if (!break_point_objects()->IsFixedArray()) return 1;
12755 // Multiple break points. 12765 // Multiple break points.
12756 return FixedArray::cast(break_point_objects())->length(); 12766 return FixedArray::cast(break_point_objects())->length();
12757 } 12767 }
12758 #endif // ENABLE_DEBUGGER_SUPPORT 12768 #endif // ENABLE_DEBUGGER_SUPPORT
12759 12769
12760 12770
12761 } } // namespace v8::internal 12771 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | src/objects-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698