Chromium Code Reviews| 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 |