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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 #include "src/ic/handler-configuration.h" | 8 #include "src/ic/handler-configuration.h" |
9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
10 | 10 |
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 GotoUnless(is_map_type, &done); | 1104 GotoUnless(is_map_type, &done); |
1105 result.Bind( | 1105 result.Bind( |
1106 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); | 1106 LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset)); |
1107 Goto(&loop); | 1107 Goto(&loop); |
1108 } | 1108 } |
1109 Bind(&done); | 1109 Bind(&done); |
1110 return result.value(); | 1110 return result.value(); |
1111 } | 1111 } |
1112 | 1112 |
1113 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { | 1113 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
| 1114 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
1114 Node* bit_field = LoadMapBitField(map); | 1115 Node* bit_field = LoadMapBitField(map); |
1115 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | | 1116 uint32_t mask = |
1116 1 << Map::kIsAccessCheckNeeded); | 1117 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
1117 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 1118 // Interceptors or access checks imply special receiver. |
1118 return IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 1119 CSA_ASSERT( |
| 1120 Select(IsSetWord32(bit_field, mask), is_special, Int32Constant(1))); |
| 1121 return is_special; |
1119 } | 1122 } |
1120 | 1123 |
1121 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { | 1124 Node* CodeStubAssembler::IsSpecialReceiverInstanceType(Node* instance_type) { |
1122 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 1125 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
1123 return Int32LessThanOrEqual(instance_type, | 1126 return Int32LessThanOrEqual(instance_type, |
1124 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); | 1127 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)); |
1125 } | 1128 } |
1126 | 1129 |
1127 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | 1130 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
1128 Node* bit_field3 = LoadMapBitField3(map); | 1131 Node* bit_field3 = LoadMapBitField3(map); |
(...skipping 5779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6908 BranchIfSmiLessThan(rhs, lhs, if_true, if_false); | 6911 BranchIfSmiLessThan(rhs, lhs, if_true, if_false); |
6909 break; | 6912 break; |
6910 case kGreaterThanOrEqual: | 6913 case kGreaterThanOrEqual: |
6911 BranchIfSmiLessThanOrEqual(rhs, lhs, if_true, if_false); | 6914 BranchIfSmiLessThanOrEqual(rhs, lhs, if_true, if_false); |
6912 break; | 6915 break; |
6913 } | 6916 } |
6914 } | 6917 } |
6915 | 6918 |
6916 Bind(&if_rhsisnotsmi); | 6919 Bind(&if_rhsisnotsmi); |
6917 { | 6920 { |
6918 Assert(WordEqual(LoadMap(rhs), HeapNumberMapConstant())); | 6921 CSA_ASSERT(WordEqual(LoadMap(rhs), HeapNumberMapConstant())); |
6919 // Convert the {lhs} and {rhs} to floating point values, and | 6922 // Convert the {lhs} and {rhs} to floating point values, and |
6920 // perform a floating point comparison. | 6923 // perform a floating point comparison. |
6921 var_fcmp_lhs.Bind(SmiToFloat64(lhs)); | 6924 var_fcmp_lhs.Bind(SmiToFloat64(lhs)); |
6922 var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs)); | 6925 var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs)); |
6923 Goto(&do_fcmp); | 6926 Goto(&do_fcmp); |
6924 } | 6927 } |
6925 } | 6928 } |
6926 | 6929 |
6927 Bind(&if_lhsisnotsmi); | 6930 Bind(&if_lhsisnotsmi); |
6928 { | 6931 { |
6929 Assert(WordEqual(LoadMap(lhs), HeapNumberMapConstant())); | 6932 CSA_ASSERT(WordEqual(LoadMap(lhs), HeapNumberMapConstant())); |
6930 | 6933 |
6931 // Check if {rhs} is a Smi or a HeapObject. | 6934 // Check if {rhs} is a Smi or a HeapObject. |
6932 Label if_rhsissmi(this), if_rhsisnotsmi(this); | 6935 Label if_rhsissmi(this), if_rhsisnotsmi(this); |
6933 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); | 6936 Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); |
6934 | 6937 |
6935 Bind(&if_rhsissmi); | 6938 Bind(&if_rhsissmi); |
6936 { | 6939 { |
6937 // Convert the {lhs} and {rhs} to floating point values, and | 6940 // Convert the {lhs} and {rhs} to floating point values, and |
6938 // perform a floating point comparison. | 6941 // perform a floating point comparison. |
6939 var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs)); | 6942 var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs)); |
6940 var_fcmp_rhs.Bind(SmiToFloat64(rhs)); | 6943 var_fcmp_rhs.Bind(SmiToFloat64(rhs)); |
6941 Goto(&do_fcmp); | 6944 Goto(&do_fcmp); |
6942 } | 6945 } |
6943 | 6946 |
6944 Bind(&if_rhsisnotsmi); | 6947 Bind(&if_rhsisnotsmi); |
6945 { | 6948 { |
6946 Assert(WordEqual(LoadMap(rhs), HeapNumberMapConstant())); | 6949 CSA_ASSERT(WordEqual(LoadMap(rhs), HeapNumberMapConstant())); |
6947 | 6950 |
6948 // Convert the {lhs} and {rhs} to floating point values, and | 6951 // Convert the {lhs} and {rhs} to floating point values, and |
6949 // perform a floating point comparison. | 6952 // perform a floating point comparison. |
6950 var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs)); | 6953 var_fcmp_lhs.Bind(LoadHeapNumberValue(lhs)); |
6951 var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs)); | 6954 var_fcmp_rhs.Bind(LoadHeapNumberValue(rhs)); |
6952 Goto(&do_fcmp); | 6955 Goto(&do_fcmp); |
6953 } | 6956 } |
6954 } | 6957 } |
6955 | 6958 |
6956 Bind(&do_fcmp); | 6959 Bind(&do_fcmp); |
(...skipping 1396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8353 Bind(&if_overflow); | 8356 Bind(&if_overflow); |
8354 { | 8357 { |
8355 var_finc_value.Bind(SmiToFloat64(value)); | 8358 var_finc_value.Bind(SmiToFloat64(value)); |
8356 Goto(&do_finc); | 8359 Goto(&do_finc); |
8357 } | 8360 } |
8358 } | 8361 } |
8359 | 8362 |
8360 Bind(&if_isnotsmi); | 8363 Bind(&if_isnotsmi); |
8361 { | 8364 { |
8362 // Check if the value is a HeapNumber. | 8365 // Check if the value is a HeapNumber. |
8363 Assert(IsHeapNumberMap(LoadMap(value))); | 8366 CSA_ASSERT(IsHeapNumberMap(LoadMap(value))); |
8364 | 8367 |
8365 // Load the HeapNumber value. | 8368 // Load the HeapNumber value. |
8366 var_finc_value.Bind(LoadHeapNumberValue(value)); | 8369 var_finc_value.Bind(LoadHeapNumberValue(value)); |
8367 Goto(&do_finc); | 8370 Goto(&do_finc); |
8368 } | 8371 } |
8369 | 8372 |
8370 Bind(&do_finc); | 8373 Bind(&do_finc); |
8371 { | 8374 { |
8372 Node* finc_value = var_finc_value.value(); | 8375 Node* finc_value = var_finc_value.value(); |
8373 Node* one = Float64Constant(1.0); | 8376 Node* one = Float64Constant(1.0); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8408 | 8411 |
8409 // Slow Array iterator map index: (kBaseIndex + kSlowIteratorOffset) | 8412 // Slow Array iterator map index: (kBaseIndex + kSlowIteratorOffset) |
8410 const int kSlowIteratorOffset = | 8413 const int kSlowIteratorOffset = |
8411 Context::GENERIC_ARRAY_VALUE_ITERATOR_MAP_INDEX - | 8414 Context::GENERIC_ARRAY_VALUE_ITERATOR_MAP_INDEX - |
8412 Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; | 8415 Context::UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX; |
8413 STATIC_ASSERT(kSlowIteratorOffset == | 8416 STATIC_ASSERT(kSlowIteratorOffset == |
8414 (Context::GENERIC_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX - | 8417 (Context::GENERIC_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX - |
8415 Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX)); | 8418 Context::UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX)); |
8416 | 8419 |
8417 // Assert: Type(array) is Object | 8420 // Assert: Type(array) is Object |
8418 Assert(IsJSReceiverInstanceType(array_type)); | 8421 CSA_ASSERT(IsJSReceiverInstanceType(array_type)); |
8419 | 8422 |
8420 Variable var_result(this, MachineRepresentation::kTagged); | 8423 Variable var_result(this, MachineRepresentation::kTagged); |
8421 Variable var_map_index(this, MachineType::PointerRepresentation()); | 8424 Variable var_map_index(this, MachineType::PointerRepresentation()); |
8422 Variable var_array_map(this, MachineRepresentation::kTagged); | 8425 Variable var_array_map(this, MachineRepresentation::kTagged); |
8423 | 8426 |
8424 Label return_result(this); | 8427 Label return_result(this); |
8425 Label allocate_iterator(this); | 8428 Label allocate_iterator(this); |
8426 | 8429 |
8427 if (mode == IterationKind::kKeys) { | 8430 if (mode == IterationKind::kKeys) { |
8428 // There are only two key iterator maps, branch depending on whether or not | 8431 // There are only two key iterator maps, branch depending on whether or not |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8467 Bind(&if_isgeneric); | 8470 Bind(&if_isgeneric); |
8468 { | 8471 { |
8469 Label if_isfast(this), if_isslow(this); | 8472 Label if_isfast(this), if_isslow(this); |
8470 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); | 8473 BranchIfFastJSArray(array, context, &if_isfast, &if_isslow); |
8471 | 8474 |
8472 Bind(&if_isfast); | 8475 Bind(&if_isfast); |
8473 { | 8476 { |
8474 Node* map_index = | 8477 Node* map_index = |
8475 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), | 8478 IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset), |
8476 LoadMapElementsKind(array_map)); | 8479 LoadMapElementsKind(array_map)); |
8477 Assert(IntPtrGreaterThanOrEqual( | 8480 CSA_ASSERT(IntPtrGreaterThanOrEqual( |
8478 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); | 8481 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); |
8479 Assert(IntPtrLessThan( | 8482 CSA_ASSERT(IntPtrLessThan( |
8480 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset))); | 8483 map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset))); |
8481 | 8484 |
8482 var_map_index.Bind(map_index); | 8485 var_map_index.Bind(map_index); |
8483 var_array_map.Bind(array_map); | 8486 var_array_map.Bind(array_map); |
8484 Goto(&allocate_iterator); | 8487 Goto(&allocate_iterator); |
8485 } | 8488 } |
8486 | 8489 |
8487 Bind(&if_isslow); | 8490 Bind(&if_isslow); |
8488 { | 8491 { |
8489 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), | 8492 Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex), |
8490 IntPtrConstant(kSlowIteratorOffset)); | 8493 IntPtrConstant(kSlowIteratorOffset)); |
8491 var_map_index.Bind(map_index); | 8494 var_map_index.Bind(map_index); |
8492 var_array_map.Bind(UndefinedConstant()); | 8495 var_array_map.Bind(UndefinedConstant()); |
8493 Goto(&allocate_iterator); | 8496 Goto(&allocate_iterator); |
8494 } | 8497 } |
8495 } | 8498 } |
8496 | 8499 |
8497 Bind(&if_istypedarray); | 8500 Bind(&if_istypedarray); |
8498 { | 8501 { |
8499 Node* map_index = | 8502 Node* map_index = |
8500 IntPtrAdd(IntPtrConstant(kBaseMapIndex - UINT8_ELEMENTS), | 8503 IntPtrAdd(IntPtrConstant(kBaseMapIndex - UINT8_ELEMENTS), |
8501 LoadMapElementsKind(array_map)); | 8504 LoadMapElementsKind(array_map)); |
8502 Assert(IntPtrLessThan( | 8505 CSA_ASSERT(IntPtrLessThan( |
8503 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); | 8506 map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset))); |
8504 Assert( | 8507 CSA_ASSERT( |
8505 IntPtrGreaterThanOrEqual(map_index, IntPtrConstant(kBaseMapIndex))); | 8508 IntPtrGreaterThanOrEqual(map_index, IntPtrConstant(kBaseMapIndex))); |
8506 var_map_index.Bind(map_index); | 8509 var_map_index.Bind(map_index); |
8507 var_array_map.Bind(UndefinedConstant()); | 8510 var_array_map.Bind(UndefinedConstant()); |
8508 Goto(&allocate_iterator); | 8511 Goto(&allocate_iterator); |
8509 } | 8512 } |
8510 } | 8513 } |
8511 | 8514 |
8512 Bind(&allocate_iterator); | 8515 Bind(&allocate_iterator); |
8513 { | 8516 { |
8514 Node* map = | 8517 Node* map = |
(...skipping 30 matching lines...) Expand all Loading... |
8545 Node* buffer_bit_field = LoadObjectField( | 8548 Node* buffer_bit_field = LoadObjectField( |
8546 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); | 8549 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); |
8547 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); | 8550 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); |
8548 | 8551 |
8549 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), | 8552 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), |
8550 Int32Constant(0)); | 8553 Int32Constant(0)); |
8551 } | 8554 } |
8552 | 8555 |
8553 } // namespace internal | 8556 } // namespace internal |
8554 } // namespace v8 | 8557 } // namespace v8 |
OLD | NEW |