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:: kCanonoicalNonHoleNanLower32 = 0x7FF00000; | |
Mads Ager (chromium)
2011/06/06 07:58:23
remove space after '::'
Can't you use the V8_UINT
danno
2011/06/08 12:09:43
This macro only works with x64 builds. It reports
| |
63 uint64_t FixedDoubleArray::kCanonoicalNonHoleNanInt64 = | |
64 kCanonoicalNonHoleNanLower32 << 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 2955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3026 } | 3030 } |
3027 return DeleteElementWithInterceptor(index); | 3031 return DeleteElementWithInterceptor(index); |
3028 } | 3032 } |
3029 | 3033 |
3030 switch (GetElementsKind()) { | 3034 switch (GetElementsKind()) { |
3031 case FAST_ELEMENTS: { | 3035 case FAST_ELEMENTS: { |
3032 Object* obj; | 3036 Object* obj; |
3033 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 3037 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
3034 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3038 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3035 } | 3039 } |
3036 uint32_t length = IsJSArray() ? | 3040 int length = IsJSArray() |
3037 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 3041 ? Smi::cast(JSArray::cast(this)->length())->value() |
3038 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 3042 : FixedArray::cast(elements())->length(); |
3039 if (index < length) { | 3043 if (index < static_cast<uint32_t>(length)) { |
3040 FixedArray::cast(elements())->set_the_hole(index); | 3044 FixedArray::cast(elements())->set_the_hole(index); |
3041 } | 3045 } |
3042 break; | 3046 break; |
3043 } | 3047 } |
3048 case FAST_DOUBLE_ELEMENTS: { | |
3049 int length = IsJSArray() | |
3050 ? Smi::cast(JSArray::cast(this)->length())->value() | |
3051 : FixedArray::cast(elements())->length(); | |
3052 if (index < static_cast<uint32_t>(length)) { | |
3053 FixedDoubleArray::cast(elements())->set_the_hole(index); | |
3054 } | |
3055 break; | |
3056 } | |
3044 case EXTERNAL_PIXEL_ELEMENTS: | 3057 case EXTERNAL_PIXEL_ELEMENTS: |
3045 case EXTERNAL_BYTE_ELEMENTS: | 3058 case EXTERNAL_BYTE_ELEMENTS: |
3046 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3059 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3047 case EXTERNAL_SHORT_ELEMENTS: | 3060 case EXTERNAL_SHORT_ELEMENTS: |
3048 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3061 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3049 case EXTERNAL_INT_ELEMENTS: | 3062 case EXTERNAL_INT_ELEMENTS: |
3050 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3063 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3051 case EXTERNAL_FLOAT_ELEMENTS: | 3064 case EXTERNAL_FLOAT_ELEMENTS: |
3052 case EXTERNAL_DOUBLE_ELEMENTS: | 3065 case EXTERNAL_DOUBLE_ELEMENTS: |
3053 // Pixel and external array elements cannot be deleted. Just | 3066 // Pixel and external array elements cannot be deleted. Just |
(...skipping 3848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6902 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); | 6915 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
6903 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6916 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6904 } | 6917 } |
6905 FixedArray* elems = FixedArray::cast(obj); | 6918 FixedArray* elems = FixedArray::cast(obj); |
6906 | 6919 |
6907 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); | 6920 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
6908 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6921 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6909 } | 6922 } |
6910 Map* new_map = Map::cast(obj); | 6923 Map* new_map = Map::cast(obj); |
6911 | 6924 |
6912 AssertNoAllocation no_gc; | |
6913 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); | |
6914 switch (GetElementsKind()) { | 6925 switch (GetElementsKind()) { |
6915 case FAST_ELEMENTS: { | 6926 case FAST_ELEMENTS: { |
6927 AssertNoAllocation no_gc; | |
6928 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); | |
6916 FixedArray* old_elements = FixedArray::cast(elements()); | 6929 FixedArray* old_elements = FixedArray::cast(elements()); |
6917 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); | 6930 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); |
6918 // Fill out the new array with this content and array holes. | 6931 // Fill out the new array with this content and array holes. |
6919 for (uint32_t i = 0; i < old_length; i++) { | 6932 for (uint32_t i = 0; i < old_length; i++) { |
6920 elems->set(i, old_elements->get(i), mode); | 6933 elems->set(i, old_elements->get(i), mode); |
6921 } | 6934 } |
6922 break; | 6935 break; |
6923 } | 6936 } |
6937 case FAST_DOUBLE_ELEMENTS: { | |
6938 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements()); | |
6939 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); | |
6940 // Fill out the new array with this content and array holes. | |
6941 for (uint32_t i = 0; i < old_length; i++) { | |
6942 if (!old_elements->is_the_hole(i)) { | |
6943 Object* obj; | |
6944 // Objects must be allocated in the old object space, since the | |
6945 // overall number of HeapNumbers needed for the conversion might | |
6946 // exceed the capacity of new space, and we would fail repeatedly | |
6947 // trying to convert the FixedDoubleArray. | |
6948 MaybeObject* maybe_value_object = | |
6949 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); | |
6950 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; | |
6951 elems->set(i, obj, UPDATE_WRITE_BARRIER); | |
Mads Ager (chromium)
2011/06/06 07:58:23
Why not use the WriteBarrierMode of the new elemen
danno
2011/06/08 12:09:43
It doesn't really make sense to use GetWriteBarrie
| |
6952 } | |
6953 } | |
6954 break; | |
6955 } | |
6924 case DICTIONARY_ELEMENTS: { | 6956 case DICTIONARY_ELEMENTS: { |
6957 AssertNoAllocation no_gc; | |
6958 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); | |
6925 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 6959 NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
6926 for (int i = 0; i < dictionary->Capacity(); i++) { | 6960 for (int i = 0; i < dictionary->Capacity(); i++) { |
6927 Object* key = dictionary->KeyAt(i); | 6961 Object* key = dictionary->KeyAt(i); |
6928 if (key->IsNumber()) { | 6962 if (key->IsNumber()) { |
6929 uint32_t entry = static_cast<uint32_t>(key->Number()); | 6963 uint32_t entry = static_cast<uint32_t>(key->Number()); |
6930 elems->set(entry, dictionary->ValueAt(i), mode); | 6964 elems->set(entry, dictionary->ValueAt(i), mode); |
6931 } | 6965 } |
6932 } | 6966 } |
6933 break; | 6967 break; |
6934 } | 6968 } |
6935 default: | 6969 default: |
6936 UNREACHABLE(); | 6970 UNREACHABLE(); |
6937 break; | 6971 break; |
6938 } | 6972 } |
6939 | 6973 |
6940 set_map(new_map); | 6974 set_map(new_map); |
6941 set_elements(elems); | 6975 set_elements(elems); |
6942 | 6976 |
6943 if (IsJSArray()) { | 6977 if (IsJSArray()) { |
6944 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 6978 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
6945 } | 6979 } |
6946 | 6980 |
6947 return this; | 6981 return this; |
6948 } | 6982 } |
6949 | 6983 |
6950 | 6984 |
6985 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | |
6986 int capacity, | |
6987 int length) { | |
6988 Heap* heap = GetHeap(); | |
6989 // We should never end in here with a pixel or external array. | |
6990 ASSERT(!HasExternalArrayElements()); | |
6991 | |
6992 Object* obj; | |
6993 { MaybeObject* maybe_obj = heap->AllocateFixedDoubleArray(capacity); | |
6994 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
6995 } | |
6996 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); | |
6997 | |
6998 { MaybeObject* maybe_obj = map()->GetFastDoubleElementsMap(); | |
6999 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
7000 } | |
7001 Map* new_map = Map::cast(obj); | |
7002 | |
7003 AssertNoAllocation no_gc; | |
7004 switch (GetElementsKind()) { | |
7005 case FAST_ELEMENTS: { | |
7006 FixedArray* old_elements = FixedArray::cast(elements()); | |
7007 elems->Initialize(old_elements); | |
7008 break; | |
7009 } | |
7010 case FAST_DOUBLE_ELEMENTS: { | |
7011 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements()); | |
7012 elems->Initialize(old_elements); | |
7013 break; | |
7014 } | |
7015 case DICTIONARY_ELEMENTS: { | |
7016 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | |
7017 elems->Initialize(dictionary); | |
7018 break; | |
7019 } | |
7020 default: | |
7021 UNREACHABLE(); | |
7022 break; | |
7023 } | |
7024 | |
7025 set_map(new_map); | |
7026 set_elements(elems); | |
7027 | |
7028 if (IsJSArray()) { | |
7029 JSArray::cast(this)->set_length(Smi::FromInt(length)); | |
7030 } | |
7031 | |
7032 return this; | |
7033 } | |
7034 | |
7035 | |
6951 MaybeObject* JSObject::SetSlowElements(Object* len) { | 7036 MaybeObject* JSObject::SetSlowElements(Object* len) { |
6952 // We should never end in here with a pixel or external array. | 7037 // We should never end in here with a pixel or external array. |
6953 ASSERT(!HasExternalArrayElements()); | 7038 ASSERT(!HasExternalArrayElements()); |
6954 | 7039 |
6955 uint32_t new_length = static_cast<uint32_t>(len->Number()); | 7040 uint32_t new_length = static_cast<uint32_t>(len->Number()); |
6956 | 7041 |
6957 switch (GetElementsKind()) { | 7042 switch (GetElementsKind()) { |
6958 case FAST_ELEMENTS: { | 7043 case FAST_ELEMENTS: { |
6959 // Make sure we never try to shrink dense arrays into sparse arrays. | 7044 // Make sure we never try to shrink dense arrays into sparse arrays. |
6960 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= | 7045 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7641 if (check_prototype && | 7726 if (check_prototype && |
7642 (index >= elms_length || elms->get(index)->IsTheHole())) { | 7727 (index >= elms_length || elms->get(index)->IsTheHole())) { |
7643 bool found; | 7728 bool found; |
7644 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 7729 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
7645 value, | 7730 value, |
7646 &found, | 7731 &found, |
7647 strict_mode); | 7732 strict_mode); |
7648 if (found) return result; | 7733 if (found) return result; |
7649 } | 7734 } |
7650 | 7735 |
7651 | |
7652 // Check whether there is extra space in fixed array.. | 7736 // Check whether there is extra space in fixed array.. |
7653 if (index < elms_length) { | 7737 if (index < elms_length) { |
7654 elms->set(index, value); | 7738 elms->set(index, value); |
7655 if (IsJSArray()) { | 7739 if (IsJSArray()) { |
7656 // Update the length of the array if needed. | 7740 // Update the length of the array if needed. |
7657 uint32_t array_length = 0; | 7741 uint32_t array_length = 0; |
7658 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 7742 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); |
7659 if (index >= array_length) { | 7743 if (index >= array_length) { |
7660 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 7744 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); |
7661 } | 7745 } |
(...skipping 21 matching lines...) Expand all Loading... | |
7683 // Otherwise default to slow case. | 7767 // Otherwise default to slow case. |
7684 Object* obj; | 7768 Object* obj; |
7685 { MaybeObject* maybe_obj = NormalizeElements(); | 7769 { MaybeObject* maybe_obj = NormalizeElements(); |
7686 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7770 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
7687 } | 7771 } |
7688 ASSERT(HasDictionaryElements()); | 7772 ASSERT(HasDictionaryElements()); |
7689 return SetElement(index, value, strict_mode, check_prototype); | 7773 return SetElement(index, value, strict_mode, check_prototype); |
7690 } | 7774 } |
7691 | 7775 |
7692 | 7776 |
7777 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( | |
7778 uint32_t index, | |
7779 Object* value, | |
7780 StrictModeFlag strict_mode, | |
7781 bool check_prototype) { | |
7782 ASSERT(HasFastDoubleElements()); | |
7783 | |
7784 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | |
7785 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | |
7786 | |
7787 // If storing to an element that isn't in the array, pass the store request | |
7788 // up the prototype chain before storing in the receiver's elements. | |
7789 if (check_prototype && | |
7790 (index >= elms_length || elms->is_the_hole(index))) { | |
7791 bool found; | |
7792 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | |
7793 value, | |
7794 &found, | |
7795 strict_mode); | |
7796 if (found) return result; | |
7797 } | |
7798 | |
7799 // If the value object is not a heap number, switch to fast elements and try | |
7800 // again. | |
7801 bool value_is_smi = value->IsSmi(); | |
7802 if (!value_is_smi && | |
Mads Ager (chromium)
2011/06/06 07:58:23
if (!value->IsNumber()) which covers IsSmi() and I
danno
2011/06/08 12:09:43
Done.
| |
7803 (HeapObject::cast(value)->map() != | |
7804 *(GetIsolate()->factory()->heap_number_map()))) { | |
7805 Object* obj; | |
7806 { MaybeObject* maybe_obj = | |
7807 SetFastElementsCapacityAndLength(elms_length, elms_length); | |
Mads Ager (chromium)
2011/06/06 07:58:23
Should you really pass in elms_length for both her
danno
2011/06/08 12:09:43
Done.
| |
7808 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
7809 } | |
7810 return SetFastElement(index, value, strict_mode, check_prototype); | |
7811 } | |
7812 | |
7813 double double_value = value_is_smi | |
7814 ? static_cast<double>(Smi::cast(value)->value()) | |
7815 : HeapNumber::cast(value)->value(); | |
7816 | |
7817 // Check whether there is extra space in fixed array.. | |
Mads Ager (chromium)
2011/06/06 07:58:23
.. -> .
in the fixed array?
danno
2011/06/08 12:09:43
Done.
| |
7818 if (index < elms_length) { | |
7819 elms->set(index, double_value); | |
7820 if (IsJSArray()) { | |
7821 // Update the length of the array if needed. | |
7822 uint32_t array_length = 0; | |
7823 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | |
7824 if (index >= array_length) { | |
7825 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | |
7826 } | |
7827 } | |
7828 return value; | |
7829 } | |
7830 | |
7831 // Allow gap in fast case. | |
7832 if ((index - elms_length) < kMaxGap) { | |
7833 // Try allocating extra space. | |
7834 int new_capacity = NewElementsCapacity(index+1); | |
7835 if (new_capacity <= kMaxFastElementsLength || | |
7836 !ShouldConvertToSlowElements(new_capacity)) { | |
7837 ASSERT(static_cast<uint32_t>(new_capacity) > index); | |
7838 Object* obj; | |
7839 { MaybeObject* maybe_obj = | |
7840 SetFastDoubleElementsCapacityAndLength(new_capacity, | |
7841 index + 1); | |
7842 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
7843 } | |
7844 FixedDoubleArray::cast(elements())->set(index, double_value); | |
7845 return value; | |
7846 } | |
7847 } | |
7848 | |
7849 // Otherwise default to slow case. | |
7850 Object* obj; | |
7851 { MaybeObject* maybe_obj = NormalizeElements(); | |
7852 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
7853 } | |
7854 ASSERT(HasDictionaryElements()); | |
7855 return SetElement(index, value, strict_mode, check_prototype); | |
7856 } | |
7857 | |
7858 | |
7693 MaybeObject* JSObject::SetElement(uint32_t index, | 7859 MaybeObject* JSObject::SetElement(uint32_t index, |
7694 Object* value, | 7860 Object* value, |
7695 StrictModeFlag strict_mode, | 7861 StrictModeFlag strict_mode, |
7696 bool check_prototype) { | 7862 bool check_prototype) { |
7697 // Check access rights if needed. | 7863 // Check access rights if needed. |
7698 if (IsAccessCheckNeeded()) { | 7864 if (IsAccessCheckNeeded()) { |
7699 Heap* heap = GetHeap(); | 7865 Heap* heap = GetHeap(); |
7700 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7866 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
7701 HandleScope scope; | 7867 HandleScope scope; |
7702 Handle<Object> value_handle(value); | 7868 Handle<Object> value_handle(value); |
(...skipping 29 matching lines...) Expand all Loading... | |
7732 | 7898 |
7733 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7899 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
7734 Object* value, | 7900 Object* value, |
7735 StrictModeFlag strict_mode, | 7901 StrictModeFlag strict_mode, |
7736 bool check_prototype) { | 7902 bool check_prototype) { |
7737 Isolate* isolate = GetIsolate(); | 7903 Isolate* isolate = GetIsolate(); |
7738 switch (GetElementsKind()) { | 7904 switch (GetElementsKind()) { |
7739 case FAST_ELEMENTS: | 7905 case FAST_ELEMENTS: |
7740 // Fast case. | 7906 // Fast case. |
7741 return SetFastElement(index, value, strict_mode, check_prototype); | 7907 return SetFastElement(index, value, strict_mode, check_prototype); |
7908 case FAST_DOUBLE_ELEMENTS: | |
7909 return SetFastDoubleElement(index, value, strict_mode, check_prototype); | |
7742 case EXTERNAL_PIXEL_ELEMENTS: { | 7910 case EXTERNAL_PIXEL_ELEMENTS: { |
7743 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 7911 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
7744 return pixels->SetValue(index, value); | 7912 return pixels->SetValue(index, value); |
7745 } | 7913 } |
7746 case EXTERNAL_BYTE_ELEMENTS: { | 7914 case EXTERNAL_BYTE_ELEMENTS: { |
7747 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7915 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
7748 return array->SetValue(index, value); | 7916 return array->SetValue(index, value); |
7749 } | 7917 } |
7750 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 7918 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
7751 ExternalUnsignedByteArray* array = | 7919 ExternalUnsignedByteArray* array = |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7855 } | 8023 } |
7856 | 8024 |
7857 // Attempt to put this object back in fast case. | 8025 // Attempt to put this object back in fast case. |
7858 if (ShouldConvertToFastElements()) { | 8026 if (ShouldConvertToFastElements()) { |
7859 uint32_t new_length = 0; | 8027 uint32_t new_length = 0; |
7860 if (IsJSArray()) { | 8028 if (IsJSArray()) { |
7861 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); | 8029 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); |
7862 } else { | 8030 } else { |
7863 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; | 8031 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; |
7864 } | 8032 } |
7865 Object* obj; | 8033 if (ShouldConvertToFastDoubleElements()) { |
7866 { MaybeObject* maybe_obj = | 8034 Object* obj; |
7867 SetFastElementsCapacityAndLength(new_length, new_length); | 8035 { MaybeObject* maybe_obj = |
7868 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8036 SetFastDoubleElementsCapacityAndLength(new_length, new_length); |
8037 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
8038 } | |
8039 #ifdef DEBUG | |
8040 if (FLAG_trace_normalization) { | |
8041 PrintF("Object elements are fast double case again:\n"); | |
8042 Print(); | |
8043 } | |
8044 #endif | |
8045 } else { | |
8046 Object* obj; | |
8047 { MaybeObject* maybe_obj = | |
8048 SetFastElementsCapacityAndLength(new_length, new_length); | |
8049 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
8050 } | |
8051 #ifdef DEBUG | |
8052 if (FLAG_trace_normalization) { | |
8053 PrintF("Object elements are fast case again:\n"); | |
8054 Print(); | |
8055 } | |
8056 #endif | |
7869 } | 8057 } |
7870 #ifdef DEBUG | |
7871 if (FLAG_trace_normalization) { | |
7872 PrintF("Object elements are fast case again:\n"); | |
7873 Print(); | |
7874 } | |
7875 #endif | |
7876 } | 8058 } |
7877 | 8059 |
7878 return value; | 8060 return value; |
7879 } | 8061 } |
7880 default: | |
7881 UNREACHABLE(); | |
7882 break; | |
7883 } | 8062 } |
7884 // All possible cases have been handled above. Add a return to avoid the | 8063 // All possible cases have been handled above. Add a return to avoid the |
7885 // complaints from the compiler. | 8064 // complaints from the compiler. |
7886 UNREACHABLE(); | 8065 UNREACHABLE(); |
7887 return isolate->heap()->null_value(); | 8066 return isolate->heap()->null_value(); |
7888 } | 8067 } |
7889 | 8068 |
7890 | 8069 |
7891 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 8070 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
7892 Object* value) { | 8071 Object* value) { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8015 // JSArray::length cannot change. | 8194 // JSArray::length cannot change. |
8016 switch (GetElementsKind()) { | 8195 switch (GetElementsKind()) { |
8017 case FAST_ELEMENTS: { | 8196 case FAST_ELEMENTS: { |
8018 FixedArray* elms = FixedArray::cast(elements()); | 8197 FixedArray* elms = FixedArray::cast(elements()); |
8019 if (index < static_cast<uint32_t>(elms->length())) { | 8198 if (index < static_cast<uint32_t>(elms->length())) { |
8020 Object* value = elms->get(index); | 8199 Object* value = elms->get(index); |
8021 if (!value->IsTheHole()) return value; | 8200 if (!value->IsTheHole()) return value; |
8022 } | 8201 } |
8023 break; | 8202 break; |
8024 } | 8203 } |
8204 case FAST_DOUBLE_ELEMENTS: { | |
8205 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | |
8206 if (index < static_cast<uint32_t>(elms->length())) { | |
8207 if (!elms->is_the_hole(index)) { | |
8208 double double_value = elms->get(index); | |
8209 return GetHeap()->AllocateHeapNumber(double_value); | |
8210 } | |
8211 } | |
8212 break; | |
8213 } | |
8025 case EXTERNAL_PIXEL_ELEMENTS: | 8214 case EXTERNAL_PIXEL_ELEMENTS: |
8026 case EXTERNAL_BYTE_ELEMENTS: | 8215 case EXTERNAL_BYTE_ELEMENTS: |
8027 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 8216 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
8028 case EXTERNAL_SHORT_ELEMENTS: | 8217 case EXTERNAL_SHORT_ELEMENTS: |
8029 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 8218 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
8030 case EXTERNAL_INT_ELEMENTS: | 8219 case EXTERNAL_INT_ELEMENTS: |
8031 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8220 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
8032 case EXTERNAL_FLOAT_ELEMENTS: | 8221 case EXTERNAL_FLOAT_ELEMENTS: |
8033 case EXTERNAL_DOUBLE_ELEMENTS: { | 8222 case EXTERNAL_DOUBLE_ELEMENTS: { |
8034 MaybeObject* maybe_value = GetExternalElement(index); | 8223 MaybeObject* maybe_value = GetExternalElement(index); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8134 break; | 8323 break; |
8135 } | 8324 } |
8136 case EXTERNAL_DOUBLE_ELEMENTS: { | 8325 case EXTERNAL_DOUBLE_ELEMENTS: { |
8137 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); | 8326 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); |
8138 if (index < static_cast<uint32_t>(array->length())) { | 8327 if (index < static_cast<uint32_t>(array->length())) { |
8139 double value = array->get(index); | 8328 double value = array->get(index); |
8140 return GetHeap()->AllocateHeapNumber(value); | 8329 return GetHeap()->AllocateHeapNumber(value); |
8141 } | 8330 } |
8142 break; | 8331 break; |
8143 } | 8332 } |
8333 case FAST_DOUBLE_ELEMENTS: | |
8144 case FAST_ELEMENTS: | 8334 case FAST_ELEMENTS: |
8145 case DICTIONARY_ELEMENTS: | 8335 case DICTIONARY_ELEMENTS: |
8146 UNREACHABLE(); | 8336 UNREACHABLE(); |
8147 break; | 8337 break; |
8148 } | 8338 } |
8149 return GetHeap()->undefined_value(); | 8339 return GetHeap()->undefined_value(); |
8150 } | 8340 } |
8151 | 8341 |
8152 | 8342 |
8153 bool JSObject::HasDenseElements() { | 8343 bool JSObject::HasDenseElements() { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8218 if (IsJSArray()) { | 8408 if (IsJSArray()) { |
8219 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); | 8409 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); |
8220 } else { | 8410 } else { |
8221 length = dictionary->max_number_key(); | 8411 length = dictionary->max_number_key(); |
8222 } | 8412 } |
8223 return static_cast<uint32_t>(dictionary->Capacity()) >= | 8413 return static_cast<uint32_t>(dictionary->Capacity()) >= |
8224 (length / (2 * NumberDictionary::kEntrySize)); | 8414 (length / (2 * NumberDictionary::kEntrySize)); |
8225 } | 8415 } |
8226 | 8416 |
8227 | 8417 |
8418 bool JSObject::ShouldConvertToFastDoubleElements() { | |
8419 if (FLAG_unbox_double_arrays) { | |
8420 ASSERT(HasDictionaryElements()); | |
8421 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | |
8422 for (int i = 0; i < dictionary->Capacity(); i++) { | |
8423 Object* key = dictionary->KeyAt(i); | |
8424 if (key->IsNumber()) { | |
8425 if (!dictionary->ValueAt(i)->IsNumber()) return false; | |
8426 } | |
8427 } | |
8428 return true; | |
8429 } else { | |
8430 return false; | |
8431 } | |
8432 } | |
8433 | |
8434 | |
8228 // Certain compilers request function template instantiation when they | 8435 // Certain compilers request function template instantiation when they |
8229 // see the definition of the other template functions in the | 8436 // see the definition of the other template functions in the |
8230 // class. This requires us to have the template functions put | 8437 // class. This requires us to have the template functions put |
8231 // together, so even though this function belongs in objects-debug.cc, | 8438 // together, so even though this function belongs in objects-debug.cc, |
8232 // we keep it here instead to satisfy certain compilers. | 8439 // we keep it here instead to satisfy certain compilers. |
8233 #ifdef OBJECT_PRINT | 8440 #ifdef OBJECT_PRINT |
8234 template<typename Shape, typename Key> | 8441 template<typename Shape, typename Key> |
8235 void Dictionary<Shape, Key>::Print(FILE* out) { | 8442 void Dictionary<Shape, Key>::Print(FILE* out) { |
8236 int capacity = HashTable<Shape, Key>::Capacity(); | 8443 int capacity = HashTable<Shape, Key>::Capacity(); |
8237 for (int i = 0; i < capacity; i++) { | 8444 for (int i = 0; i < capacity; i++) { |
(...skipping 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10744 if (break_point_objects()->IsUndefined()) return 0; | 10951 if (break_point_objects()->IsUndefined()) return 0; |
10745 // Single beak point. | 10952 // Single beak point. |
10746 if (!break_point_objects()->IsFixedArray()) return 1; | 10953 if (!break_point_objects()->IsFixedArray()) return 1; |
10747 // Multiple break points. | 10954 // Multiple break points. |
10748 return FixedArray::cast(break_point_objects())->length(); | 10955 return FixedArray::cast(break_point_objects())->length(); |
10749 } | 10956 } |
10750 #endif | 10957 #endif |
10751 | 10958 |
10752 | 10959 |
10753 } } // namespace v8::internal | 10960 } } // namespace v8::internal |
OLD | NEW |