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 |