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

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

Powered by Google App Engine
This is Rietveld 408576698