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