| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/elements.h" | 9 #include "src/elements.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 // existing heap objects to be propertly initialized. | 238 // existing heap objects to be propertly initialized. |
| 239 int start = to_start; | 239 int start = to_start; |
| 240 int length = to_base->length() - start; | 240 int length = to_base->length() - start; |
| 241 if (length > 0) { | 241 if (length > 0) { |
| 242 Heap* heap = from_base->GetHeap(); | 242 Heap* heap = from_base->GetHeap(); |
| 243 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, | 243 MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
| 244 heap->the_hole_value(), length); | 244 heap->the_hole_value(), length); |
| 245 } | 245 } |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 |
| 248 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 249 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
| 249 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 250 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
| 250 if (copy_size == 0) return; | 251 if (copy_size == 0) return; |
| 251 | 252 |
| 252 // From here on, the code below could actually allocate. Therefore the raw | 253 // From here on, the code below could actually allocate. Therefore the raw |
| 253 // values are wrapped into handles. | 254 // values are wrapped into handles. |
| 254 Isolate* isolate = from_base->GetIsolate(); | 255 Isolate* isolate = from_base->GetIsolate(); |
| 255 Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate); | 256 Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate); |
| 256 Handle<FixedArray> to(FixedArray::cast(to_base), isolate); | 257 Handle<FixedArray> to(FixedArray::cast(to_base), isolate); |
| 257 for (int i = 0; i < copy_size; ++i) { | 258 for (int i = 0; i < copy_size; ++i) { |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 ElementsAccessorSubclass::AddImpl(object, index, value, attributes, | 565 ElementsAccessorSubclass::AddImpl(object, index, value, attributes, |
| 565 new_capacity); | 566 new_capacity); |
| 566 } | 567 } |
| 567 | 568 |
| 568 static void AddImpl(Handle<JSObject> object, uint32_t index, | 569 static void AddImpl(Handle<JSObject> object, uint32_t index, |
| 569 Handle<Object> value, PropertyAttributes attributes, | 570 Handle<Object> value, PropertyAttributes attributes, |
| 570 uint32_t new_capacity) { | 571 uint32_t new_capacity) { |
| 571 UNREACHABLE(); | 572 UNREACHABLE(); |
| 572 } | 573 } |
| 573 | 574 |
| 575 virtual uint32_t Push(Handle<JSArray> receiver, |
| 576 Handle<FixedArrayBase> backing_store, Object** objects, |
| 577 uint32_t push_size, int direction) { |
| 578 return ElementsAccessorSubclass::PushImpl(receiver, backing_store, objects, |
| 579 push_size, direction); |
| 580 } |
| 581 |
| 582 static uint32_t PushImpl(Handle<JSArray> receiver, |
| 583 Handle<FixedArrayBase> elms_obj, Object** objects, |
| 584 uint32_t push_size, int direction) { |
| 585 UNREACHABLE(); |
| 586 return 0; |
| 587 } |
| 588 |
| 574 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { | 589 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { |
| 575 ElementsAccessorSubclass::SetLengthImpl(array, length, | 590 ElementsAccessorSubclass::SetLengthImpl(array, length, |
| 576 handle(array->elements())); | 591 handle(array->elements())); |
| 577 } | 592 } |
| 578 | 593 |
| 579 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 594 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, |
| 580 Handle<FixedArrayBase> backing_store); | 595 Handle<FixedArrayBase> backing_store); |
| 581 | 596 |
| 582 static Handle<FixedArrayBase> ConvertElementsWithCapacity( | 597 static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
| 583 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, | 598 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1148 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
| 1134 if (IsFastSmiElementsKind(KindTraits::Kind)) { | 1149 if (IsFastSmiElementsKind(KindTraits::Kind)) { |
| 1135 for (int i = 0; i < length; i++) { | 1150 for (int i = 0; i < length; i++) { |
| 1136 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || | 1151 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || |
| 1137 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1152 (IsFastHoleyElementsKind(KindTraits::Kind) && |
| 1138 backing_store->is_the_hole(i))); | 1153 backing_store->is_the_hole(i))); |
| 1139 } | 1154 } |
| 1140 } | 1155 } |
| 1141 #endif | 1156 #endif |
| 1142 } | 1157 } |
| 1158 |
| 1159 static uint32_t PushImpl(Handle<JSArray> receiver, |
| 1160 Handle<FixedArrayBase> backing_store, |
| 1161 Object** objects, uint32_t push_size, |
| 1162 int direction) { |
| 1163 uint32_t len = Smi::cast(receiver->length())->value(); |
| 1164 if (push_size == 0) { |
| 1165 return len; |
| 1166 } |
| 1167 uint32_t elms_len = backing_store->length(); |
| 1168 // Currently fixed arrays cannot grow too big, so |
| 1169 // we should never hit this case. |
| 1170 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
| 1171 uint32_t new_length = len + push_size; |
| 1172 Handle<FixedArrayBase> new_elms; |
| 1173 |
| 1174 if (new_length > elms_len) { |
| 1175 // New backing storage is needed. |
| 1176 uint32_t capacity = new_length + (new_length >> 1) + 16; |
| 1177 new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1178 receiver, backing_store, KindTraits::Kind, capacity); |
| 1179 } else { |
| 1180 // push_size is > 0 and new_length <= elms_len, so backing_store cannot be |
| 1181 // the |
| 1182 // empty_fixed_array. |
| 1183 new_elms = backing_store; |
| 1184 } |
| 1185 |
| 1186 // Add the provided values. |
| 1187 DisallowHeapAllocation no_gc; |
| 1188 DCHECK(direction == ElementsAccessor::kDirectionForward || |
| 1189 direction == ElementsAccessor::kDirectionReverse); |
| 1190 STATIC_ASSERT(ElementsAccessor::kDirectionForward == 1); |
| 1191 STATIC_ASSERT(ElementsAccessor::kDirectionReverse == -1); |
| 1192 for (uint32_t index = 0; index < push_size; index++) { |
| 1193 int offset = direction * index; |
| 1194 Object* object = objects[offset]; |
| 1195 FastElementsAccessorSubclass::SetImpl(*new_elms, index + len, object); |
| 1196 } |
| 1197 if (!new_elms.is_identical_to(backing_store)) { |
| 1198 receiver->set_elements(*new_elms); |
| 1199 } |
| 1200 DCHECK(*new_elms == receiver->elements()); |
| 1201 // Set the length. |
| 1202 receiver->set_length(Smi::FromInt(new_length)); |
| 1203 return new_length; |
| 1204 } |
| 1143 }; | 1205 }; |
| 1144 | 1206 |
| 1145 | 1207 |
| 1146 template<typename FastElementsAccessorSubclass, | 1208 template<typename FastElementsAccessorSubclass, |
| 1147 typename KindTraits> | 1209 typename KindTraits> |
| 1148 class FastSmiOrObjectElementsAccessor | 1210 class FastSmiOrObjectElementsAccessor |
| 1149 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { | 1211 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { |
| 1150 public: | 1212 public: |
| 1151 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1213 explicit FastSmiOrObjectElementsAccessor(const char* name) |
| 1152 : FastElementsAccessor<FastElementsAccessorSubclass, | 1214 : FastElementsAccessor<FastElementsAccessorSubclass, |
| (...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1910 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 1972 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
| 1911 ELEMENTS_LIST(ACCESSOR_DELETE) | 1973 ELEMENTS_LIST(ACCESSOR_DELETE) |
| 1912 #undef ACCESSOR_DELETE | 1974 #undef ACCESSOR_DELETE |
| 1913 elements_accessors_ = NULL; | 1975 elements_accessors_ = NULL; |
| 1914 } | 1976 } |
| 1915 | 1977 |
| 1916 | 1978 |
| 1917 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 1979 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 1918 } // namespace internal | 1980 } // namespace internal |
| 1919 } // namespace v8 | 1981 } // namespace v8 |
| OLD | NEW |