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

Side by Side Diff: src/objects.cc

Issue 7385006: Reintroduced dictionary that can use objects as keys. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporated review by Vitaly Repeshko. Created 9 years, 4 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
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2949 matching lines...) Expand 10 before | Expand all | Expand 10 after
2960 PrintF("Object elements have been normalized:\n"); 2960 PrintF("Object elements have been normalized:\n");
2961 Print(); 2961 Print();
2962 } 2962 }
2963 #endif 2963 #endif
2964 2964
2965 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 2965 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
2966 return dictionary; 2966 return dictionary;
2967 } 2967 }
2968 2968
2969 2969
2970 MaybeObject* JSObject::GetHiddenProperties(HiddenPropertiesFlag flag) {
2971 Isolate* isolate = GetIsolate();
2972 Heap* heap = isolate->heap();
2973 Object* holder = BypassGlobalProxy();
2974 if (holder->IsUndefined()) return heap->undefined_value();
2975 JSObject* obj = JSObject::cast(holder);
2976 if (obj->HasFastProperties()) {
2977 // If the object has fast properties, check whether the first slot
2978 // in the descriptor array matches the hidden symbol. Since the
2979 // hidden symbols hash code is zero (and no other string has hash
2980 // code zero) it will always occupy the first entry if present.
2981 DescriptorArray* descriptors = obj->map()->instance_descriptors();
2982 if ((descriptors->number_of_descriptors() > 0) &&
2983 (descriptors->GetKey(0) == heap->hidden_symbol()) &&
2984 descriptors->IsProperty(0)) {
2985 ASSERT(descriptors->GetType(0) == FIELD);
2986 return obj->FastPropertyAt(descriptors->GetFieldIndex(0));
2987 }
2988 }
2989
2990 // Only attempt to find the hidden properties in the local object and not
2991 // in the prototype chain.
2992 if (!obj->HasHiddenPropertiesObject()) {
2993 // Hidden properties object not found. Allocate a new hidden properties
2994 // object if requested. Otherwise return the undefined value.
2995 if (flag == ALLOW_CREATION) {
2996 Object* hidden_obj;
2997 { MaybeObject* maybe_obj = heap->AllocateJSObject(
2998 isolate->context()->global_context()->object_function());
2999 if (!maybe_obj->ToObject(&hidden_obj)) return maybe_obj;
3000 }
3001 return obj->SetHiddenPropertiesObject(hidden_obj);
3002 } else {
3003 return heap->undefined_value();
3004 }
3005 }
3006 return obj->GetHiddenPropertiesObject();
3007 }
3008
3009
3010 MaybeObject* JSObject::GetIdentityHash(HiddenPropertiesFlag flag) {
3011 Isolate* isolate = GetIsolate();
3012 Object* hidden_props_obj;
3013 { MaybeObject* maybe_obj = GetHiddenProperties(flag);
3014 if (!maybe_obj->ToObject(&hidden_props_obj)) return maybe_obj;
3015 }
3016 if (!hidden_props_obj->IsJSObject()) {
3017 // We failed to create hidden properties. That's a detached
3018 // global proxy.
3019 ASSERT(hidden_props_obj->IsUndefined());
3020 return Smi::FromInt(0);
3021 }
3022 JSObject* hidden_props = JSObject::cast(hidden_props_obj);
3023 String* hash_symbol = isolate->heap()->identity_hash_symbol();
3024 {
3025 // Note that HasLocalProperty() can cause a GC in the general case in the
3026 // presence of interceptors.
3027 AssertNoAllocation no_alloc;
3028 if (hidden_props->HasLocalProperty(hash_symbol)) {
3029 MaybeObject* hash = hidden_props->GetProperty(hash_symbol);
3030 return Smi::cast(hash->ToObjectChecked());
3031 }
3032 }
3033
3034 int hash_value;
3035 int attempts = 0;
3036 do {
3037 // Generate a random 32-bit hash value but limit range to fit
3038 // within a smi.
3039 hash_value = V8::Random(isolate) & Smi::kMaxValue;
3040 attempts++;
3041 } while (hash_value == 0 && attempts < 30);
3042 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
3043
3044 Smi* hash = Smi::FromInt(hash_value);
3045 { MaybeObject* result = hidden_props->SetLocalPropertyIgnoreAttributes(
3046 hash_symbol,
3047 hash,
3048 static_cast<PropertyAttributes>(None));
3049 if (result->IsFailure()) return result;
3050 }
3051 return hash;
3052 }
3053
3054
2970 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 3055 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
2971 DeleteMode mode) { 3056 DeleteMode mode) {
2972 // Check local property, ignore interceptor. 3057 // Check local property, ignore interceptor.
2973 LookupResult result; 3058 LookupResult result;
2974 LocalLookupRealNamedProperty(name, &result); 3059 LocalLookupRealNamedProperty(name, &result);
2975 if (!result.IsProperty()) return GetHeap()->true_value(); 3060 if (!result.IsProperty()) return GetHeap()->true_value();
2976 3061
2977 // Normalize object if needed. 3062 // Normalize object if needed.
2978 Object* obj; 3063 Object* obj;
2979 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 3064 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
(...skipping 7393 matching lines...) Expand 10 before | Expand all | Expand 10 after
10373 10458
10374 // Force instantiation of template instances class. 10459 // Force instantiation of template instances class.
10375 // Please note this list is compiler dependent. 10460 // Please note this list is compiler dependent.
10376 10461
10377 template class HashTable<SymbolTableShape, HashTableKey*>; 10462 template class HashTable<SymbolTableShape, HashTableKey*>;
10378 10463
10379 template class HashTable<CompilationCacheShape, HashTableKey*>; 10464 template class HashTable<CompilationCacheShape, HashTableKey*>;
10380 10465
10381 template class HashTable<MapCacheShape, HashTableKey*>; 10466 template class HashTable<MapCacheShape, HashTableKey*>;
10382 10467
10468 template class HashTable<ObjectHashTableShape, JSObject*>;
10469
10383 template class Dictionary<StringDictionaryShape, String*>; 10470 template class Dictionary<StringDictionaryShape, String*>;
10384 10471
10385 template class Dictionary<NumberDictionaryShape, uint32_t>; 10472 template class Dictionary<NumberDictionaryShape, uint32_t>;
10386 10473
10387 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( 10474 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
10388 int); 10475 int);
10389 10476
10390 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( 10477 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
10391 int); 10478 int);
10392 10479
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
11684 ASSERT(obj->IsJSObject()); 11771 ASSERT(obj->IsJSObject());
11685 11772
11686 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 11773 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
11687 // Check that it really works. 11774 // Check that it really works.
11688 ASSERT(obj->HasFastProperties()); 11775 ASSERT(obj->HasFastProperties());
11689 11776
11690 return obj; 11777 return obj;
11691 } 11778 }
11692 11779
11693 11780
11781 Object* ObjectHashTable::Lookup(JSObject* key) {
11782 // If the object does not have an identity hash, it was never used as a key.
11783 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
11784 if (maybe_hash->IsFailure()) return GetHeap()->undefined_value();
11785 int entry = FindEntry(key);
11786 if (entry == kNotFound) return GetHeap()->undefined_value();
11787 return get(EntryToIndex(entry) + 1);
11788 }
11789
11790
11791 MaybeObject* ObjectHashTable::Put(JSObject* key, Object* value) {
11792 // Make sure the key object has an identity hash code.
11793 int hash;
11794 { MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::ALLOW_CREATION);
11795 if (maybe_hash->IsFailure()) return maybe_hash;
11796 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
11797 }
11798 int entry = FindEntry(key);
11799
11800 // Check whether to perform removal operation.
11801 if (value->IsUndefined()) {
11802 if (entry == kNotFound) return this;
11803 RemoveEntry(entry);
11804 return Shrink(key);
11805 }
11806
11807 // Key is already in table, just overwrite value.
11808 if (entry != kNotFound) {
11809 set(EntryToIndex(entry) + 1, value);
11810 return this;
11811 }
11812
11813 // Check whether the hash table should be extended.
11814 Object* obj;
11815 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
11816 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11817 }
11818 ObjectHashTable* table = ObjectHashTable::cast(obj);
11819 table->AddEntry(table->FindInsertionEntry(hash), key, value);
11820 return table;
11821 }
11822
11823
11824 void ObjectHashTable::AddEntry(int entry, JSObject* key, Object* value) {
11825 set(EntryToIndex(entry), key);
11826 set(EntryToIndex(entry) + 1, value);
11827 ElementAdded();
11828 }
11829
11830
11831 void ObjectHashTable::RemoveEntry(int entry) {
11832 Object* null_value = GetHeap()->null_value();
11833 set(EntryToIndex(entry), null_value);
11834 set(EntryToIndex(entry) + 1, null_value);
11835 ElementRemoved();
11836 }
11837
11838
11694 #ifdef ENABLE_DEBUGGER_SUPPORT 11839 #ifdef ENABLE_DEBUGGER_SUPPORT
11695 // Check if there is a break point at this code position. 11840 // Check if there is a break point at this code position.
11696 bool DebugInfo::HasBreakPoint(int code_position) { 11841 bool DebugInfo::HasBreakPoint(int code_position) {
11697 // Get the break point info object for this code position. 11842 // Get the break point info object for this code position.
11698 Object* break_point_info = GetBreakPointInfo(code_position); 11843 Object* break_point_info = GetBreakPointInfo(code_position);
11699 11844
11700 // If there is no break point info object or no break points in the break 11845 // If there is no break point info object or no break points in the break
11701 // point info object there is no break point at this code position. 11846 // point info object there is no break point at this code position.
11702 if (break_point_info->IsUndefined()) return false; 11847 if (break_point_info->IsUndefined()) return false;
11703 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; 11848 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
11938 if (break_point_objects()->IsUndefined()) return 0; 12083 if (break_point_objects()->IsUndefined()) return 0;
11939 // Single beak point. 12084 // Single beak point.
11940 if (!break_point_objects()->IsFixedArray()) return 1; 12085 if (!break_point_objects()->IsFixedArray()) return 1;
11941 // Multiple break points. 12086 // Multiple break points.
11942 return FixedArray::cast(break_point_objects())->length(); 12087 return FixedArray::cast(break_point_objects())->length();
11943 } 12088 }
11944 #endif 12089 #endif
11945 12090
11946 12091
11947 } } // namespace v8::internal 12092 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698