OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stub-assembler.h" | 9 #include "src/code-stub-assembler.h" |
10 #include "src/contexts.h" | 10 #include "src/contexts.h" |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 Node* test = assembler.Word32And(bit_field2, assembler.Int32Constant(mask)); | 218 Node* test = assembler.Word32And(bit_field2, assembler.Int32Constant(mask)); |
219 assembler.GotoIf( | 219 assembler.GotoIf( |
220 assembler.Word32NotEqual( | 220 assembler.Word32NotEqual( |
221 test, assembler.Int32Constant(1 << Map::kIsExtensible)), | 221 test, assembler.Int32Constant(1 << Map::kIsExtensible)), |
222 &runtime); | 222 &runtime); |
223 | 223 |
224 // Disallow pushing onto arrays in dictionary named property mode. We need | 224 // Disallow pushing onto arrays in dictionary named property mode. We need |
225 // to figure out whether the length property is still writable. | 225 // to figure out whether the length property is still writable. |
226 assembler.Comment( | 226 assembler.Comment( |
227 "Disallow pushing onto arrays in dictionary named property mode"); | 227 "Disallow pushing onto arrays in dictionary named property mode"); |
228 Node* bit_field3 = assembler.LoadMapBitField3(map); | 228 assembler.GotoIf(assembler.IsDictionaryMap(map), &runtime); |
229 assembler.GotoIf(assembler.IsSetWord32<Map::DictionaryMap>(bit_field3), | |
230 &runtime); | |
231 | 229 |
232 // Check whether the length property is writable. The length property is the | 230 // Check whether the length property is writable. The length property is the |
233 // only default named property on arrays. It's nonconfigurable, hence is | 231 // only default named property on arrays. It's nonconfigurable, hence is |
234 // guaranteed to stay the first property. | 232 // guaranteed to stay the first property. |
235 Node* descriptors = assembler.LoadMapDescriptors(map); | 233 Node* descriptors = assembler.LoadMapDescriptors(map); |
236 Node* details = assembler.LoadFixedArrayElement( | 234 Node* details = assembler.LoadFixedArrayElement( |
237 descriptors, DescriptorArray::ToDetailsIndex(0)); | 235 descriptors, DescriptorArray::ToDetailsIndex(0)); |
238 mask = READ_ONLY << PropertyDetails::AttributesField::kShift; | 236 mask = READ_ONLY << PropertyDetails::AttributesField::kShift; |
239 Node* mask_node = assembler.SmiConstant(mask); | 237 Node* mask_node = assembler.SmiConstant(mask); |
240 test = assembler.WordAnd(details, mask_node); | 238 test = assembler.SmiAnd(details, mask_node); |
241 assembler.GotoIf(assembler.WordEqual(test, mask_node), &runtime); | 239 assembler.GotoIf(assembler.WordEqual(test, mask_node), &runtime); |
242 | 240 |
243 arg_index.Bind(assembler.IntPtrConstant(0)); | 241 arg_index.Bind(assembler.IntPtrConstant(0)); |
244 kind = assembler.DecodeWord32<Map::ElementsKindBits>(bit_field2); | 242 kind = assembler.DecodeWord32<Map::ElementsKindBits>(bit_field2); |
245 | 243 |
246 assembler.GotoIf( | 244 assembler.GotoIf( |
247 assembler.IntPtrGreaterThan( | 245 assembler.Int32GreaterThan( |
248 kind, assembler.IntPtrConstant(FAST_HOLEY_SMI_ELEMENTS)), | 246 kind, assembler.Int32Constant(FAST_HOLEY_SMI_ELEMENTS)), |
249 &object_push_pre); | 247 &object_push_pre); |
250 | 248 |
251 Node* new_length = assembler.BuildAppendJSArray( | 249 Node* new_length = assembler.BuildAppendJSArray( |
252 FAST_SMI_ELEMENTS, context, receiver, args, arg_index, &smi_transition); | 250 FAST_SMI_ELEMENTS, context, receiver, args, arg_index, &smi_transition); |
253 args.PopAndReturn(new_length); | 251 args.PopAndReturn(new_length); |
254 } | 252 } |
255 | 253 |
256 // If the argument is not a smi, then use a heavyweight SetProperty to | 254 // If the argument is not a smi, then use a heavyweight SetProperty to |
257 // transition the array for only the single next element. If the argument is | 255 // transition the array for only the single next element. If the argument is |
258 // a smi, the failure is due to some other reason and we should fall back on | 256 // a smi, the failure is due to some other reason and we should fall back on |
259 // the most generic implementation for the rest of the array. | 257 // the most generic implementation for the rest of the array. |
260 assembler.Bind(&smi_transition); | 258 assembler.Bind(&smi_transition); |
261 { | 259 { |
262 Node* arg = args.AtIndex(arg_index.value()); | 260 Node* arg = args.AtIndex(arg_index.value()); |
263 assembler.GotoIf(assembler.TaggedIsSmi(arg), &default_label); | 261 assembler.GotoIf(assembler.TaggedIsSmi(arg), &default_label); |
264 Node* length = assembler.LoadJSArrayLength(receiver); | 262 Node* length = assembler.LoadJSArrayLength(receiver); |
265 // TODO(danno): Use the KeyedStoreGeneric stub here when possible, | 263 // TODO(danno): Use the KeyedStoreGeneric stub here when possible, |
266 // calling into the runtime to do the elements transition is overkill. | 264 // calling into the runtime to do the elements transition is overkill. |
267 assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, | 265 assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, |
268 assembler.SmiConstant(STRICT)); | 266 assembler.SmiConstant(STRICT)); |
269 assembler.Increment(arg_index); | 267 assembler.Increment(arg_index); |
270 assembler.GotoIfNotNumber(arg, &object_push); | 268 assembler.GotoIfNotNumber(arg, &object_push); |
271 assembler.Goto(&double_push); | 269 assembler.Goto(&double_push); |
272 } | 270 } |
273 | 271 |
274 assembler.Bind(&object_push_pre); | 272 assembler.Bind(&object_push_pre); |
275 { | 273 { |
276 assembler.Branch(assembler.IntPtrGreaterThan( | 274 assembler.Branch(assembler.Int32GreaterThan( |
277 kind, assembler.IntPtrConstant(FAST_HOLEY_ELEMENTS)), | 275 kind, assembler.Int32Constant(FAST_HOLEY_ELEMENTS)), |
278 &double_push, &object_push); | 276 &double_push, &object_push); |
279 } | 277 } |
280 | 278 |
281 assembler.Bind(&object_push); | 279 assembler.Bind(&object_push); |
282 { | 280 { |
283 Node* new_length = assembler.BuildAppendJSArray( | 281 Node* new_length = assembler.BuildAppendJSArray( |
284 FAST_ELEMENTS, context, receiver, args, arg_index, &default_label); | 282 FAST_ELEMENTS, context, receiver, args, arg_index, &default_label); |
285 args.PopAndReturn(new_length); | 283 args.PopAndReturn(new_length); |
286 } | 284 } |
287 | 285 |
(...skipping 1907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 | 2193 |
2196 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), | 2194 assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), |
2197 &return_found, &continue_loop); | 2195 &return_found, &continue_loop); |
2198 assembler.Bind(&continue_loop); | 2196 assembler.Bind(&continue_loop); |
2199 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); | 2197 index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); |
2200 assembler.Goto(¬_nan_loop); | 2198 assembler.Goto(¬_nan_loop); |
2201 } | 2199 } |
2202 } | 2200 } |
2203 | 2201 |
2204 assembler.Bind(&return_found); | 2202 assembler.Bind(&return_found); |
2205 assembler.Return(assembler.ChangeInt32ToTagged(index_var.value())); | 2203 assembler.Return(assembler.SmiTag(index_var.value())); |
2206 | 2204 |
2207 assembler.Bind(&return_not_found); | 2205 assembler.Bind(&return_not_found); |
2208 assembler.Return(assembler.NumberConstant(-1)); | 2206 assembler.Return(assembler.NumberConstant(-1)); |
2209 | 2207 |
2210 assembler.Bind(&call_runtime); | 2208 assembler.Bind(&call_runtime); |
2211 assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, | 2209 assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, |
2212 search_element, start_from)); | 2210 search_element, start_from)); |
2213 } | 2211 } |
2214 | 2212 |
2215 namespace { | 2213 namespace { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2332 assembler.Int32Constant(JS_ARRAY_TYPE))); | 2330 assembler.Int32Constant(JS_ARRAY_TYPE))); |
2333 | 2331 |
2334 Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); | 2332 Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); |
2335 | 2333 |
2336 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); | 2334 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); |
2337 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); | 2335 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); |
2338 | 2336 |
2339 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); | 2337 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); |
2340 | 2338 |
2341 Node* one = assembler.SmiConstant(Smi::FromInt(1)); | 2339 Node* one = assembler.SmiConstant(Smi::FromInt(1)); |
2342 assembler.StoreObjectFieldNoWriteBarrier( | 2340 assembler.StoreObjectFieldNoWriteBarrier(iterator, |
2343 iterator, JSArrayIterator::kNextIndexOffset, | 2341 JSArrayIterator::kNextIndexOffset, |
2344 assembler.IntPtrAdd(assembler.BitcastTaggedToWord(index), | 2342 assembler.SmiAdd(index, one)); |
2345 assembler.BitcastTaggedToWord(one))); | |
2346 | 2343 |
2347 var_done.Bind(assembler.FalseConstant()); | 2344 var_done.Bind(assembler.FalseConstant()); |
2348 Node* elements = assembler.LoadElements(array); | 2345 Node* elements = assembler.LoadElements(array); |
2349 | 2346 |
2350 static int32_t kInstanceType[] = { | 2347 static int32_t kInstanceType[] = { |
2351 JS_FAST_ARRAY_KEY_ITERATOR_TYPE, | 2348 JS_FAST_ARRAY_KEY_ITERATOR_TYPE, |
2352 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2349 JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2353 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2350 JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2354 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2351 JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2355 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2352 JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2559 } | 2556 } |
2560 | 2557 |
2561 assembler.Bind(&done); | 2558 assembler.Bind(&done); |
2562 length = var_length.value(); | 2559 length = var_length.value(); |
2563 } | 2560 } |
2564 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); | 2561 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); |
2565 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); | 2562 CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); |
2566 | 2563 |
2567 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); | 2564 assembler.GotoUnless(assembler.SmiBelow(index, length), &set_done); |
2568 | 2565 |
2569 Node* one = assembler.SmiConstant(Smi::FromInt(1)); | 2566 Node* one = assembler.SmiConstant(1); |
2570 assembler.StoreObjectFieldNoWriteBarrier( | 2567 assembler.StoreObjectFieldNoWriteBarrier( |
2571 iterator, JSArrayIterator::kNextIndexOffset, | 2568 iterator, JSArrayIterator::kNextIndexOffset, |
2572 assembler.IntPtrAdd(assembler.BitcastTaggedToWord(index), | 2569 assembler.SmiAdd(index, one)); |
2573 assembler.BitcastTaggedToWord(one))); | |
2574 var_done.Bind(assembler.FalseConstant()); | 2570 var_done.Bind(assembler.FalseConstant()); |
2575 | 2571 |
2576 Node* elements = assembler.LoadElements(array); | 2572 Node* elements = assembler.LoadElements(array); |
2577 Node* base_ptr = assembler.LoadObjectField( | 2573 Node* base_ptr = assembler.LoadObjectField( |
2578 elements, FixedTypedArrayBase::kBasePointerOffset); | 2574 elements, FixedTypedArrayBase::kBasePointerOffset); |
2579 Node* external_ptr = assembler.LoadObjectField( | 2575 Node* external_ptr = assembler.LoadObjectField( |
2580 elements, FixedTypedArrayBase::kExternalPointerOffset); | 2576 elements, FixedTypedArrayBase::kExternalPointerOffset, |
2581 Node* data_ptr = assembler.IntPtrAdd(base_ptr, external_ptr); | 2577 MachineType::Pointer()); |
| 2578 Node* data_ptr = assembler.IntPtrAdd( |
| 2579 assembler.BitcastTaggedToWord(base_ptr), external_ptr); |
2582 | 2580 |
2583 static int32_t kInstanceType[] = { | 2581 static int32_t kInstanceType[] = { |
2584 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, | 2582 JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, |
2585 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2583 JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2586 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2584 JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2587 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2585 JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2588 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2586 JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2589 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2587 JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2590 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2588 JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
2591 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, | 2589 JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE, |
(...skipping 25 matching lines...) Expand all Loading... |
2617 }; | 2615 }; |
2618 | 2616 |
2619 var_done.Bind(assembler.FalseConstant()); | 2617 var_done.Bind(assembler.FalseConstant()); |
2620 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, | 2618 assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, |
2621 kInstanceTypeHandlers, arraysize(kInstanceType)); | 2619 kInstanceTypeHandlers, arraysize(kInstanceType)); |
2622 | 2620 |
2623 assembler.Bind(&uint8_values); | 2621 assembler.Bind(&uint8_values); |
2624 { | 2622 { |
2625 Node* value_uint8 = assembler.LoadFixedTypedArrayElement( | 2623 Node* value_uint8 = assembler.LoadFixedTypedArrayElement( |
2626 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2624 data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2627 var_value.Bind(assembler.SmiFromWord(value_uint8)); | 2625 var_value.Bind(assembler.SmiFromWord32(value_uint8)); |
2628 assembler.Goto(&allocate_entry_if_needed); | 2626 assembler.Goto(&allocate_entry_if_needed); |
2629 } | 2627 } |
2630 | 2628 |
2631 assembler.Bind(&int8_values); | 2629 assembler.Bind(&int8_values); |
2632 { | 2630 { |
2633 Node* value_int8 = assembler.LoadFixedTypedArrayElement( | 2631 Node* value_int8 = assembler.LoadFixedTypedArrayElement( |
2634 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2632 data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2635 var_value.Bind(assembler.SmiFromWord(value_int8)); | 2633 var_value.Bind(assembler.SmiFromWord32(value_int8)); |
2636 assembler.Goto(&allocate_entry_if_needed); | 2634 assembler.Goto(&allocate_entry_if_needed); |
2637 } | 2635 } |
2638 | 2636 |
2639 assembler.Bind(&uint16_values); | 2637 assembler.Bind(&uint16_values); |
2640 { | 2638 { |
2641 Node* value_uint16 = assembler.LoadFixedTypedArrayElement( | 2639 Node* value_uint16 = assembler.LoadFixedTypedArrayElement( |
2642 data_ptr, index, UINT16_ELEMENTS, | 2640 data_ptr, index, UINT16_ELEMENTS, |
2643 CodeStubAssembler::SMI_PARAMETERS); | 2641 CodeStubAssembler::SMI_PARAMETERS); |
2644 var_value.Bind(assembler.SmiFromWord(value_uint16)); | 2642 var_value.Bind(assembler.SmiFromWord32(value_uint16)); |
2645 assembler.Goto(&allocate_entry_if_needed); | 2643 assembler.Goto(&allocate_entry_if_needed); |
2646 } | 2644 } |
2647 | 2645 |
2648 assembler.Bind(&int16_values); | 2646 assembler.Bind(&int16_values); |
2649 { | 2647 { |
2650 Node* value_int16 = assembler.LoadFixedTypedArrayElement( | 2648 Node* value_int16 = assembler.LoadFixedTypedArrayElement( |
2651 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); | 2649 data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); |
2652 var_value.Bind(assembler.SmiFromWord(value_int16)); | 2650 var_value.Bind(assembler.SmiFromWord32(value_int16)); |
2653 assembler.Goto(&allocate_entry_if_needed); | 2651 assembler.Goto(&allocate_entry_if_needed); |
2654 } | 2652 } |
2655 | 2653 |
2656 assembler.Bind(&uint32_values); | 2654 assembler.Bind(&uint32_values); |
2657 { | 2655 { |
2658 Node* value_uint32 = assembler.LoadFixedTypedArrayElement( | 2656 Node* value_uint32 = assembler.LoadFixedTypedArrayElement( |
2659 data_ptr, index, UINT32_ELEMENTS, | 2657 data_ptr, index, UINT32_ELEMENTS, |
2660 CodeStubAssembler::SMI_PARAMETERS); | 2658 CodeStubAssembler::SMI_PARAMETERS); |
2661 var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); | 2659 var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); |
2662 assembler.Goto(&allocate_entry_if_needed); | 2660 assembler.Goto(&allocate_entry_if_needed); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2759 Runtime::kThrowIncompatibleMethodReceiver, context, | 2757 Runtime::kThrowIncompatibleMethodReceiver, context, |
2760 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( | 2758 assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( |
2761 "Array Iterator.prototype.next", TENURED)), | 2759 "Array Iterator.prototype.next", TENURED)), |
2762 iterator); | 2760 iterator); |
2763 assembler.Return(result); | 2761 assembler.Return(result); |
2764 } | 2762 } |
2765 } | 2763 } |
2766 | 2764 |
2767 } // namespace internal | 2765 } // namespace internal |
2768 } // namespace v8 | 2766 } // namespace v8 |
OLD | NEW |