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

Side by Side Diff: src/objects.cc

Issue 7307030: Implement ICs for FastDoubleArray loads and stores (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix asserts Created 9 years, 5 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
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;
65
66 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, 61 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
67 Object* value) { 62 Object* value) {
68 Object* result; 63 Object* result;
69 { MaybeObject* maybe_result = 64 { MaybeObject* maybe_result =
70 constructor->GetHeap()->AllocateJSObject(constructor); 65 constructor->GetHeap()->AllocateJSObject(constructor);
71 if (!maybe_result->ToObject(&result)) return maybe_result; 66 if (!maybe_result->ToObject(&result)) return maybe_result;
72 } 67 }
73 JSValue::cast(result)->set_value(value); 68 JSValue::cast(result)->set_value(value);
74 return result; 69 return result;
75 } 70 }
(...skipping 2728 matching lines...) Expand 10 before | Expand all | Expand 10 after
2804 ASSERT(!IsGlobalObject()); 2799 ASSERT(!IsGlobalObject());
2805 return property_dictionary()-> 2800 return property_dictionary()->
2806 TransformPropertiesToFastFor(this, unused_property_fields); 2801 TransformPropertiesToFastFor(this, unused_property_fields);
2807 } 2802 }
2808 2803
2809 2804
2810 MaybeObject* JSObject::NormalizeElements() { 2805 MaybeObject* JSObject::NormalizeElements() {
2811 ASSERT(!HasExternalArrayElements()); 2806 ASSERT(!HasExternalArrayElements());
2812 2807
2813 // Find the backing store. 2808 // Find the backing store.
2814 FixedArray* array = FixedArray::cast(elements()); 2809 FixedArrayBase* array = FixedArrayBase::cast(elements());
2815 Map* old_map = array->map(); 2810 Map* old_map = array->map();
2816 bool is_arguments = 2811 bool is_arguments =
2817 (old_map == old_map->heap()->non_strict_arguments_elements_map()); 2812 (old_map == old_map->heap()->non_strict_arguments_elements_map());
2818 if (is_arguments) { 2813 if (is_arguments) {
2819 array = FixedArray::cast(array->get(1)); 2814 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
2820 } 2815 }
2821 if (array->IsDictionary()) return array; 2816 if (array->IsDictionary()) return array;
2822 2817
2823 ASSERT(HasFastElements() || HasFastArgumentsElements()); 2818 ASSERT(HasFastElements() ||
2819 HasFastDoubleElements() ||
2820 HasFastArgumentsElements());
2824 // Compute the effective length and allocate a new backing store. 2821 // Compute the effective length and allocate a new backing store.
2825 int length = IsJSArray() 2822 int length = IsJSArray()
2826 ? Smi::cast(JSArray::cast(this)->length())->value() 2823 ? Smi::cast(JSArray::cast(this)->length())->value()
2827 : array->length(); 2824 : array->length();
2828 NumberDictionary* dictionary = NULL; 2825 NumberDictionary* dictionary = NULL;
2829 { Object* object; 2826 { Object* object;
2830 MaybeObject* maybe = NumberDictionary::Allocate(length); 2827 MaybeObject* maybe = NumberDictionary::Allocate(length);
2831 if (!maybe->ToObject(&object)) return maybe; 2828 if (!maybe->ToObject(&object)) return maybe;
2832 dictionary = NumberDictionary::cast(object); 2829 dictionary = NumberDictionary::cast(object);
2833 } 2830 }
2834 2831
2835 // Copy the elements to the new backing store. 2832 // Copy the elements to the new backing store.
2836 bool has_double_elements = old_map->has_fast_double_elements(); 2833 bool has_double_elements = array->IsFixedDoubleArray();
2837 for (int i = 0; i < length; i++) { 2834 for (int i = 0; i < length; i++) {
2838 Object* value = NULL; 2835 Object* value = NULL;
2839 if (has_double_elements) { 2836 if (has_double_elements) {
2840 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); 2837 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
2841 if (double_array->is_the_hole(i)) { 2838 if (double_array->is_the_hole(i)) {
2842 value = GetIsolate()->heap()->the_hole_value(); 2839 value = GetIsolate()->heap()->the_hole_value();
2843 } else { 2840 } else {
2844 // Objects must be allocated in the old object space, since the 2841 // Objects must be allocated in the old object space, since the
2845 // overall number of HeapNumbers needed for the conversion might 2842 // overall number of HeapNumbers needed for the conversion might
2846 // exceed the capacity of new space, and we would fail repeatedly 2843 // exceed the capacity of new space, and we would fail repeatedly
2847 // trying to convert the FixedDoubleArray. 2844 // trying to convert the FixedDoubleArray.
2848 MaybeObject* maybe_value_object = 2845 MaybeObject* maybe_value_object =
2849 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED); 2846 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED);
2850 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2847 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
2851 } 2848 }
2852 } else { 2849 } else {
2853 ASSERT(old_map->has_fast_elements()); 2850 ASSERT(old_map->has_fast_elements());
2854 value = array->get(i); 2851 value = FixedArray::cast(array)->get(i);
2855 } 2852 }
2856 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2853 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2857 if (!value->IsTheHole()) { 2854 if (!value->IsTheHole()) {
2858 Object* result; 2855 Object* result;
2859 MaybeObject* maybe_result = 2856 MaybeObject* maybe_result =
2860 dictionary->AddNumberEntry(i, value, details); 2857 dictionary->AddNumberEntry(i, value, details);
2861 if (!maybe_result->ToObject(&result)) return maybe_result; 2858 if (!maybe_result->ToObject(&result)) return maybe_result;
2862 dictionary = NumberDictionary::cast(result); 2859 dictionary = NumberDictionary::cast(result);
2863 } 2860 }
2864 } 2861 }
(...skipping 4445 matching lines...) Expand 10 before | Expand all | Expand 10 after
7310 7307
7311 // Find the new map to use for this object if there is a map change. 7308 // Find the new map to use for this object if there is a map change.
7312 Map* new_map = NULL; 7309 Map* new_map = NULL;
7313 if (elements()->map() != heap->non_strict_arguments_elements_map()) { 7310 if (elements()->map() != heap->non_strict_arguments_elements_map()) {
7314 Object* object; 7311 Object* object;
7315 MaybeObject* maybe = map()->GetFastElementsMap(); 7312 MaybeObject* maybe = map()->GetFastElementsMap();
7316 if (!maybe->ToObject(&object)) return maybe; 7313 if (!maybe->ToObject(&object)) return maybe;
7317 new_map = Map::cast(object); 7314 new_map = Map::cast(object);
7318 } 7315 }
7319 7316
7320 AssertNoAllocation no_gc;
7321 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7322 switch (GetElementsKind()) { 7317 switch (GetElementsKind()) {
7323 case FAST_ELEMENTS: 7318 case FAST_ELEMENTS: {
7319 AssertNoAllocation no_gc;
7320 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7324 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7321 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
7325 set_map(new_map); 7322 set_map(new_map);
7326 set_elements(new_elements); 7323 set_elements(new_elements);
7327 break; 7324 break;
7328 case DICTIONARY_ELEMENTS: 7325 }
7326 case DICTIONARY_ELEMENTS: {
7327 AssertNoAllocation no_gc;
7328 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7329 CopySlowElementsToFast(NumberDictionary::cast(elements()), 7329 CopySlowElementsToFast(NumberDictionary::cast(elements()),
7330 new_elements, 7330 new_elements,
7331 mode); 7331 mode);
7332 set_map(new_map); 7332 set_map(new_map);
7333 set_elements(new_elements); 7333 set_elements(new_elements);
7334 break; 7334 break;
7335 }
7335 case NON_STRICT_ARGUMENTS_ELEMENTS: { 7336 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7337 AssertNoAllocation no_gc;
7338 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7336 // The object's map and the parameter map are unchanged, the unaliased 7339 // The object's map and the parameter map are unchanged, the unaliased
7337 // arguments are copied to the new backing store. 7340 // arguments are copied to the new backing store.
7338 FixedArray* parameter_map = FixedArray::cast(elements()); 7341 FixedArray* parameter_map = FixedArray::cast(elements());
7339 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 7342 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7340 if (arguments->IsDictionary()) { 7343 if (arguments->IsDictionary()) {
7341 CopySlowElementsToFast(NumberDictionary::cast(arguments), 7344 CopySlowElementsToFast(NumberDictionary::cast(arguments),
7342 new_elements, 7345 new_elements,
7343 mode); 7346 mode);
7344 } else { 7347 } else {
7345 CopyFastElementsToFast(arguments, new_elements, mode); 7348 CopyFastElementsToFast(arguments, new_elements, mode);
(...skipping 15 matching lines...) Expand all
7361 MaybeObject* maybe_value_object = 7364 MaybeObject* maybe_value_object =
7362 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); 7365 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED);
7363 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; 7366 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object;
7364 // Force write barrier. It's not worth trying to exploit 7367 // Force write barrier. It's not worth trying to exploit
7365 // elems->GetWriteBarrierMode(), since it requires an 7368 // elems->GetWriteBarrierMode(), since it requires an
7366 // AssertNoAllocation stack object that would have to be positioned 7369 // AssertNoAllocation stack object that would have to be positioned
7367 // after the HeapNumber allocation anyway. 7370 // after the HeapNumber allocation anyway.
7368 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); 7371 new_elements->set(i, obj, UPDATE_WRITE_BARRIER);
7369 } 7372 }
7370 } 7373 }
7374 set_map(new_map);
7375 set_elements(new_elements);
7371 break; 7376 break;
7372 } 7377 }
7373 case EXTERNAL_BYTE_ELEMENTS: 7378 case EXTERNAL_BYTE_ELEMENTS:
7374 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7379 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7375 case EXTERNAL_SHORT_ELEMENTS: 7380 case EXTERNAL_SHORT_ELEMENTS:
7376 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7381 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7377 case EXTERNAL_INT_ELEMENTS: 7382 case EXTERNAL_INT_ELEMENTS:
7378 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7383 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7379 case EXTERNAL_FLOAT_ELEMENTS: 7384 case EXTERNAL_FLOAT_ELEMENTS:
7380 case EXTERNAL_DOUBLE_ELEMENTS: 7385 case EXTERNAL_DOUBLE_ELEMENTS:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
7423 } 7428 }
7424 case DICTIONARY_ELEMENTS: { 7429 case DICTIONARY_ELEMENTS: {
7425 elems->Initialize(NumberDictionary::cast(elements())); 7430 elems->Initialize(NumberDictionary::cast(elements()));
7426 break; 7431 break;
7427 } 7432 }
7428 default: 7433 default:
7429 UNREACHABLE(); 7434 UNREACHABLE();
7430 break; 7435 break;
7431 } 7436 }
7432 7437
7438 ASSERT(new_map->has_fast_double_elements());
7433 set_map(new_map); 7439 set_map(new_map);
7440 ASSERT(elems->IsFixedDoubleArray());
7434 set_elements(elems); 7441 set_elements(elems);
7435 7442
7436 if (IsJSArray()) { 7443 if (IsJSArray()) {
7437 JSArray::cast(this)->set_length(Smi::FromInt(length)); 7444 JSArray::cast(this)->set_length(Smi::FromInt(length));
7438 } 7445 }
7439 7446
7440 return this; 7447 return this;
7441 } 7448 }
7442 7449
7443 7450
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
8400 } 8407 }
8401 8408
8402 // Attempt to put this object back in fast case. 8409 // Attempt to put this object back in fast case.
8403 if (ShouldConvertToFastElements()) { 8410 if (ShouldConvertToFastElements()) {
8404 uint32_t new_length = 0; 8411 uint32_t new_length = 0;
8405 if (IsJSArray()) { 8412 if (IsJSArray()) {
8406 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 8413 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
8407 } else { 8414 } else {
8408 new_length = dictionary->max_number_key() + 1; 8415 new_length = dictionary->max_number_key() + 1;
8409 } 8416 }
8410 MaybeObject* result = 8417 MaybeObject* result = ShouldConvertToFastDoubleElements()
8411 SetFastElementsCapacityAndLength(new_length, new_length); 8418 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
8419 : SetFastElementsCapacityAndLength(new_length, new_length);
8412 if (result->IsFailure()) return result; 8420 if (result->IsFailure()) return result;
8413 #ifdef DEBUG 8421 #ifdef DEBUG
8414 if (FLAG_trace_normalization) { 8422 if (FLAG_trace_normalization) {
8415 PrintF("Object elements are fast case again:\n"); 8423 PrintF("Object elements are fast case again:\n");
8416 Print(); 8424 Print();
8417 } 8425 }
8418 #endif 8426 #endif
8419 } 8427 }
8420 return value; 8428 return value;
8421 } 8429 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
8488 SetFastDoubleElementsCapacityAndLength(new_capacity, 8496 SetFastDoubleElementsCapacityAndLength(new_capacity,
8489 index + 1); 8497 index + 1);
8490 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8498 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8491 } 8499 }
8492 FixedDoubleArray::cast(elements())->set(index, double_value); 8500 FixedDoubleArray::cast(elements())->set(index, double_value);
8493 return value; 8501 return value;
8494 } 8502 }
8495 } 8503 }
8496 8504
8497 // Otherwise default to slow case. 8505 // Otherwise default to slow case.
8506 ASSERT(HasFastDoubleElements());
8507 ASSERT(map()->has_fast_double_elements());
8508 ASSERT(elements()->IsFixedDoubleArray());
8498 Object* obj; 8509 Object* obj;
8499 { MaybeObject* maybe_obj = NormalizeElements(); 8510 { MaybeObject* maybe_obj = NormalizeElements();
8500 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8511 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8501 } 8512 }
8502 ASSERT(HasDictionaryElements()); 8513 ASSERT(HasDictionaryElements());
8503 return SetElement(index, value, strict_mode, check_prototype); 8514 return SetElement(index, value, strict_mode, check_prototype);
8504 } 8515 }
8505 8516
8506 8517
8507 MaybeObject* JSObject::SetElement(uint32_t index, 8518 MaybeObject* JSObject::SetElement(uint32_t index,
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
8941 break; 8952 break;
8942 } 8953 }
8943 return GetHeap()->undefined_value(); 8954 return GetHeap()->undefined_value();
8944 } 8955 }
8945 8956
8946 8957
8947 bool JSObject::HasDenseElements() { 8958 bool JSObject::HasDenseElements() {
8948 int capacity = 0; 8959 int capacity = 0;
8949 int number_of_elements = 0; 8960 int number_of_elements = 0;
8950 8961
8951 FixedArray* backing_store = FixedArray::cast(elements()); 8962 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
8963 FixedArray* backing_store = NULL;
8952 switch (GetElementsKind()) { 8964 switch (GetElementsKind()) {
8953 case NON_STRICT_ARGUMENTS_ELEMENTS: 8965 case NON_STRICT_ARGUMENTS_ELEMENTS:
8954 backing_store = FixedArray::cast(backing_store->get(1)); 8966 backing_store_base =
8967 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
8968 backing_store = FixedArray::cast(backing_store_base);
8955 if (backing_store->IsDictionary()) { 8969 if (backing_store->IsDictionary()) {
8956 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 8970 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
8957 capacity = dictionary->Capacity(); 8971 capacity = dictionary->Capacity();
8958 number_of_elements = dictionary->NumberOfElements(); 8972 number_of_elements = dictionary->NumberOfElements();
8959 break; 8973 break;
8960 } 8974 }
8961 // Fall through. 8975 // Fall through.
8962 case FAST_ELEMENTS: 8976 case FAST_ELEMENTS:
8977 backing_store = FixedArray::cast(backing_store_base);
8963 capacity = backing_store->length(); 8978 capacity = backing_store->length();
8964 for (int i = 0; i < capacity; ++i) { 8979 for (int i = 0; i < capacity; ++i) {
8965 if (!backing_store->get(i)->IsTheHole()) ++number_of_elements; 8980 if (!backing_store->get(i)->IsTheHole()) ++number_of_elements;
8966 } 8981 }
8967 break; 8982 break;
8968 case DICTIONARY_ELEMENTS: { 8983 case DICTIONARY_ELEMENTS: {
8969 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 8984 NumberDictionary* dictionary =
8985 NumberDictionary::cast(FixedArray::cast(elements()));
8970 capacity = dictionary->Capacity(); 8986 capacity = dictionary->Capacity();
8971 number_of_elements = dictionary->NumberOfElements(); 8987 number_of_elements = dictionary->NumberOfElements();
8972 break; 8988 break;
8973 } 8989 }
8974 case FAST_DOUBLE_ELEMENTS: { 8990 case FAST_DOUBLE_ELEMENTS: {
8975 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 8991 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
8976 capacity = elms->length(); 8992 capacity = elms->length();
8977 for (int i = 0; i < capacity; i++) { 8993 for (int i = 0; i < capacity; i++) {
8978 if (!elms->is_the_hole(i)) number_of_elements++; 8994 if (!elms->is_the_hole(i)) number_of_elements++;
8979 } 8995 }
(...skipping 2709 matching lines...) Expand 10 before | Expand all | Expand 10 after
11689 if (break_point_objects()->IsUndefined()) return 0; 11705 if (break_point_objects()->IsUndefined()) return 0;
11690 // Single beak point. 11706 // Single beak point.
11691 if (!break_point_objects()->IsFixedArray()) return 1; 11707 if (!break_point_objects()->IsFixedArray()) return 1;
11692 // Multiple break points. 11708 // Multiple break points.
11693 return FixedArray::cast(break_point_objects())->length(); 11709 return FixedArray::cast(break_point_objects())->length();
11694 } 11710 }
11695 #endif 11711 #endif
11696 11712
11697 11713
11698 } } // namespace v8::internal 11714 } } // 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