Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2957 PrintF("Object elements have been normalized:\n"); | 2957 PrintF("Object elements have been normalized:\n"); |
| 2958 Print(); | 2958 Print(); |
| 2959 } | 2959 } |
| 2960 #endif | 2960 #endif |
| 2961 | 2961 |
| 2962 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 2962 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 2963 return dictionary; | 2963 return dictionary; |
| 2964 } | 2964 } |
| 2965 | 2965 |
| 2966 | 2966 |
| 2967 MaybeObject* JSObject::GetHiddenProperties(bool create_if_needed) { | |
| 2968 Isolate* isolate = GetIsolate(); | |
| 2969 Heap* heap = isolate->heap(); | |
| 2970 Object* holder = BypassGlobalProxy(); | |
| 2971 if (holder->IsUndefined()) return heap->undefined_value(); | |
| 2972 JSObject* obj = JSObject::cast(holder); | |
| 2973 if (obj->HasFastProperties()) { | |
| 2974 // If the object has fast properties, check whether the first slot | |
| 2975 // in the descriptor array matches the hidden symbol. Since the | |
| 2976 // hidden symbols hash code is zero (and no other string has hash | |
| 2977 // code zero) it will always occupy the first entry if present. | |
| 2978 DescriptorArray* descriptors = obj->map()->instance_descriptors(); | |
| 2979 if ((descriptors->number_of_descriptors() > 0) && | |
| 2980 (descriptors->GetKey(0) == heap->hidden_symbol()) && | |
| 2981 descriptors->IsProperty(0)) { | |
| 2982 ASSERT(descriptors->GetType(0) == FIELD); | |
| 2983 return obj->FastPropertyAt(descriptors->GetFieldIndex(0)); | |
| 2984 } | |
| 2985 } | |
| 2986 | |
| 2987 // Only attempt to find the hidden properties in the local object and not | |
| 2988 // in the prototype chain. Note that HasLocalProperty() can cause a GC in | |
|
Vitaly Repeshko
2011/07/26 13:53:14
The comment about HasLocalProperty should be moved
Michael Starzinger
2011/07/26 22:30:23
Fixed.
| |
| 2989 // the general case in the presence of interceptors. | |
| 2990 if (!obj->HasHiddenPropertiesObject()) { | |
| 2991 // Hidden properties object not found. Allocate a new hidden properties | |
| 2992 // object if requested. Otherwise return the undefined value. | |
| 2993 if (create_if_needed) { | |
| 2994 Object* hidden_obj; | |
| 2995 { MaybeObject* maybe_obj = heap->AllocateJSObject( | |
| 2996 isolate->context()->global_context()->object_function()); | |
| 2997 if (!maybe_obj->ToObject(&hidden_obj)) return maybe_obj; | |
| 2998 } | |
| 2999 return obj->SetHiddenPropertiesObject(hidden_obj); | |
| 3000 } else { | |
| 3001 return heap->undefined_value(); | |
| 3002 } | |
| 3003 } | |
| 3004 return obj->GetHiddenPropertiesObject(); | |
| 3005 } | |
| 3006 | |
| 3007 | |
| 3008 MaybeObject* JSObject::GetIdentityHash() { | |
| 3009 Isolate* isolate = GetIsolate(); | |
| 3010 Object* hidden_props_obj; | |
| 3011 { MaybeObject* maybe_obj = GetHiddenProperties(true); | |
| 3012 if (!maybe_obj->ToObject(&hidden_props_obj)) return maybe_obj; | |
| 3013 } | |
| 3014 if (!hidden_props_obj->IsJSObject()) { | |
| 3015 // We failed to create hidden properties. That's a detached | |
| 3016 // global proxy. | |
| 3017 ASSERT(hidden_props_obj->IsUndefined()); | |
| 3018 return Smi::FromInt(0); | |
| 3019 } | |
| 3020 JSObject* hidden_props = JSObject::cast(hidden_props_obj); | |
| 3021 String* hash_symbol = isolate->heap()->identity_hash_symbol(); | |
| 3022 if (hidden_props->HasLocalProperty(hash_symbol)) { | |
| 3023 MaybeObject* hash = hidden_props->GetProperty(hash_symbol); | |
| 3024 return Smi::cast(hash->ToObjectChecked()); | |
| 3025 } | |
| 3026 | |
| 3027 int hash_value; | |
| 3028 int attempts = 0; | |
| 3029 do { | |
| 3030 // Generate a random 32-bit hash value but limit range to fit | |
| 3031 // within a smi. | |
| 3032 hash_value = V8::Random(isolate) & Smi::kMaxValue; | |
| 3033 attempts++; | |
| 3034 } while (hash_value == 0 && attempts < 30); | |
| 3035 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | |
| 3036 | |
| 3037 Smi* hash = Smi::FromInt(hash_value); | |
| 3038 { MaybeObject* result = hidden_props->SetLocalPropertyIgnoreAttributes( | |
| 3039 hash_symbol, | |
| 3040 hash, | |
| 3041 static_cast<PropertyAttributes>(None)); | |
| 3042 if (result->IsFailure()) return result; | |
| 3043 } | |
| 3044 return hash; | |
| 3045 } | |
| 3046 | |
| 3047 | |
| 2967 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 3048 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, |
| 2968 DeleteMode mode) { | 3049 DeleteMode mode) { |
| 2969 // Check local property, ignore interceptor. | 3050 // Check local property, ignore interceptor. |
| 2970 LookupResult result; | 3051 LookupResult result; |
| 2971 LocalLookupRealNamedProperty(name, &result); | 3052 LocalLookupRealNamedProperty(name, &result); |
| 2972 if (!result.IsProperty()) return GetHeap()->true_value(); | 3053 if (!result.IsProperty()) return GetHeap()->true_value(); |
| 2973 | 3054 |
| 2974 // Normalize object if needed. | 3055 // Normalize object if needed. |
| 2975 Object* obj; | 3056 Object* obj; |
| 2976 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 3057 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| (...skipping 7389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10366 template class HashTable<SymbolTableShape, HashTableKey*>; | 10447 template class HashTable<SymbolTableShape, HashTableKey*>; |
| 10367 | 10448 |
| 10368 template class HashTable<CompilationCacheShape, HashTableKey*>; | 10449 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 10369 | 10450 |
| 10370 template class HashTable<MapCacheShape, HashTableKey*>; | 10451 template class HashTable<MapCacheShape, HashTableKey*>; |
| 10371 | 10452 |
| 10372 template class Dictionary<StringDictionaryShape, String*>; | 10453 template class Dictionary<StringDictionaryShape, String*>; |
| 10373 | 10454 |
| 10374 template class Dictionary<NumberDictionaryShape, uint32_t>; | 10455 template class Dictionary<NumberDictionaryShape, uint32_t>; |
| 10375 | 10456 |
| 10457 template class Dictionary<ObjectDictionaryShape, JSObject*>; | |
| 10458 | |
| 10376 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( | 10459 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( |
| 10377 int); | 10460 int); |
| 10378 | 10461 |
| 10379 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( | 10462 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( |
| 10380 int); | 10463 int); |
| 10381 | 10464 |
| 10465 template MaybeObject* Dictionary<ObjectDictionaryShape, JSObject*>::Allocate( | |
| 10466 int); | |
| 10467 | |
| 10382 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( | 10468 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( |
| 10383 uint32_t, Object*); | 10469 uint32_t, Object*); |
| 10384 | 10470 |
| 10385 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( | 10471 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( |
| 10386 Object*); | 10472 Object*); |
| 10387 | 10473 |
| 10388 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( | 10474 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( |
| 10389 Object*); | 10475 Object*); |
| 10390 | 10476 |
| 10391 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( | 10477 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11368 // Insert element at empty or deleted entry | 11454 // Insert element at empty or deleted entry |
| 11369 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { | 11455 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { |
| 11370 // Assign an enumeration index to the property and update | 11456 // Assign an enumeration index to the property and update |
| 11371 // SetNextEnumerationIndex. | 11457 // SetNextEnumerationIndex. |
| 11372 int index = NextEnumerationIndex(); | 11458 int index = NextEnumerationIndex(); |
| 11373 details = PropertyDetails(details.attributes(), details.type(), index); | 11459 details = PropertyDetails(details.attributes(), details.type(), index); |
| 11374 SetNextEnumerationIndex(index + 1); | 11460 SetNextEnumerationIndex(index + 1); |
| 11375 } | 11461 } |
| 11376 SetEntry(entry, k, value, details); | 11462 SetEntry(entry, k, value, details); |
| 11377 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() | 11463 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() |
| 11378 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); | 11464 || Dictionary<Shape, Key>::KeyAt(entry)->IsString() |
| 11465 || Dictionary<Shape, Key>::KeyAt(entry)->IsJSObject())); | |
| 11379 HashTable<Shape, Key>::ElementAdded(); | 11466 HashTable<Shape, Key>::ElementAdded(); |
| 11380 return this; | 11467 return this; |
| 11381 } | 11468 } |
| 11382 | 11469 |
| 11383 | 11470 |
| 11384 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 11471 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 11385 // If the dictionary requires slow elements an element has already | 11472 // If the dictionary requires slow elements an element has already |
| 11386 // been added at a high index. | 11473 // been added at a high index. |
| 11387 if (requires_slow_elements()) return; | 11474 if (requires_slow_elements()) return; |
| 11388 // Check if this index is high enough that we should require slow | 11475 // Check if this index is high enough that we should require slow |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11673 ASSERT(obj->IsJSObject()); | 11760 ASSERT(obj->IsJSObject()); |
| 11674 | 11761 |
| 11675 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); | 11762 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |
| 11676 // Check that it really works. | 11763 // Check that it really works. |
| 11677 ASSERT(obj->HasFastProperties()); | 11764 ASSERT(obj->HasFastProperties()); |
| 11678 | 11765 |
| 11679 return obj; | 11766 return obj; |
| 11680 } | 11767 } |
| 11681 | 11768 |
| 11682 | 11769 |
| 11770 int ObjectDictionary::FindEntry(JSObject* key) { | |
| 11771 // If the object does not have an identity hash, it was never used as a key. | |
| 11772 MaybeObject* maybe_hash = key->GetIdentityHash(); | |
|
Vitaly Repeshko
2011/07/26 13:53:14
It'd be nice to avoid allocating a hidden properti
Michael Starzinger
2011/07/26 22:30:23
Fixed (partially, didn't create an enum so far). I
Vitaly Repeshko
2011/07/27 15:42:26
Why do you want to add the enum in a separate CL?
Michael Starzinger
2011/07/28 01:23:18
Fixed. Ok. :)
| |
| 11773 if (maybe_hash->IsFailure()) return kNotFound; | |
| 11774 return Dictionary<ObjectDictionaryShape, JSObject*>::FindEntry(key); | |
| 11775 } | |
| 11776 | |
| 11777 | |
| 11778 MaybeObject* ObjectDictionary::Add(JSObject* key, Object* value) { | |
| 11779 // Make sure the key object has an identity hash code. | |
| 11780 MaybeObject* maybe_hash = key->GetIdentityHash(); | |
| 11781 if (maybe_hash->IsFailure()) return maybe_hash; | |
| 11782 PropertyDetails details(NONE, NORMAL); | |
| 11783 return Dictionary<ObjectDictionaryShape, JSObject*>::Add(key, value, details); | |
| 11784 } | |
| 11785 | |
| 11786 | |
| 11683 #ifdef ENABLE_DEBUGGER_SUPPORT | 11787 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 11684 // Check if there is a break point at this code position. | 11788 // Check if there is a break point at this code position. |
| 11685 bool DebugInfo::HasBreakPoint(int code_position) { | 11789 bool DebugInfo::HasBreakPoint(int code_position) { |
| 11686 // Get the break point info object for this code position. | 11790 // Get the break point info object for this code position. |
| 11687 Object* break_point_info = GetBreakPointInfo(code_position); | 11791 Object* break_point_info = GetBreakPointInfo(code_position); |
| 11688 | 11792 |
| 11689 // If there is no break point info object or no break points in the break | 11793 // If there is no break point info object or no break points in the break |
| 11690 // point info object there is no break point at this code position. | 11794 // point info object there is no break point at this code position. |
| 11691 if (break_point_info->IsUndefined()) return false; | 11795 if (break_point_info->IsUndefined()) return false; |
| 11692 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 11796 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11927 if (break_point_objects()->IsUndefined()) return 0; | 12031 if (break_point_objects()->IsUndefined()) return 0; |
| 11928 // Single beak point. | 12032 // Single beak point. |
| 11929 if (!break_point_objects()->IsFixedArray()) return 1; | 12033 if (!break_point_objects()->IsFixedArray()) return 1; |
| 11930 // Multiple break points. | 12034 // Multiple break points. |
| 11931 return FixedArray::cast(break_point_objects())->length(); | 12035 return FixedArray::cast(break_point_objects())->length(); |
| 11932 } | 12036 } |
| 11933 #endif | 12037 #endif |
| 11934 | 12038 |
| 11935 | 12039 |
| 11936 } } // namespace v8::internal | 12040 } } // namespace v8::internal |
| OLD | NEW |