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

Side by Side Diff: src/objects.cc

Issue 7349005: Added dictionary that can use objects as keys. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added unit test to gyp buildfile as well. Created 9 years, 5 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 2876 matching lines...) Expand 10 before | Expand all | Expand 10 after
2887 PrintF("Object elements have been normalized:\n"); 2887 PrintF("Object elements have been normalized:\n");
2888 Print(); 2888 Print();
2889 } 2889 }
2890 #endif 2890 #endif
2891 2891
2892 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 2892 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
2893 return dictionary; 2893 return dictionary;
2894 } 2894 }
2895 2895
2896 2896
2897 MaybeObject* JSObject::GetHiddenProperties(bool create_if_needed) {
2898 Isolate* isolate = GetIsolate();
2899 Heap* heap = isolate->heap();
2900 if (HasFastProperties()) {
2901 // If the object has fast properties, check whether the first slot
2902 // in the descriptor array matches the hidden symbol. Since the
2903 // hidden symbols hash code is zero (and no other string has hash
2904 // code zero) it will always occupy the first entry if present.
2905 DescriptorArray* descriptors = map()->instance_descriptors();
2906 if ((descriptors->number_of_descriptors() > 0) &&
2907 (descriptors->GetKey(0) == heap->hidden_symbol()) &&
2908 descriptors->IsProperty(0)) {
2909 ASSERT(descriptors->GetType(0) == FIELD);
2910 return FastPropertyAt(descriptors->GetFieldIndex(0));
2911 }
2912 }
2913
2914 // Only attempt to find the hidden properties in the local object and not
2915 // in the prototype chain. Note that HasLocalProperty() can cause a GC in
2916 // the general case in the presence of interceptors.
2917 if (!HasHiddenPropertiesObject()) {
2918 // Hidden properties object not found. Allocate a new hidden properties
2919 // object if requested. Otherwise return the undefined value.
2920 if (create_if_needed) {
2921 Object* hidden_obj;
2922 { MaybeObject* maybe_obj = heap->AllocateJSObject(
2923 isolate->context()->global_context()->object_function());
2924 if (!maybe_obj->ToObject(&hidden_obj)) return maybe_obj;
2925 }
2926 return SetHiddenPropertiesObject(hidden_obj);
2927 } else {
2928 return heap->undefined_value();
2929 }
2930 }
2931 return GetHiddenPropertiesObject();
2932 }
2933
2934
2935 MaybeObject* JSObject::GetIdentityHash() {
2936 Isolate* isolate = GetIsolate();
2937 Object* hidden_props_obj;
2938 { MaybeObject* maybe_obj = GetHiddenProperties(true);
2939 if (!maybe_obj->ToObject(&hidden_props_obj)) return maybe_obj;
2940 }
2941 if (!hidden_props_obj->IsJSObject()) {
2942 // We failed to create hidden properties. That's a detached
2943 // global proxy.
2944 ASSERT(hidden_props_obj->IsUndefined());
2945 return Smi::FromInt(0);
2946 }
2947 JSObject* hidden_props = JSObject::cast(hidden_props_obj);
2948 String* hash_symbol = isolate->heap()->identity_hash_symbol();
2949 if (hidden_props->HasLocalProperty(hash_symbol)) {
2950 MaybeObject* hash = hidden_props->GetProperty(hash_symbol);
2951 return Smi::cast(hash->ToObjectChecked());
2952 }
2953
2954 int hash_value;
2955 int attempts = 0;
2956 do {
2957 // Generate a random 32-bit hash value but limit range to fit
2958 // within a smi.
2959 hash_value = V8::Random(isolate) & Smi::kMaxValue;
2960 attempts++;
2961 } while (hash_value == 0 && attempts < 30);
2962 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
2963
2964 Smi* hash = Smi::FromInt(hash_value);
2965 { MaybeObject* result = hidden_props->SetLocalPropertyIgnoreAttributes(
2966 hash_symbol,
2967 hash,
2968 static_cast<PropertyAttributes>(None));
2969 if (result->IsFailure()) return result;
2970 }
2971 return hash;
2972 }
2973
2974
2897 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 2975 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
2898 DeleteMode mode) { 2976 DeleteMode mode) {
2899 // Check local property, ignore interceptor. 2977 // Check local property, ignore interceptor.
2900 LookupResult result; 2978 LookupResult result;
2901 LocalLookupRealNamedProperty(name, &result); 2979 LocalLookupRealNamedProperty(name, &result);
2902 if (!result.IsProperty()) return GetHeap()->true_value(); 2980 if (!result.IsProperty()) return GetHeap()->true_value();
2903 2981
2904 // Normalize object if needed. 2982 // Normalize object if needed.
2905 Object* obj; 2983 Object* obj;
2906 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2984 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
(...skipping 7224 matching lines...) Expand 10 before | Expand all | Expand 10 after
10131 template class HashTable<SymbolTableShape, HashTableKey*>; 10209 template class HashTable<SymbolTableShape, HashTableKey*>;
10132 10210
10133 template class HashTable<CompilationCacheShape, HashTableKey*>; 10211 template class HashTable<CompilationCacheShape, HashTableKey*>;
10134 10212
10135 template class HashTable<MapCacheShape, HashTableKey*>; 10213 template class HashTable<MapCacheShape, HashTableKey*>;
10136 10214
10137 template class Dictionary<StringDictionaryShape, String*>; 10215 template class Dictionary<StringDictionaryShape, String*>;
10138 10216
10139 template class Dictionary<NumberDictionaryShape, uint32_t>; 10217 template class Dictionary<NumberDictionaryShape, uint32_t>;
10140 10218
10219 template class Dictionary<ObjectDictionaryShape, JSObject*>;
10220
10141 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( 10221 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
10142 int); 10222 int);
10143 10223
10144 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( 10224 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
10145 int); 10225 int);
10146 10226
10227 template MaybeObject* Dictionary<ObjectDictionaryShape, JSObject*>::Allocate(
10228 int);
10229
10147 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( 10230 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut(
10148 uint32_t, Object*); 10231 uint32_t, Object*);
10149 10232
10150 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( 10233 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup(
10151 Object*); 10234 Object*);
10152 10235
10153 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( 10236 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup(
10154 Object*); 10237 Object*);
10155 10238
10156 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( 10239 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo(
(...skipping 17 matching lines...) Expand all
10174 FixedArray*, 10257 FixedArray*,
10175 Dictionary<StringDictionaryShape, String*>::SortMode); 10258 Dictionary<StringDictionaryShape, String*>::SortMode);
10176 10259
10177 template int 10260 template int
10178 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( 10261 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
10179 PropertyAttributes); 10262 PropertyAttributes);
10180 10263
10181 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( 10264 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add(
10182 String*, Object*, PropertyDetails); 10265 String*, Object*, PropertyDetails);
10183 10266
10267 template MaybeObject* Dictionary<ObjectDictionaryShape, JSObject*>::Add(
10268 JSObject*, Object*, PropertyDetails);
10269
10184 template MaybeObject* 10270 template MaybeObject*
10185 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); 10271 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices();
10186 10272
10187 template int 10273 template int
10188 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes( 10274 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes(
10189 PropertyAttributes); 10275 PropertyAttributes);
10190 10276
10191 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add( 10277 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add(
10192 uint32_t, Object*, PropertyDetails); 10278 uint32_t, Object*, PropertyDetails);
10193 10279
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
11133 // Insert element at empty or deleted entry 11219 // Insert element at empty or deleted entry
11134 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { 11220 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) {
11135 // Assign an enumeration index to the property and update 11221 // Assign an enumeration index to the property and update
11136 // SetNextEnumerationIndex. 11222 // SetNextEnumerationIndex.
11137 int index = NextEnumerationIndex(); 11223 int index = NextEnumerationIndex();
11138 details = PropertyDetails(details.attributes(), details.type(), index); 11224 details = PropertyDetails(details.attributes(), details.type(), index);
11139 SetNextEnumerationIndex(index + 1); 11225 SetNextEnumerationIndex(index + 1);
11140 } 11226 }
11141 SetEntry(entry, k, value, details); 11227 SetEntry(entry, k, value, details);
11142 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() 11228 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber()
11143 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); 11229 || Dictionary<Shape, Key>::KeyAt(entry)->IsString()
11230 || Dictionary<Shape, Key>::KeyAt(entry)->IsJSObject()));
11144 HashTable<Shape, Key>::ElementAdded(); 11231 HashTable<Shape, Key>::ElementAdded();
11145 return this; 11232 return this;
11146 } 11233 }
11147 11234
11148 11235
11149 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { 11236 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) {
11150 // If the dictionary requires slow elements an element has already 11237 // If the dictionary requires slow elements an element has already
11151 // been added at a high index. 11238 // been added at a high index.
11152 if (requires_slow_elements()) return; 11239 if (requires_slow_elements()) return;
11153 // Check if this index is high enough that we should require slow 11240 // Check if this index is high enough that we should require slow
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
11438 ASSERT(obj->IsJSObject()); 11525 ASSERT(obj->IsJSObject());
11439 11526
11440 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 11527 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
11441 // Check that it really works. 11528 // Check that it really works.
11442 ASSERT(obj->HasFastProperties()); 11529 ASSERT(obj->HasFastProperties());
11443 11530
11444 return obj; 11531 return obj;
11445 } 11532 }
11446 11533
11447 11534
11535 MaybeObject* ObjectDictionary::AddChecked(JSObject* key, Object* value) {
11536 // Make sure the key object has an identity hash code.
11537 MaybeObject* maybe_hash = key->GetIdentityHash();
11538 if (maybe_hash->IsFailure()) return maybe_hash;
11539 PropertyDetails details(NONE, NORMAL);
11540 return Add(key, value, details);
11541 }
11542
11543
11448 #ifdef ENABLE_DEBUGGER_SUPPORT 11544 #ifdef ENABLE_DEBUGGER_SUPPORT
11449 // Check if there is a break point at this code position. 11545 // Check if there is a break point at this code position.
11450 bool DebugInfo::HasBreakPoint(int code_position) { 11546 bool DebugInfo::HasBreakPoint(int code_position) {
11451 // Get the break point info object for this code position. 11547 // Get the break point info object for this code position.
11452 Object* break_point_info = GetBreakPointInfo(code_position); 11548 Object* break_point_info = GetBreakPointInfo(code_position);
11453 11549
11454 // If there is no break point info object or no break points in the break 11550 // If there is no break point info object or no break points in the break
11455 // point info object there is no break point at this code position. 11551 // point info object there is no break point at this code position.
11456 if (break_point_info->IsUndefined()) return false; 11552 if (break_point_info->IsUndefined()) return false;
11457 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; 11553 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
11692 if (break_point_objects()->IsUndefined()) return 0; 11788 if (break_point_objects()->IsUndefined()) return 0;
11693 // Single beak point. 11789 // Single beak point.
11694 if (!break_point_objects()->IsFixedArray()) return 1; 11790 if (!break_point_objects()->IsFixedArray()) return 1;
11695 // Multiple break points. 11791 // Multiple break points.
11696 return FixedArray::cast(break_point_objects())->length(); 11792 return FixedArray::cast(break_point_objects())->length();
11697 } 11793 }
11698 #endif 11794 #endif
11699 11795
11700 11796
11701 } } // namespace v8::internal 11797 } } // 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