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

Side by Side Diff: src/objects.cc

Issue 8372027: Implement Harmony sets and maps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Andreas Rossberg. Created 9 years, 2 months 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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 return context->string_function()->instance_prototype(); 716 return context->string_function()->instance_prototype();
717 } 717 }
718 if (heap_object->IsBoolean()) { 718 if (heap_object->IsBoolean()) {
719 return context->boolean_function()->instance_prototype(); 719 return context->boolean_function()->instance_prototype();
720 } else { 720 } else {
721 return heap->null_value(); 721 return heap->null_value();
722 } 722 }
723 } 723 }
724 724
725 725
726 MaybeObject* Object::GetHash(CreationFlag flag) {
727 // The object is either a number, a string, an odd-ball,
728 // a real JS object, or a Harmony proxy.
729 if (IsNumber()) {
730 uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
731 return Smi::FromInt(hash & Smi::kMaxValue);
732 }
733 if (IsString()) {
734 uint32_t hash = String::cast(this)->Hash();
735 return Smi::FromInt(hash);
736 }
737 if (IsOddball()) {
738 uint32_t hash = Oddball::cast(this)->to_string()->Hash();
739 return Smi::FromInt(hash);
740 }
741 if (IsJSReceiver()) {
742 return JSReceiver::cast(this)->GetIdentityHash(flag);
743 }
744
745 UNREACHABLE();
746 return Smi::FromInt(0);
747 }
748
749
750 bool Object::SameValue(Object* other) {
751 if (other == this) return true;
752 if (!IsHeapObject() || !other->IsHeapObject()) return false;
753
754 // The object is either a number, a string, an odd-ball,
755 // a real JS object, or a Harmony proxy.
756 if (IsNumber() && other->IsNumber()) {
757 double this_value = Number();
758 double other_value = other->Number();
759 return (this_value == other_value) ||
760 (isnan(this_value) && isnan(other_value));
761 }
762 if (IsString() && other->IsString()) {
763 return String::cast(this)->Equals(String::cast(other));
764 }
765 return false;
766 }
767
768
726 void Object::ShortPrint(FILE* out) { 769 void Object::ShortPrint(FILE* out) {
727 HeapStringAllocator allocator; 770 HeapStringAllocator allocator;
728 StringStream accumulator(&allocator); 771 StringStream accumulator(&allocator);
729 ShortPrint(&accumulator); 772 ShortPrint(&accumulator);
730 accumulator.OutputToFile(out); 773 accumulator.OutputToFile(out);
731 } 774 }
732 775
733 776
734 void Object::ShortPrint(StringStream* accumulator) { 777 void Object::ShortPrint(StringStream* accumulator) {
735 if (IsSmi()) { 778 if (IsSmi()) {
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 switch (type) { 1306 switch (type) {
1264 case FIXED_ARRAY_TYPE: 1307 case FIXED_ARRAY_TYPE:
1265 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); 1308 FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1266 break; 1309 break;
1267 case FIXED_DOUBLE_ARRAY_TYPE: 1310 case FIXED_DOUBLE_ARRAY_TYPE:
1268 break; 1311 break;
1269 case JS_OBJECT_TYPE: 1312 case JS_OBJECT_TYPE:
1270 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 1313 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1271 case JS_VALUE_TYPE: 1314 case JS_VALUE_TYPE:
1272 case JS_ARRAY_TYPE: 1315 case JS_ARRAY_TYPE:
1316 case JS_SET_TYPE:
1317 case JS_MAP_TYPE:
1273 case JS_WEAK_MAP_TYPE: 1318 case JS_WEAK_MAP_TYPE:
1274 case JS_REGEXP_TYPE: 1319 case JS_REGEXP_TYPE:
1275 case JS_GLOBAL_PROXY_TYPE: 1320 case JS_GLOBAL_PROXY_TYPE:
1276 case JS_GLOBAL_OBJECT_TYPE: 1321 case JS_GLOBAL_OBJECT_TYPE:
1277 case JS_BUILTINS_OBJECT_TYPE: 1322 case JS_BUILTINS_OBJECT_TYPE:
1278 case JS_MESSAGE_OBJECT_TYPE: 1323 case JS_MESSAGE_OBJECT_TYPE:
1279 JSObject::BodyDescriptor::IterateBody(this, object_size, v); 1324 JSObject::BodyDescriptor::IterateBody(this, object_size, v);
1280 break; 1325 break;
1281 case JS_FUNCTION_TYPE: 1326 case JS_FUNCTION_TYPE:
1282 reinterpret_cast<JSFunction*>(this) 1327 reinterpret_cast<JSFunction*>(this)
(...skipping 9537 matching lines...) Expand 10 before | Expand all | Expand 10 after
10820 10865
10821 // Force instantiation of template instances class. 10866 // Force instantiation of template instances class.
10822 // Please note this list is compiler dependent. 10867 // Please note this list is compiler dependent.
10823 10868
10824 template class HashTable<SymbolTableShape, HashTableKey*>; 10869 template class HashTable<SymbolTableShape, HashTableKey*>;
10825 10870
10826 template class HashTable<CompilationCacheShape, HashTableKey*>; 10871 template class HashTable<CompilationCacheShape, HashTableKey*>;
10827 10872
10828 template class HashTable<MapCacheShape, HashTableKey*>; 10873 template class HashTable<MapCacheShape, HashTableKey*>;
10829 10874
10830 template class HashTable<ObjectHashTableShape, JSReceiver*>; 10875 template class HashTable<ObjectHashTableShape<1>, Object*>;
10876
10877 template class HashTable<ObjectHashTableShape<2>, Object*>;
10831 10878
10832 template class Dictionary<StringDictionaryShape, String*>; 10879 template class Dictionary<StringDictionaryShape, String*>;
10833 10880
10834 template class Dictionary<NumberDictionaryShape, uint32_t>; 10881 template class Dictionary<NumberDictionaryShape, uint32_t>;
10835 10882
10836 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( 10883 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
10837 int); 10884 int);
10838 10885
10839 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( 10886 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
10840 int); 10887 int);
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after
12166 ASSERT(obj->IsJSObject()); 12213 ASSERT(obj->IsJSObject());
12167 12214
12168 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 12215 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
12169 // Check that it really works. 12216 // Check that it really works.
12170 ASSERT(obj->HasFastProperties()); 12217 ASSERT(obj->HasFastProperties());
12171 12218
12172 return obj; 12219 return obj;
12173 } 12220 }
12174 12221
12175 12222
12176 Object* ObjectHashTable::Lookup(JSReceiver* key) { 12223 bool ObjectHashSet::Contains(Object* key) {
12177 // If the object does not have an identity hash, it was never used as a key. 12224 // If the object does not have an identity hash, it was never used as a key.
12178 MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION); 12225 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12179 if (maybe_hash->IsFailure()) return GetHeap()->undefined_value(); 12226 if (maybe_hash->IsFailure()) return false;
12227 }
12228 return (FindEntry(key) != kNotFound);
12229 }
12230
12231
12232 MaybeObject* ObjectHashSet::Add(Object* key) {
12233 // Make sure the key object has an identity hash code.
12234 int hash;
12235 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
12236 if (maybe_hash->IsFailure()) return maybe_hash;
12237 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
12238 }
12239 int entry = FindEntry(key);
12240
12241 // Check whether key is already present.
12242 if (entry != kNotFound) return this;
12243
12244 // Check whether the hash set should be extended and add entry.
12245 Object* obj;
12246 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
12247 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
12248 }
12249 ObjectHashSet* table = ObjectHashSet::cast(obj);
12250 entry = table->FindInsertionEntry(hash);
12251 table->set(EntryToIndex(entry), key);
12252 table->ElementAdded();
12253 return table;
12254 }
12255
12256
12257 MaybeObject* ObjectHashSet::Remove(Object* key) {
12258 // If the object does not have an identity hash, it was never used as a key.
12259 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12260 if (maybe_hash->IsFailure()) return this;
12261 }
12262 int entry = FindEntry(key);
12263
12264 // Check whether key is actually present.
12265 if (entry == kNotFound) return this;
12266
12267 // Remove entry and try to shrink this hash set.
12268 set_null(EntryToIndex(entry));
12269 ElementRemoved();
12270 return Shrink(key);
12271 }
12272
12273
12274 Object* ObjectHashTable::Lookup(Object* key) {
12275 // If the object does not have an identity hash, it was never used as a key.
12276 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
12277 if (maybe_hash->IsFailure()) GetHeap()->undefined_value();
12278 }
12180 int entry = FindEntry(key); 12279 int entry = FindEntry(key);
12181 if (entry == kNotFound) return GetHeap()->undefined_value(); 12280 if (entry == kNotFound) return GetHeap()->undefined_value();
12182 return get(EntryToIndex(entry) + 1); 12281 return get(EntryToIndex(entry) + 1);
12183 } 12282 }
12184 12283
12185 12284
12186 MaybeObject* ObjectHashTable::Put(JSReceiver* key, Object* value) { 12285 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) {
12187 // Make sure the key object has an identity hash code. 12286 // Make sure the key object has an identity hash code.
12188 int hash; 12287 int hash;
12189 { MaybeObject* maybe_hash = key->GetIdentityHash(ALLOW_CREATION); 12288 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION);
12190 if (maybe_hash->IsFailure()) return maybe_hash; 12289 if (maybe_hash->IsFailure()) return maybe_hash;
12191 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value(); 12290 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
12192 } 12291 }
12193 int entry = FindEntry(key); 12292 int entry = FindEntry(key);
12194 12293
12195 // Check whether to perform removal operation. 12294 // Check whether to perform removal operation.
12196 if (value->IsUndefined()) { 12295 if (value->IsUndefined()) {
12197 if (entry == kNotFound) return this; 12296 if (entry == kNotFound) return this;
12198 RemoveEntry(entry); 12297 RemoveEntry(entry);
12199 return Shrink(key); 12298 return Shrink(key);
12200 } 12299 }
12201 12300
12202 // Key is already in table, just overwrite value. 12301 // Key is already in table, just overwrite value.
12203 if (entry != kNotFound) { 12302 if (entry != kNotFound) {
12204 set(EntryToIndex(entry) + 1, value); 12303 set(EntryToIndex(entry) + 1, value);
12205 return this; 12304 return this;
12206 } 12305 }
12207 12306
12208 // Check whether the hash table should be extended. 12307 // Check whether the hash table should be extended.
12209 Object* obj; 12308 Object* obj;
12210 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 12309 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
12211 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 12310 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
12212 } 12311 }
12213 ObjectHashTable* table = ObjectHashTable::cast(obj); 12312 ObjectHashTable* table = ObjectHashTable::cast(obj);
12214 table->AddEntry(table->FindInsertionEntry(hash), key, value); 12313 table->AddEntry(table->FindInsertionEntry(hash), key, value);
12215 return table; 12314 return table;
12216 } 12315 }
12217 12316
12218 12317
12219 void ObjectHashTable::AddEntry(int entry, JSReceiver* key, Object* value) { 12318 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
12220 set(EntryToIndex(entry), key); 12319 set(EntryToIndex(entry), key);
12221 set(EntryToIndex(entry) + 1, value); 12320 set(EntryToIndex(entry) + 1, value);
12222 ElementAdded(); 12321 ElementAdded();
12223 } 12322 }
12224 12323
12225 12324
12226 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) { 12325 void ObjectHashTable::RemoveEntry(int entry, Heap* heap) {
12227 set_null(heap, EntryToIndex(entry)); 12326 set_null(heap, EntryToIndex(entry));
12228 set_null(heap, EntryToIndex(entry) + 1); 12327 set_null(heap, EntryToIndex(entry) + 1);
12229 ElementRemoved(); 12328 ElementRemoved();
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
12477 if (break_point_objects()->IsUndefined()) return 0; 12576 if (break_point_objects()->IsUndefined()) return 0;
12478 // Single break point. 12577 // Single break point.
12479 if (!break_point_objects()->IsFixedArray()) return 1; 12578 if (!break_point_objects()->IsFixedArray()) return 1;
12480 // Multiple break points. 12579 // Multiple break points.
12481 return FixedArray::cast(break_point_objects())->length(); 12580 return FixedArray::cast(break_point_objects())->length();
12482 } 12581 }
12483 #endif // ENABLE_DEBUGGER_SUPPORT 12582 #endif // ENABLE_DEBUGGER_SUPPORT
12484 12583
12485 12584
12486 } } // namespace v8::internal 12585 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698