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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 #endif | 51 #endif |
52 | 52 |
53 namespace v8 { | 53 namespace v8 { |
54 namespace internal { | 54 namespace internal { |
55 | 55 |
56 // Getters and setters are stored in a fixed array property. These are | 56 // Getters and setters are stored in a fixed array property. These are |
57 // constants for their indices. | 57 // constants for their indices. |
58 const int kGetterIndex = 0; | 58 const int kGetterIndex = 0; |
59 const int kSetterIndex = 1; | 59 const int kSetterIndex = 1; |
60 | 60 |
| 61 uint64_t FixedDoubleArray::kHoleNanInt64 = -1; |
| 62 uint64_t FixedDoubleArray::kCanonicalNonHoleNanLower32 = 0x7FF00000; |
| 63 uint64_t FixedDoubleArray::kCanonicalNonHoleNanInt64 = |
| 64 kCanonicalNonHoleNanLower32 << 32; |
61 | 65 |
62 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, | 66 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, |
63 Object* value) { | 67 Object* value) { |
64 Object* result; | 68 Object* result; |
65 { MaybeObject* maybe_result = | 69 { MaybeObject* maybe_result = |
66 constructor->GetHeap()->AllocateJSObject(constructor); | 70 constructor->GetHeap()->AllocateJSObject(constructor); |
67 if (!maybe_result->ToObject(&result)) return maybe_result; | 71 if (!maybe_result->ToObject(&result)) return maybe_result; |
68 } | 72 } |
69 JSValue::cast(result)->set_value(value); | 73 JSValue::cast(result)->set_value(value); |
70 return result; | 74 return result; |
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 } | 1175 } |
1172 break; | 1176 break; |
1173 } | 1177 } |
1174 return; | 1178 return; |
1175 } | 1179 } |
1176 | 1180 |
1177 switch (type) { | 1181 switch (type) { |
1178 case FIXED_ARRAY_TYPE: | 1182 case FIXED_ARRAY_TYPE: |
1179 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); | 1183 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); |
1180 break; | 1184 break; |
| 1185 case FIXED_DOUBLE_ARRAY_TYPE: |
| 1186 break; |
1181 case JS_OBJECT_TYPE: | 1187 case JS_OBJECT_TYPE: |
1182 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: | 1188 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
1183 case JS_VALUE_TYPE: | 1189 case JS_VALUE_TYPE: |
1184 case JS_ARRAY_TYPE: | 1190 case JS_ARRAY_TYPE: |
1185 case JS_REGEXP_TYPE: | 1191 case JS_REGEXP_TYPE: |
1186 case JS_GLOBAL_PROXY_TYPE: | 1192 case JS_GLOBAL_PROXY_TYPE: |
1187 case JS_GLOBAL_OBJECT_TYPE: | 1193 case JS_GLOBAL_OBJECT_TYPE: |
1188 case JS_BUILTINS_OBJECT_TYPE: | 1194 case JS_BUILTINS_OBJECT_TYPE: |
1189 case JS_MESSAGE_OBJECT_TYPE: | 1195 case JS_MESSAGE_OBJECT_TYPE: |
1190 JSObject::BodyDescriptor::IterateBody(this, object_size, v); | 1196 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
(...skipping 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2793 ASSERT(!IsGlobalObject()); | 2799 ASSERT(!IsGlobalObject()); |
2794 return property_dictionary()-> | 2800 return property_dictionary()-> |
2795 TransformPropertiesToFastFor(this, unused_property_fields); | 2801 TransformPropertiesToFastFor(this, unused_property_fields); |
2796 } | 2802 } |
2797 | 2803 |
2798 | 2804 |
2799 MaybeObject* JSObject::NormalizeElements() { | 2805 MaybeObject* JSObject::NormalizeElements() { |
2800 ASSERT(!HasExternalArrayElements()); | 2806 ASSERT(!HasExternalArrayElements()); |
2801 if (HasDictionaryElements()) return this; | 2807 if (HasDictionaryElements()) return this; |
2802 Map* old_map = map(); | 2808 Map* old_map = map(); |
2803 ASSERT(old_map->has_fast_elements()); | 2809 ASSERT(old_map->has_fast_elements() || old_map->has_fast_double_elements()); |
2804 | 2810 |
2805 Object* obj; | 2811 Object* obj; |
2806 { MaybeObject* maybe_obj = old_map->GetSlowElementsMap(); | 2812 { MaybeObject* maybe_obj = old_map->GetSlowElementsMap(); |
2807 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2813 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2808 } | 2814 } |
2809 Map* new_map = Map::cast(obj); | 2815 Map* new_map = Map::cast(obj); |
2810 | 2816 |
2811 // Get number of entries. | 2817 // Get number of entries. |
2812 FixedArray* array = FixedArray::cast(elements()); | 2818 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
2813 | 2819 |
2814 // Compute the effective length. | 2820 // Compute the effective length. |
2815 int length = IsJSArray() ? | 2821 int length = IsJSArray() ? |
2816 Smi::cast(JSArray::cast(this)->length())->value() : | 2822 Smi::cast(JSArray::cast(this)->length())->value() : |
2817 array->length(); | 2823 array->length(); |
2818 { MaybeObject* maybe_obj = NumberDictionary::Allocate(length); | 2824 { MaybeObject* maybe_obj = NumberDictionary::Allocate(length); |
2819 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2825 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2820 } | 2826 } |
| 2827 bool has_double_elements = old_map->has_fast_double_elements(); |
2821 NumberDictionary* dictionary = NumberDictionary::cast(obj); | 2828 NumberDictionary* dictionary = NumberDictionary::cast(obj); |
2822 // Copy entries. | 2829 // Copy entries. |
2823 for (int i = 0; i < length; i++) { | 2830 for (int i = 0; i < length; i++) { |
2824 Object* value = array->get(i); | 2831 Object* value = NULL; |
| 2832 if (has_double_elements) { |
| 2833 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); |
| 2834 if (double_array->is_the_hole(i)) { |
| 2835 value = GetIsolate()->heap()->the_hole_value(); |
| 2836 } else { |
| 2837 // Objects must be allocated in the old object space, since the |
| 2838 // overall number of HeapNumbers needed for the conversion might |
| 2839 // exceed the capacity of new space, and we would fail repeatedly |
| 2840 // trying to convert the FixedDoubleArray. |
| 2841 MaybeObject* maybe_value_object = |
| 2842 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED); |
| 2843 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; |
| 2844 } |
| 2845 } else { |
| 2846 ASSERT(old_map->has_fast_elements()); |
| 2847 FixedArray* fixed_array = FixedArray::cast(array); |
| 2848 value = fixed_array->get(i); |
| 2849 } |
| 2850 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
2825 if (!value->IsTheHole()) { | 2851 if (!value->IsTheHole()) { |
2826 PropertyDetails details = PropertyDetails(NONE, NORMAL); | |
2827 Object* result; | 2852 Object* result; |
2828 { MaybeObject* maybe_result = | 2853 MaybeObject* maybe_result = |
2829 dictionary->AddNumberEntry(i, array->get(i), details); | 2854 dictionary->AddNumberEntry(i, value, details); |
2830 if (!maybe_result->ToObject(&result)) return maybe_result; | 2855 if (!maybe_result->ToObject(&result)) return maybe_result; |
2831 } | |
2832 dictionary = NumberDictionary::cast(result); | 2856 dictionary = NumberDictionary::cast(result); |
2833 } | 2857 } |
2834 } | 2858 } |
2835 // Switch to using the dictionary as the backing storage for | 2859 // Switch to using the dictionary as the backing storage for |
2836 // elements. Set the new map first to satify the elements type | 2860 // elements. Set the new map first to satify the elements type |
2837 // assert in set_elements(). | 2861 // assert in set_elements(). |
2838 set_map(new_map); | 2862 set_map(new_map); |
2839 set_elements(dictionary); | 2863 set_elements(dictionary); |
2840 | 2864 |
2841 new_map->heap()->isolate()->counters()->elements_to_dictionary()-> | 2865 new_map->heap()->isolate()->counters()->elements_to_dictionary()-> |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2991 } | 3015 } |
2992 return DeleteElementWithInterceptor(index); | 3016 return DeleteElementWithInterceptor(index); |
2993 } | 3017 } |
2994 | 3018 |
2995 switch (GetElementsKind()) { | 3019 switch (GetElementsKind()) { |
2996 case FAST_ELEMENTS: { | 3020 case FAST_ELEMENTS: { |
2997 Object* obj; | 3021 Object* obj; |
2998 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 3022 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
2999 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3023 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3000 } | 3024 } |
3001 uint32_t length = IsJSArray() ? | 3025 int length = IsJSArray() |
3002 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 3026 ? Smi::cast(JSArray::cast(this)->length())->value() |
3003 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 3027 : FixedArray::cast(elements())->length(); |
3004 if (index < length) { | 3028 if (index < static_cast<uint32_t>(length)) { |
3005 FixedArray::cast(elements())->set_the_hole(index); | 3029 FixedArray::cast(elements())->set_the_hole(index); |
3006 } | 3030 } |
3007 break; | 3031 break; |
3008 } | 3032 } |
| 3033 case FAST_DOUBLE_ELEMENTS: { |
| 3034 int length = IsJSArray() |
| 3035 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 3036 : FixedArray::cast(elements())->length(); |
| 3037 if (index < static_cast<uint32_t>(length)) { |
| 3038 FixedDoubleArray::cast(elements())->set_the_hole(index); |
| 3039 } |
| 3040 break; |
| 3041 } |
3009 case EXTERNAL_PIXEL_ELEMENTS: | 3042 case EXTERNAL_PIXEL_ELEMENTS: |
3010 case EXTERNAL_BYTE_ELEMENTS: | 3043 case EXTERNAL_BYTE_ELEMENTS: |
3011 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3044 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3012 case EXTERNAL_SHORT_ELEMENTS: | 3045 case EXTERNAL_SHORT_ELEMENTS: |
3013 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3046 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3014 case EXTERNAL_INT_ELEMENTS: | 3047 case EXTERNAL_INT_ELEMENTS: |
3015 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3048 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3016 case EXTERNAL_FLOAT_ELEMENTS: | 3049 case EXTERNAL_FLOAT_ELEMENTS: |
3017 case EXTERNAL_DOUBLE_ELEMENTS: | 3050 case EXTERNAL_DOUBLE_ELEMENTS: |
3018 // Pixel and external array elements cannot be deleted. Just | 3051 // Pixel and external array elements cannot be deleted. Just |
(...skipping 4072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7091 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); | 7124 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
7092 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7125 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7093 } | 7126 } |
7094 FixedArray* elems = FixedArray::cast(obj); | 7127 FixedArray* elems = FixedArray::cast(obj); |
7095 | 7128 |
7096 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); | 7129 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
7097 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7130 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7098 } | 7131 } |
7099 Map* new_map = Map::cast(obj); | 7132 Map* new_map = Map::cast(obj); |
7100 | 7133 |
7101 AssertNoAllocation no_gc; | |
7102 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); | |
7103 switch (GetElementsKind()) { | 7134 switch (GetElementsKind()) { |
7104 case FAST_ELEMENTS: { | 7135 case FAST_ELEMENTS: { |
| 7136 AssertNoAllocation no_gc; |
| 7137 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); |
7105 FixedArray* old_elements = FixedArray::cast(elements()); | 7138 FixedArray* old_elements = FixedArray::cast(elements()); |
7106 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); | 7139 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); |
7107 // Fill out the new array with this content and array holes. | 7140 // Fill out the new array with this content and array holes. |
7108 for (uint32_t i = 0; i < old_length; i++) { | 7141 for (uint32_t i = 0; i < old_length; i++) { |
7109 elems->set(i, old_elements->get(i), mode); | 7142 elems->set(i, old_elements->get(i), mode); |
7110 } | 7143 } |
7111 break; | 7144 break; |
7112 } | 7145 } |
| 7146 case FAST_DOUBLE_ELEMENTS: { |
| 7147 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements()); |
| 7148 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); |
| 7149 // Fill out the new array with this content and array holes. |
| 7150 for (uint32_t i = 0; i < old_length; i++) { |
| 7151 if (!old_elements->is_the_hole(i)) { |
| 7152 Object* obj; |
| 7153 // Objects must be allocated in the old object space, since the |
| 7154 // overall number of HeapNumbers needed for the conversion might |
| 7155 // exceed the capacity of new space, and we would fail repeatedly |
| 7156 // trying to convert the FixedDoubleArray. |
| 7157 MaybeObject* maybe_value_object = |
| 7158 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); |
| 7159 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; |
| 7160 // Force write barrier. It's not worth trying to exploit |
| 7161 // elems->GetWriteBarrierMode(), since it requires an |
| 7162 // AssertNoAllocation stack object that would have to be positioned |
| 7163 // after the HeapNumber allocation anyway. |
| 7164 elems->set(i, obj, UPDATE_WRITE_BARRIER); |
| 7165 } |
| 7166 } |
| 7167 break; |
| 7168 } |
7113 case DICTIONARY_ELEMENTS: { | 7169 case DICTIONARY_ELEMENTS: { |
| 7170 AssertNoAllocation no_gc; |
| 7171 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); |
7114 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 7172 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
7115 for (int i = 0; i < dictionary->Capacity(); i++) { | 7173 for (int i = 0; i < dictionary->Capacity(); i++) { |
7116 Object* key = dictionary->KeyAt(i); | 7174 Object* key = dictionary->KeyAt(i); |
7117 if (key->IsNumber()) { | 7175 if (key->IsNumber()) { |
7118 uint32_t entry = static_cast<uint32_t>(key->Number()); | 7176 uint32_t entry = static_cast<uint32_t>(key->Number()); |
7119 elems->set(entry, dictionary->ValueAt(i), mode); | 7177 elems->set(entry, dictionary->ValueAt(i), mode); |
7120 } | 7178 } |
7121 } | 7179 } |
7122 break; | 7180 break; |
7123 } | 7181 } |
7124 default: | 7182 default: |
7125 UNREACHABLE(); | 7183 UNREACHABLE(); |
7126 break; | 7184 break; |
7127 } | 7185 } |
7128 | 7186 |
7129 set_map(new_map); | 7187 set_map(new_map); |
7130 set_elements(elems); | 7188 set_elements(elems); |
7131 | 7189 |
7132 if (IsJSArray()) { | 7190 if (IsJSArray()) { |
7133 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 7191 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
7134 } | 7192 } |
7135 | 7193 |
7136 return this; | 7194 return this; |
7137 } | 7195 } |
7138 | 7196 |
7139 | 7197 |
| 7198 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
| 7199 int capacity, |
| 7200 int length) { |
| 7201 Heap* heap = GetHeap(); |
| 7202 // We should never end in here with a pixel or external array. |
| 7203 ASSERT(!HasExternalArrayElements()); |
| 7204 |
| 7205 Object* obj; |
| 7206 { MaybeObject* maybe_obj = |
| 7207 heap->AllocateUninitializedFixedDoubleArray(capacity); |
| 7208 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7209 } |
| 7210 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); |
| 7211 |
| 7212 { MaybeObject* maybe_obj = map()->GetFastDoubleElementsMap(); |
| 7213 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7214 } |
| 7215 Map* new_map = Map::cast(obj); |
| 7216 |
| 7217 AssertNoAllocation no_gc; |
| 7218 switch (GetElementsKind()) { |
| 7219 case FAST_ELEMENTS: { |
| 7220 elems->Initialize(FixedArray::cast(elements())); |
| 7221 break; |
| 7222 } |
| 7223 case FAST_DOUBLE_ELEMENTS: { |
| 7224 elems->Initialize(FixedDoubleArray::cast(elements())); |
| 7225 break; |
| 7226 } |
| 7227 case DICTIONARY_ELEMENTS: { |
| 7228 elems->Initialize(NumberDictionary::cast(elements())); |
| 7229 break; |
| 7230 } |
| 7231 default: |
| 7232 UNREACHABLE(); |
| 7233 break; |
| 7234 } |
| 7235 |
| 7236 set_map(new_map); |
| 7237 set_elements(elems); |
| 7238 |
| 7239 if (IsJSArray()) { |
| 7240 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
| 7241 } |
| 7242 |
| 7243 return this; |
| 7244 } |
| 7245 |
| 7246 |
7140 MaybeObject* JSObject::SetSlowElements(Object* len) { | 7247 MaybeObject* JSObject::SetSlowElements(Object* len) { |
7141 // We should never end in here with a pixel or external array. | 7248 // We should never end in here with a pixel or external array. |
7142 ASSERT(!HasExternalArrayElements()); | 7249 ASSERT(!HasExternalArrayElements()); |
7143 | 7250 |
7144 uint32_t new_length = static_cast<uint32_t>(len->Number()); | 7251 uint32_t new_length = static_cast<uint32_t>(len->Number()); |
7145 | 7252 |
7146 switch (GetElementsKind()) { | 7253 switch (GetElementsKind()) { |
7147 case FAST_ELEMENTS: { | 7254 case FAST_ELEMENTS: { |
7148 // Make sure we never try to shrink dense arrays into sparse arrays. | 7255 // Make sure we never try to shrink dense arrays into sparse arrays. |
7149 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= | 7256 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7851 if (check_prototype && | 7958 if (check_prototype && |
7852 (index >= elms_length || elms->get(index)->IsTheHole())) { | 7959 (index >= elms_length || elms->get(index)->IsTheHole())) { |
7853 bool found; | 7960 bool found; |
7854 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 7961 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
7855 value, | 7962 value, |
7856 &found, | 7963 &found, |
7857 strict_mode); | 7964 strict_mode); |
7858 if (found) return result; | 7965 if (found) return result; |
7859 } | 7966 } |
7860 | 7967 |
7861 | |
7862 // Check whether there is extra space in fixed array.. | 7968 // Check whether there is extra space in fixed array.. |
7863 if (index < elms_length) { | 7969 if (index < elms_length) { |
7864 elms->set(index, value); | 7970 elms->set(index, value); |
7865 if (IsJSArray()) { | 7971 if (IsJSArray()) { |
7866 // Update the length of the array if needed. | 7972 // Update the length of the array if needed. |
7867 uint32_t array_length = 0; | 7973 uint32_t array_length = 0; |
7868 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 7974 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); |
7869 if (index >= array_length) { | 7975 if (index >= array_length) { |
7870 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 7976 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); |
7871 } | 7977 } |
(...skipping 21 matching lines...) Expand all Loading... |
7893 // Otherwise default to slow case. | 7999 // Otherwise default to slow case. |
7894 Object* obj; | 8000 Object* obj; |
7895 { MaybeObject* maybe_obj = NormalizeElements(); | 8001 { MaybeObject* maybe_obj = NormalizeElements(); |
7896 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8002 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7897 } | 8003 } |
7898 ASSERT(HasDictionaryElements()); | 8004 ASSERT(HasDictionaryElements()); |
7899 return SetElement(index, value, strict_mode, check_prototype); | 8005 return SetElement(index, value, strict_mode, check_prototype); |
7900 } | 8006 } |
7901 | 8007 |
7902 | 8008 |
| 8009 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( |
| 8010 uint32_t index, |
| 8011 Object* value, |
| 8012 StrictModeFlag strict_mode, |
| 8013 bool check_prototype) { |
| 8014 ASSERT(HasFastDoubleElements()); |
| 8015 |
| 8016 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| 8017 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
| 8018 |
| 8019 // If storing to an element that isn't in the array, pass the store request |
| 8020 // up the prototype chain before storing in the receiver's elements. |
| 8021 if (check_prototype && |
| 8022 (index >= elms_length || elms->is_the_hole(index))) { |
| 8023 bool found; |
| 8024 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
| 8025 value, |
| 8026 &found, |
| 8027 strict_mode); |
| 8028 if (found) return result; |
| 8029 } |
| 8030 |
| 8031 // If the value object is not a heap number, switch to fast elements and try |
| 8032 // again. |
| 8033 bool value_is_smi = value->IsSmi(); |
| 8034 if (!value->IsNumber()) { |
| 8035 Object* obj; |
| 8036 uint32_t length = elms_length; |
| 8037 if (IsJSArray()) { |
| 8038 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); |
| 8039 } |
| 8040 MaybeObject* maybe_obj = |
| 8041 SetFastElementsCapacityAndLength(elms_length, length); |
| 8042 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8043 return SetFastElement(index, value, strict_mode, check_prototype); |
| 8044 } |
| 8045 |
| 8046 double double_value = value_is_smi |
| 8047 ? static_cast<double>(Smi::cast(value)->value()) |
| 8048 : HeapNumber::cast(value)->value(); |
| 8049 |
| 8050 // Check whether there is extra space in the fixed array. |
| 8051 if (index < elms_length) { |
| 8052 elms->set(index, double_value); |
| 8053 if (IsJSArray()) { |
| 8054 // Update the length of the array if needed. |
| 8055 uint32_t array_length = 0; |
| 8056 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); |
| 8057 if (index >= array_length) { |
| 8058 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); |
| 8059 } |
| 8060 } |
| 8061 return value; |
| 8062 } |
| 8063 |
| 8064 // Allow gap in fast case. |
| 8065 if ((index - elms_length) < kMaxGap) { |
| 8066 // Try allocating extra space. |
| 8067 int new_capacity = NewElementsCapacity(index+1); |
| 8068 if (new_capacity <= kMaxFastElementsLength || |
| 8069 !ShouldConvertToSlowElements(new_capacity)) { |
| 8070 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
| 8071 Object* obj; |
| 8072 { MaybeObject* maybe_obj = |
| 8073 SetFastDoubleElementsCapacityAndLength(new_capacity, |
| 8074 index + 1); |
| 8075 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8076 } |
| 8077 FixedDoubleArray::cast(elements())->set(index, double_value); |
| 8078 return value; |
| 8079 } |
| 8080 } |
| 8081 |
| 8082 // Otherwise default to slow case. |
| 8083 Object* obj; |
| 8084 { MaybeObject* maybe_obj = NormalizeElements(); |
| 8085 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8086 } |
| 8087 ASSERT(HasDictionaryElements()); |
| 8088 return SetElement(index, value, strict_mode, check_prototype); |
| 8089 } |
| 8090 |
| 8091 |
7903 MaybeObject* JSObject::SetElement(uint32_t index, | 8092 MaybeObject* JSObject::SetElement(uint32_t index, |
7904 Object* value, | 8093 Object* value, |
7905 StrictModeFlag strict_mode, | 8094 StrictModeFlag strict_mode, |
7906 bool check_prototype) { | 8095 bool check_prototype) { |
7907 // Check access rights if needed. | 8096 // Check access rights if needed. |
7908 if (IsAccessCheckNeeded()) { | 8097 if (IsAccessCheckNeeded()) { |
7909 Heap* heap = GetHeap(); | 8098 Heap* heap = GetHeap(); |
7910 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 8099 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
7911 HandleScope scope; | 8100 HandleScope scope; |
7912 Handle<Object> value_handle(value); | 8101 Handle<Object> value_handle(value); |
(...skipping 29 matching lines...) Expand all Loading... |
7942 | 8131 |
7943 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 8132 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
7944 Object* value, | 8133 Object* value, |
7945 StrictModeFlag strict_mode, | 8134 StrictModeFlag strict_mode, |
7946 bool check_prototype) { | 8135 bool check_prototype) { |
7947 Isolate* isolate = GetIsolate(); | 8136 Isolate* isolate = GetIsolate(); |
7948 switch (GetElementsKind()) { | 8137 switch (GetElementsKind()) { |
7949 case FAST_ELEMENTS: | 8138 case FAST_ELEMENTS: |
7950 // Fast case. | 8139 // Fast case. |
7951 return SetFastElement(index, value, strict_mode, check_prototype); | 8140 return SetFastElement(index, value, strict_mode, check_prototype); |
| 8141 case FAST_DOUBLE_ELEMENTS: |
| 8142 return SetFastDoubleElement(index, value, strict_mode, check_prototype); |
7952 case EXTERNAL_PIXEL_ELEMENTS: { | 8143 case EXTERNAL_PIXEL_ELEMENTS: { |
7953 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 8144 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
7954 return pixels->SetValue(index, value); | 8145 return pixels->SetValue(index, value); |
7955 } | 8146 } |
7956 case EXTERNAL_BYTE_ELEMENTS: { | 8147 case EXTERNAL_BYTE_ELEMENTS: { |
7957 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 8148 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
7958 return array->SetValue(index, value); | 8149 return array->SetValue(index, value); |
7959 } | 8150 } |
7960 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 8151 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
7961 ExternalUnsignedByteArray* array = | 8152 ExternalUnsignedByteArray* array = |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8065 } | 8256 } |
8066 | 8257 |
8067 // Attempt to put this object back in fast case. | 8258 // Attempt to put this object back in fast case. |
8068 if (ShouldConvertToFastElements()) { | 8259 if (ShouldConvertToFastElements()) { |
8069 uint32_t new_length = 0; | 8260 uint32_t new_length = 0; |
8070 if (IsJSArray()) { | 8261 if (IsJSArray()) { |
8071 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); | 8262 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); |
8072 } else { | 8263 } else { |
8073 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; | 8264 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; |
8074 } | 8265 } |
8075 Object* obj; | 8266 if (ShouldConvertToFastDoubleElements()) { |
8076 { MaybeObject* maybe_obj = | 8267 Object* obj; |
8077 SetFastElementsCapacityAndLength(new_length, new_length); | 8268 { MaybeObject* maybe_obj = |
8078 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8269 SetFastDoubleElementsCapacityAndLength(new_length, new_length); |
| 8270 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8271 } |
| 8272 #ifdef DEBUG |
| 8273 if (FLAG_trace_normalization) { |
| 8274 PrintF("Object elements are fast double case again:\n"); |
| 8275 Print(); |
| 8276 } |
| 8277 #endif |
| 8278 } else { |
| 8279 Object* obj; |
| 8280 { MaybeObject* maybe_obj = |
| 8281 SetFastElementsCapacityAndLength(new_length, new_length); |
| 8282 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 8283 } |
| 8284 #ifdef DEBUG |
| 8285 if (FLAG_trace_normalization) { |
| 8286 PrintF("Object elements are fast case again:\n"); |
| 8287 Print(); |
| 8288 } |
| 8289 #endif |
8079 } | 8290 } |
8080 #ifdef DEBUG | |
8081 if (FLAG_trace_normalization) { | |
8082 PrintF("Object elements are fast case again:\n"); | |
8083 Print(); | |
8084 } | |
8085 #endif | |
8086 } | 8291 } |
8087 | 8292 |
8088 return value; | 8293 return value; |
8089 } | 8294 } |
8090 default: | |
8091 UNREACHABLE(); | |
8092 break; | |
8093 } | 8295 } |
8094 // All possible cases have been handled above. Add a return to avoid the | 8296 // All possible cases have been handled above. Add a return to avoid the |
8095 // complaints from the compiler. | 8297 // complaints from the compiler. |
8096 UNREACHABLE(); | 8298 UNREACHABLE(); |
8097 return isolate->heap()->null_value(); | 8299 return isolate->heap()->null_value(); |
8098 } | 8300 } |
8099 | 8301 |
8100 | 8302 |
8101 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 8303 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
8102 Object* value) { | 8304 Object* value) { |
(...skipping 19 matching lines...) Expand all Loading... |
8122 // JSArray::length cannot change. | 8324 // JSArray::length cannot change. |
8123 switch (GetElementsKind()) { | 8325 switch (GetElementsKind()) { |
8124 case FAST_ELEMENTS: { | 8326 case FAST_ELEMENTS: { |
8125 FixedArray* elms = FixedArray::cast(elements()); | 8327 FixedArray* elms = FixedArray::cast(elements()); |
8126 if (index < static_cast<uint32_t>(elms->length())) { | 8328 if (index < static_cast<uint32_t>(elms->length())) { |
8127 Object* value = elms->get(index); | 8329 Object* value = elms->get(index); |
8128 if (!value->IsTheHole()) return value; | 8330 if (!value->IsTheHole()) return value; |
8129 } | 8331 } |
8130 break; | 8332 break; |
8131 } | 8333 } |
| 8334 case FAST_DOUBLE_ELEMENTS: { |
| 8335 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| 8336 if (index < static_cast<uint32_t>(elms->length())) { |
| 8337 if (!elms->is_the_hole(index)) { |
| 8338 return GetHeap()->NumberFromDouble(elms->get(index)); |
| 8339 } |
| 8340 } |
| 8341 break; |
| 8342 } |
8132 case EXTERNAL_PIXEL_ELEMENTS: | 8343 case EXTERNAL_PIXEL_ELEMENTS: |
8133 case EXTERNAL_BYTE_ELEMENTS: | 8344 case EXTERNAL_BYTE_ELEMENTS: |
8134 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 8345 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
8135 case EXTERNAL_SHORT_ELEMENTS: | 8346 case EXTERNAL_SHORT_ELEMENTS: |
8136 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 8347 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
8137 case EXTERNAL_INT_ELEMENTS: | 8348 case EXTERNAL_INT_ELEMENTS: |
8138 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8349 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
8139 case EXTERNAL_FLOAT_ELEMENTS: | 8350 case EXTERNAL_FLOAT_ELEMENTS: |
8140 case EXTERNAL_DOUBLE_ELEMENTS: { | 8351 case EXTERNAL_DOUBLE_ELEMENTS: { |
8141 MaybeObject* maybe_value = GetExternalElement(index); | 8352 MaybeObject* maybe_value = GetExternalElement(index); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8225 // JSArray::length cannot change. | 8436 // JSArray::length cannot change. |
8226 switch (GetElementsKind()) { | 8437 switch (GetElementsKind()) { |
8227 case FAST_ELEMENTS: { | 8438 case FAST_ELEMENTS: { |
8228 FixedArray* elms = FixedArray::cast(elements()); | 8439 FixedArray* elms = FixedArray::cast(elements()); |
8229 if (index < static_cast<uint32_t>(elms->length())) { | 8440 if (index < static_cast<uint32_t>(elms->length())) { |
8230 Object* value = elms->get(index); | 8441 Object* value = elms->get(index); |
8231 if (!value->IsTheHole()) return value; | 8442 if (!value->IsTheHole()) return value; |
8232 } | 8443 } |
8233 break; | 8444 break; |
8234 } | 8445 } |
| 8446 case FAST_DOUBLE_ELEMENTS: { |
| 8447 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| 8448 if (index < static_cast<uint32_t>(elms->length())) { |
| 8449 if (!elms->is_the_hole(index)) { |
| 8450 double double_value = elms->get(index); |
| 8451 return GetHeap()->NumberFromDouble(double_value); |
| 8452 } |
| 8453 } |
| 8454 break; |
| 8455 } |
8235 case EXTERNAL_PIXEL_ELEMENTS: | 8456 case EXTERNAL_PIXEL_ELEMENTS: |
8236 case EXTERNAL_BYTE_ELEMENTS: | 8457 case EXTERNAL_BYTE_ELEMENTS: |
8237 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 8458 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
8238 case EXTERNAL_SHORT_ELEMENTS: | 8459 case EXTERNAL_SHORT_ELEMENTS: |
8239 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 8460 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
8240 case EXTERNAL_INT_ELEMENTS: | 8461 case EXTERNAL_INT_ELEMENTS: |
8241 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8462 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
8242 case EXTERNAL_FLOAT_ELEMENTS: | 8463 case EXTERNAL_FLOAT_ELEMENTS: |
8243 case EXTERNAL_DOUBLE_ELEMENTS: { | 8464 case EXTERNAL_DOUBLE_ELEMENTS: { |
8244 MaybeObject* maybe_value = GetExternalElement(index); | 8465 MaybeObject* maybe_value = GetExternalElement(index); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8344 break; | 8565 break; |
8345 } | 8566 } |
8346 case EXTERNAL_DOUBLE_ELEMENTS: { | 8567 case EXTERNAL_DOUBLE_ELEMENTS: { |
8347 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); | 8568 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); |
8348 if (index < static_cast<uint32_t>(array->length())) { | 8569 if (index < static_cast<uint32_t>(array->length())) { |
8349 double value = array->get(index); | 8570 double value = array->get(index); |
8350 return GetHeap()->AllocateHeapNumber(value); | 8571 return GetHeap()->AllocateHeapNumber(value); |
8351 } | 8572 } |
8352 break; | 8573 break; |
8353 } | 8574 } |
| 8575 case FAST_DOUBLE_ELEMENTS: |
8354 case FAST_ELEMENTS: | 8576 case FAST_ELEMENTS: |
8355 case DICTIONARY_ELEMENTS: | 8577 case DICTIONARY_ELEMENTS: |
8356 UNREACHABLE(); | 8578 UNREACHABLE(); |
8357 break; | 8579 break; |
8358 } | 8580 } |
8359 return GetHeap()->undefined_value(); | 8581 return GetHeap()->undefined_value(); |
8360 } | 8582 } |
8361 | 8583 |
8362 | 8584 |
8363 bool JSObject::HasDenseElements() { | 8585 bool JSObject::HasDenseElements() { |
8364 int capacity = 0; | 8586 int capacity = 0; |
8365 int number_of_elements = 0; | 8587 int number_of_elements = 0; |
8366 | 8588 |
8367 switch (GetElementsKind()) { | 8589 switch (GetElementsKind()) { |
8368 case FAST_ELEMENTS: { | 8590 case FAST_ELEMENTS: { |
8369 FixedArray* elms = FixedArray::cast(elements()); | 8591 FixedArray* elms = FixedArray::cast(elements()); |
8370 capacity = elms->length(); | 8592 capacity = elms->length(); |
8371 for (int i = 0; i < capacity; i++) { | 8593 for (int i = 0; i < capacity; i++) { |
8372 if (!elms->get(i)->IsTheHole()) number_of_elements++; | 8594 if (!elms->get(i)->IsTheHole()) number_of_elements++; |
8373 } | 8595 } |
8374 break; | 8596 break; |
8375 } | 8597 } |
| 8598 case FAST_DOUBLE_ELEMENTS: { |
| 8599 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| 8600 capacity = elms->length(); |
| 8601 for (int i = 0; i < capacity; i++) { |
| 8602 if (!elms->is_the_hole(i)) number_of_elements++; |
| 8603 } |
| 8604 break; |
| 8605 } |
8376 case EXTERNAL_PIXEL_ELEMENTS: | 8606 case EXTERNAL_PIXEL_ELEMENTS: |
8377 case EXTERNAL_BYTE_ELEMENTS: | 8607 case EXTERNAL_BYTE_ELEMENTS: |
8378 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 8608 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
8379 case EXTERNAL_SHORT_ELEMENTS: | 8609 case EXTERNAL_SHORT_ELEMENTS: |
8380 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 8610 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
8381 case EXTERNAL_INT_ELEMENTS: | 8611 case EXTERNAL_INT_ELEMENTS: |
8382 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8612 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
8383 case EXTERNAL_FLOAT_ELEMENTS: | 8613 case EXTERNAL_FLOAT_ELEMENTS: |
8384 case EXTERNAL_DOUBLE_ELEMENTS: { | 8614 case EXTERNAL_DOUBLE_ELEMENTS: { |
8385 return true; | 8615 return true; |
8386 } | 8616 } |
8387 case DICTIONARY_ELEMENTS: { | 8617 case DICTIONARY_ELEMENTS: { |
8388 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 8618 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
8389 capacity = dictionary->Capacity(); | 8619 capacity = dictionary->Capacity(); |
8390 number_of_elements = dictionary->NumberOfElements(); | 8620 number_of_elements = dictionary->NumberOfElements(); |
8391 break; | 8621 break; |
8392 } | 8622 } |
8393 default: | 8623 default: |
8394 UNREACHABLE(); | 8624 UNREACHABLE(); |
8395 break; | 8625 break; |
8396 } | 8626 } |
8397 | 8627 |
8398 if (capacity == 0) return true; | 8628 if (capacity == 0) return true; |
8399 return (number_of_elements > (capacity / 2)); | 8629 return (number_of_elements > (capacity / 2)); |
8400 } | 8630 } |
8401 | 8631 |
8402 | 8632 |
8403 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { | 8633 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { |
8404 ASSERT(HasFastElements()); | |
8405 // Keep the array in fast case if the current backing storage is | 8634 // Keep the array in fast case if the current backing storage is |
8406 // almost filled and if the new capacity is no more than twice the | 8635 // almost filled and if the new capacity is no more than twice the |
8407 // old capacity. | 8636 // old capacity. |
8408 int elements_length = FixedArray::cast(elements())->length(); | 8637 int elements_length = 0; |
| 8638 if (HasFastElements()) { |
| 8639 elements_length = FixedArray::cast(elements())->length(); |
| 8640 } else if (HasFastDoubleElements()) { |
| 8641 elements_length = FixedDoubleArray::cast(elements())->length(); |
| 8642 } else { |
| 8643 UNREACHABLE(); |
| 8644 } |
8409 return !HasDenseElements() || ((new_capacity / 2) > elements_length); | 8645 return !HasDenseElements() || ((new_capacity / 2) > elements_length); |
8410 } | 8646 } |
8411 | 8647 |
8412 | 8648 |
8413 bool JSObject::ShouldConvertToFastElements() { | 8649 bool JSObject::ShouldConvertToFastElements() { |
8414 ASSERT(HasDictionaryElements()); | 8650 ASSERT(HasDictionaryElements()); |
8415 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 8651 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
8416 // If the elements are sparse, we should not go back to fast case. | 8652 // If the elements are sparse, we should not go back to fast case. |
8417 if (!HasDenseElements()) return false; | 8653 if (!HasDenseElements()) return false; |
8418 // If an element has been added at a very high index in the elements | 8654 // If an element has been added at a very high index in the elements |
8419 // dictionary, we cannot go back to fast case. | 8655 // dictionary, we cannot go back to fast case. |
8420 if (dictionary->requires_slow_elements()) return false; | 8656 if (dictionary->requires_slow_elements()) return false; |
8421 // An object requiring access checks is never allowed to have fast | 8657 // An object requiring access checks is never allowed to have fast |
8422 // elements. If it had fast elements we would skip security checks. | 8658 // elements. If it had fast elements we would skip security checks. |
8423 if (IsAccessCheckNeeded()) return false; | 8659 if (IsAccessCheckNeeded()) return false; |
8424 // If the dictionary backing storage takes up roughly half as much | 8660 // If the dictionary backing storage takes up roughly half as much |
8425 // space as a fast-case backing storage would the array should have | 8661 // space as a fast-case backing storage would the array should have |
8426 // fast elements. | 8662 // fast elements. |
8427 uint32_t length = 0; | 8663 uint32_t length = 0; |
8428 if (IsJSArray()) { | 8664 if (IsJSArray()) { |
8429 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); | 8665 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); |
8430 } else { | 8666 } else { |
8431 length = dictionary->max_number_key(); | 8667 length = dictionary->max_number_key(); |
8432 } | 8668 } |
8433 return static_cast<uint32_t>(dictionary->Capacity()) >= | 8669 return static_cast<uint32_t>(dictionary->Capacity()) >= |
8434 (length / (2 * NumberDictionary::kEntrySize)); | 8670 (length / (2 * NumberDictionary::kEntrySize)); |
8435 } | 8671 } |
8436 | 8672 |
8437 | 8673 |
| 8674 bool JSObject::ShouldConvertToFastDoubleElements() { |
| 8675 if (FLAG_unbox_double_arrays) { |
| 8676 ASSERT(HasDictionaryElements()); |
| 8677 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
| 8678 for (int i = 0; i < dictionary->Capacity(); i++) { |
| 8679 Object* key = dictionary->KeyAt(i); |
| 8680 if (key->IsNumber()) { |
| 8681 if (!dictionary->ValueAt(i)->IsNumber()) return false; |
| 8682 } |
| 8683 } |
| 8684 return true; |
| 8685 } else { |
| 8686 return false; |
| 8687 } |
| 8688 } |
| 8689 |
| 8690 |
8438 // Certain compilers request function template instantiation when they | 8691 // Certain compilers request function template instantiation when they |
8439 // see the definition of the other template functions in the | 8692 // see the definition of the other template functions in the |
8440 // class. This requires us to have the template functions put | 8693 // class. This requires us to have the template functions put |
8441 // together, so even though this function belongs in objects-debug.cc, | 8694 // together, so even though this function belongs in objects-debug.cc, |
8442 // we keep it here instead to satisfy certain compilers. | 8695 // we keep it here instead to satisfy certain compilers. |
8443 #ifdef OBJECT_PRINT | 8696 #ifdef OBJECT_PRINT |
8444 template<typename Shape, typename Key> | 8697 template<typename Shape, typename Key> |
8445 void Dictionary<Shape, Key>::Print(FILE* out) { | 8698 void Dictionary<Shape, Key>::Print(FILE* out) { |
8446 int capacity = HashTable<Shape, Key>::Capacity(); | 8699 int capacity = HashTable<Shape, Key>::Capacity(); |
8447 for (int i = 0; i < capacity; i++) { | 8700 for (int i = 0; i < capacity; i++) { |
(...skipping 2507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10955 if (break_point_objects()->IsUndefined()) return 0; | 11208 if (break_point_objects()->IsUndefined()) return 0; |
10956 // Single beak point. | 11209 // Single beak point. |
10957 if (!break_point_objects()->IsFixedArray()) return 1; | 11210 if (!break_point_objects()->IsFixedArray()) return 1; |
10958 // Multiple break points. | 11211 // Multiple break points. |
10959 return FixedArray::cast(break_point_objects())->length(); | 11212 return FixedArray::cast(break_point_objects())->length(); |
10960 } | 11213 } |
10961 #endif | 11214 #endif |
10962 | 11215 |
10963 | 11216 |
10964 } } // namespace v8::internal | 11217 } } // namespace v8::internal |
OLD | NEW |