| 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 | 
|---|