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 2949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |