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 8170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8181 { Object* object; | 8181 { Object* object; |
8182 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); | 8182 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); |
8183 if (!maybe->ToObject(&object)) return maybe; | 8183 if (!maybe->ToObject(&object)) return maybe; |
8184 new_elements = FixedArray::cast(object); | 8184 new_elements = FixedArray::cast(object); |
8185 } | 8185 } |
8186 | 8186 |
8187 // Find the new map to use for this object if there is a map change. | 8187 // Find the new map to use for this object if there is a map change. |
8188 Map* new_map = NULL; | 8188 Map* new_map = NULL; |
8189 if (elements()->map() != heap->non_strict_arguments_elements_map()) { | 8189 if (elements()->map() != heap->non_strict_arguments_elements_map()) { |
8190 Object* object; | 8190 Object* object; |
| 8191 // The resized array has FAST_SMI_ONLY_ELEMENTS if the capacity mode forces |
| 8192 // it, or if it's allowed and the old elements array contained only SMIs. |
8191 bool has_fast_smi_only_elements = | 8193 bool has_fast_smi_only_elements = |
8192 (set_capacity_mode == kAllowSmiOnlyElements) && | 8194 (set_capacity_mode == kForceSmiOnlyElements) || |
8193 (elements()->map()->has_fast_smi_only_elements() || | 8195 ((set_capacity_mode == kAllowSmiOnlyElements) && |
8194 elements() == heap->empty_fixed_array()); | 8196 (elements()->map()->has_fast_smi_only_elements() || |
| 8197 elements() == heap->empty_fixed_array())); |
8195 ElementsKind elements_kind = has_fast_smi_only_elements | 8198 ElementsKind elements_kind = has_fast_smi_only_elements |
8196 ? FAST_SMI_ONLY_ELEMENTS | 8199 ? FAST_SMI_ONLY_ELEMENTS |
8197 : FAST_ELEMENTS; | 8200 : FAST_ELEMENTS; |
8198 MaybeObject* maybe = GetElementsTransitionMap(elements_kind); | 8201 MaybeObject* maybe = GetElementsTransitionMap(elements_kind); |
8199 if (!maybe->ToObject(&object)) return maybe; | 8202 if (!maybe->ToObject(&object)) return maybe; |
8200 new_map = Map::cast(object); | 8203 new_map = Map::cast(object); |
8201 } | 8204 } |
8202 | 8205 |
8203 FixedArrayBase* old_elements_raw = elements(); | 8206 FixedArrayBase* old_elements_raw = elements(); |
8204 ElementsKind elements_kind = GetElementsKind(); | 8207 ElementsKind elements_kind = GetElementsKind(); |
8205 switch (elements_kind) { | 8208 switch (elements_kind) { |
8206 case FAST_SMI_ONLY_ELEMENTS: | 8209 case FAST_SMI_ONLY_ELEMENTS: |
8207 case FAST_ELEMENTS: { | 8210 case FAST_ELEMENTS: { |
8208 AssertNoAllocation no_gc; | 8211 AssertNoAllocation no_gc; |
8209 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); | 8212 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); |
8210 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), | 8213 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), |
8211 new_elements, mode); | 8214 new_elements, mode); |
8212 set_map(new_map); | 8215 set_map_and_elements(new_map, new_elements); |
8213 set_elements(new_elements); | |
8214 break; | 8216 break; |
8215 } | 8217 } |
8216 case DICTIONARY_ELEMENTS: { | 8218 case DICTIONARY_ELEMENTS: { |
8217 AssertNoAllocation no_gc; | 8219 AssertNoAllocation no_gc; |
8218 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 8220 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
8219 CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw), | 8221 CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw), |
8220 new_elements, | 8222 new_elements, |
8221 mode); | 8223 mode); |
8222 set_map(new_map); | 8224 set_map_and_elements(new_map, new_elements); |
8223 set_elements(new_elements); | |
8224 break; | 8225 break; |
8225 } | 8226 } |
8226 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8227 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
8227 AssertNoAllocation no_gc; | 8228 AssertNoAllocation no_gc; |
8228 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 8229 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
8229 // The object's map and the parameter map are unchanged, the unaliased | 8230 // The object's map and the parameter map are unchanged, the unaliased |
8230 // arguments are copied to the new backing store. | 8231 // arguments are copied to the new backing store. |
8231 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); | 8232 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); |
8232 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 8233 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
8233 if (arguments->IsDictionary()) { | 8234 if (arguments->IsDictionary()) { |
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9234 } | 9235 } |
9235 | 9236 |
9236 // Attempt to put this object back in fast case. | 9237 // Attempt to put this object back in fast case. |
9237 if (ShouldConvertToFastElements()) { | 9238 if (ShouldConvertToFastElements()) { |
9238 uint32_t new_length = 0; | 9239 uint32_t new_length = 0; |
9239 if (IsJSArray()) { | 9240 if (IsJSArray()) { |
9240 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); | 9241 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); |
9241 } else { | 9242 } else { |
9242 new_length = dictionary->max_number_key() + 1; | 9243 new_length = dictionary->max_number_key() + 1; |
9243 } | 9244 } |
9244 MaybeObject* result = CanConvertToFastDoubleElements() | 9245 SetFastElementsCapacityMode set_capacity_mode = FLAG_smi_only_arrays |
| 9246 ? kAllowSmiOnlyElements |
| 9247 : kDontAllowSmiOnlyElements; |
| 9248 bool has_smi_only_elements = false; |
| 9249 bool should_convert_to_fast_double_elements = |
| 9250 ShouldConvertToFastDoubleElements(&has_smi_only_elements); |
| 9251 if (has_smi_only_elements) { |
| 9252 set_capacity_mode = kForceSmiOnlyElements; |
| 9253 } |
| 9254 MaybeObject* result = should_convert_to_fast_double_elements |
9245 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) | 9255 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) |
9246 : SetFastElementsCapacityAndLength(new_length, | 9256 : SetFastElementsCapacityAndLength(new_length, |
9247 new_length, | 9257 new_length, |
9248 kDontAllowSmiOnlyElements); | 9258 set_capacity_mode); |
9249 if (result->IsFailure()) return result; | 9259 if (result->IsFailure()) return result; |
9250 #ifdef DEBUG | 9260 #ifdef DEBUG |
9251 if (FLAG_trace_normalization) { | 9261 if (FLAG_trace_normalization) { |
9252 PrintF("Object elements are fast case again:\n"); | 9262 PrintF("Object elements are fast case again:\n"); |
9253 Print(); | 9263 Print(); |
9254 } | 9264 } |
9255 #endif | 9265 #endif |
9256 } | 9266 } |
9257 return value; | 9267 return value; |
9258 } | 9268 } |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9717 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); | 9727 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); |
9718 } else { | 9728 } else { |
9719 array_size = dictionary->max_number_key(); | 9729 array_size = dictionary->max_number_key(); |
9720 } | 9730 } |
9721 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * | 9731 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * |
9722 NumberDictionary::kEntrySize; | 9732 NumberDictionary::kEntrySize; |
9723 return 2 * dictionary_size >= array_size; | 9733 return 2 * dictionary_size >= array_size; |
9724 } | 9734 } |
9725 | 9735 |
9726 | 9736 |
9727 bool JSObject::CanConvertToFastDoubleElements() { | 9737 bool JSObject::ShouldConvertToFastDoubleElements( |
| 9738 bool* has_smi_only_elements) { |
| 9739 *has_smi_only_elements = false; |
9728 if (FLAG_unbox_double_arrays) { | 9740 if (FLAG_unbox_double_arrays) { |
9729 ASSERT(HasDictionaryElements()); | 9741 ASSERT(HasDictionaryElements()); |
9730 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 9742 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
| 9743 bool found_double = false; |
9731 for (int i = 0; i < dictionary->Capacity(); i++) { | 9744 for (int i = 0; i < dictionary->Capacity(); i++) { |
9732 Object* key = dictionary->KeyAt(i); | 9745 Object* key = dictionary->KeyAt(i); |
9733 if (key->IsNumber()) { | 9746 if (key->IsNumber()) { |
9734 if (!dictionary->ValueAt(i)->IsNumber()) return false; | 9747 Object* value = dictionary->ValueAt(i); |
| 9748 if (!value->IsNumber()) return false; |
| 9749 if (!value->IsSmi()) { |
| 9750 found_double = true; |
| 9751 } |
9735 } | 9752 } |
9736 } | 9753 } |
9737 return true; | 9754 *has_smi_only_elements = !found_double; |
| 9755 return found_double; |
9738 } else { | 9756 } else { |
9739 return false; | 9757 return false; |
9740 } | 9758 } |
9741 } | 9759 } |
9742 | 9760 |
9743 | 9761 |
9744 // Certain compilers request function template instantiation when they | 9762 // Certain compilers request function template instantiation when they |
9745 // see the definition of the other template functions in the | 9763 // see the definition of the other template functions in the |
9746 // class. This requires us to have the template functions put | 9764 // class. This requires us to have the template functions put |
9747 // together, so even though this function belongs in objects-debug.cc, | 9765 // together, so even though this function belongs in objects-debug.cc, |
(...skipping 2806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12554 if (break_point_objects()->IsUndefined()) return 0; | 12572 if (break_point_objects()->IsUndefined()) return 0; |
12555 // Single break point. | 12573 // Single break point. |
12556 if (!break_point_objects()->IsFixedArray()) return 1; | 12574 if (!break_point_objects()->IsFixedArray()) return 1; |
12557 // Multiple break points. | 12575 // Multiple break points. |
12558 return FixedArray::cast(break_point_objects())->length(); | 12576 return FixedArray::cast(break_point_objects())->length(); |
12559 } | 12577 } |
12560 #endif // ENABLE_DEBUGGER_SUPPORT | 12578 #endif // ENABLE_DEBUGGER_SUPPORT |
12561 | 12579 |
12562 | 12580 |
12563 } } // namespace v8::internal | 12581 } } // namespace v8::internal |
OLD | NEW |