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 // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the | |
Jakob Kummerow
2015/07/31 12:24:14
nit: s/to_add/push_size/
| |
1181 // empty_fixed_array. | |
1182 new_elms = backing_store; | |
1183 } | |
1184 | |
1185 // Add the provided values. | |
1186 DisallowHeapAllocation no_gc; | |
1187 DCHECK(direction == ElementsAccessor::kDirectionForward || | |
1188 direction == ElementsAccessor::kDirectionReverse); | |
1189 for (uint32_t index = 0; index < push_size; index++) { | |
1190 int offset = direction * index; | |
Jakob Kummerow
2015/07/31 12:24:14
This implementation depends on the direction senti
| |
1191 Object* object = objects[offset]; | |
1192 FastElementsAccessorSubclass::SetImpl(*new_elms, index + len, object); | |
1193 } | |
1194 if (!new_elms.is_identical_to(backing_store)) { | |
1195 receiver->set_elements(*new_elms); | |
1196 } | |
1197 DCHECK(*new_elms == receiver->elements()); | |
1198 // Set the length. | |
1199 receiver->set_length(Smi::FromInt(new_length)); | |
1200 return new_length; | |
1201 } | |
1143 }; | 1202 }; |
1144 | 1203 |
1145 | 1204 |
1146 template<typename FastElementsAccessorSubclass, | 1205 template<typename FastElementsAccessorSubclass, |
1147 typename KindTraits> | 1206 typename KindTraits> |
1148 class FastSmiOrObjectElementsAccessor | 1207 class FastSmiOrObjectElementsAccessor |
1149 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { | 1208 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { |
1150 public: | 1209 public: |
1151 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1210 explicit FastSmiOrObjectElementsAccessor(const char* name) |
1152 : FastElementsAccessor<FastElementsAccessorSubclass, | 1211 : 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]; | 1969 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
1911 ELEMENTS_LIST(ACCESSOR_DELETE) | 1970 ELEMENTS_LIST(ACCESSOR_DELETE) |
1912 #undef ACCESSOR_DELETE | 1971 #undef ACCESSOR_DELETE |
1913 elements_accessors_ = NULL; | 1972 elements_accessors_ = NULL; |
1914 } | 1973 } |
1915 | 1974 |
1916 | 1975 |
1917 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 1976 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
1918 } // namespace internal | 1977 } // namespace internal |
1919 } // namespace v8 | 1978 } // namespace v8 |
OLD | NEW |