Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: src/objects.cc

Issue 9051014: Reland 10309: Ensure large Smi-only arrays don't transition to FAST_DOUBLE_ARRAY (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: final version Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698