| 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 |