| 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 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), | 38 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), |
| 39 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); | 39 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); |
| 40 } | 40 } |
| 41 DebugBreak(); | 41 DebugBreak(); |
| 42 Goto(&ok); | 42 Goto(&ok); |
| 43 Bind(&ok); | 43 Bind(&ok); |
| 44 Comment("] Assert"); | 44 Comment("] Assert"); |
| 45 #endif | 45 #endif |
| 46 } | 46 } |
| 47 | 47 |
| 48 Node* CodeStubAssembler::Select(Node* condition, const NodeGenerator& true_body, |
| 49 const NodeGenerator& false_body, |
| 50 MachineRepresentation rep) { |
| 51 Variable value(this, rep); |
| 52 Label vtrue(this), vfalse(this), end(this); |
| 53 Branch(condition, &vtrue, &vfalse); |
| 54 |
| 55 Bind(&vtrue); |
| 56 { |
| 57 value.Bind(true_body()); |
| 58 Goto(&end); |
| 59 } |
| 60 Bind(&vfalse); |
| 61 { |
| 62 value.Bind(false_body()); |
| 63 Goto(&end); |
| 64 } |
| 65 |
| 66 Bind(&end); |
| 67 return value.value(); |
| 68 } |
| 69 |
| 70 Node* CodeStubAssembler::SelectConstant(Node* condition, Node* true_value, |
| 71 Node* false_value, |
| 72 MachineRepresentation rep) { |
| 73 return Select(condition, [=] { return true_value; }, |
| 74 [=] { return false_value; }, rep); |
| 75 } |
| 76 |
| 77 Node* CodeStubAssembler::SelectInt32Constant(Node* condition, int true_value, |
| 78 int false_value) { |
| 79 return SelectConstant(condition, Int32Constant(true_value), |
| 80 Int32Constant(false_value), |
| 81 MachineRepresentation::kWord32); |
| 82 } |
| 83 |
| 84 Node* CodeStubAssembler::SelectIntPtrConstant(Node* condition, int true_value, |
| 85 int false_value) { |
| 86 return SelectConstant(condition, IntPtrConstant(true_value), |
| 87 IntPtrConstant(false_value), |
| 88 MachineType::PointerRepresentation()); |
| 89 } |
| 90 |
| 91 Node* CodeStubAssembler::SelectBooleanConstant(Node* condition) { |
| 92 return SelectConstant(condition, TrueConstant(), FalseConstant(), |
| 93 MachineRepresentation::kTagged); |
| 94 } |
| 95 |
| 96 Node* CodeStubAssembler::SelectTaggedConstant(Node* condition, Node* true_value, |
| 97 Node* false_value) { |
| 98 return SelectConstant(condition, true_value, false_value, |
| 99 MachineRepresentation::kTagged); |
| 100 } |
| 101 |
| 48 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } | 102 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } |
| 49 | 103 |
| 50 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ | 104 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ |
| 51 Node* CodeStubAssembler::name##Constant() { \ | 105 Node* CodeStubAssembler::name##Constant() { \ |
| 52 return LoadRoot(Heap::k##rootName##RootIndex); \ | 106 return LoadRoot(Heap::k##rootName##RootIndex); \ |
| 53 } | 107 } |
| 54 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); | 108 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); |
| 55 #undef HEAP_CONSTANT_ACCESSOR | 109 #undef HEAP_CONSTANT_ACCESSOR |
| 56 | 110 |
| 57 #define HEAP_CONSTANT_TEST(rootName, name) \ | 111 #define HEAP_CONSTANT_TEST(rootName, name) \ |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 value = IntPtrSub(value, IntPtrConstant(1)); | 175 value = IntPtrSub(value, IntPtrConstant(1)); |
| 122 for (int i = 1; i <= 16; i *= 2) { | 176 for (int i = 1; i <= 16; i *= 2) { |
| 123 value = WordOr(value, WordShr(value, IntPtrConstant(i))); | 177 value = WordOr(value, WordShr(value, IntPtrConstant(i))); |
| 124 } | 178 } |
| 125 return IntPtrAdd(value, IntPtrConstant(1)); | 179 return IntPtrAdd(value, IntPtrConstant(1)); |
| 126 } | 180 } |
| 127 | 181 |
| 128 Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { | 182 Node* CodeStubAssembler::WordIsPowerOfTwo(Node* value) { |
| 129 // value && !(value & (value - 1)) | 183 // value && !(value & (value - 1)) |
| 130 return WordEqual( | 184 return WordEqual( |
| 131 Select(WordEqual(value, IntPtrConstant(0)), IntPtrConstant(1), | 185 Select( |
| 132 WordAnd(value, IntPtrSub(value, IntPtrConstant(1))), | 186 WordEqual(value, IntPtrConstant(0)), |
| 133 MachineType::PointerRepresentation()), | 187 [=] { return IntPtrConstant(1); }, |
| 188 [=] { return WordAnd(value, IntPtrSub(value, IntPtrConstant(1))); }, |
| 189 MachineType::PointerRepresentation()), |
| 134 IntPtrConstant(0)); | 190 IntPtrConstant(0)); |
| 135 } | 191 } |
| 136 | 192 |
| 137 Node* CodeStubAssembler::Float64Round(Node* x) { | 193 Node* CodeStubAssembler::Float64Round(Node* x) { |
| 138 Node* one = Float64Constant(1.0); | 194 Node* one = Float64Constant(1.0); |
| 139 Node* one_half = Float64Constant(0.5); | 195 Node* one_half = Float64Constant(0.5); |
| 140 | 196 |
| 141 Variable var_x(this, MachineRepresentation::kFloat64); | 197 Variable var_x(this, MachineRepresentation::kFloat64); |
| 142 Label return_x(this); | 198 Label return_x(this); |
| 143 | 199 |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 470 |
| 415 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { | 471 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { |
| 416 return IntPtrLessThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | 472 return IntPtrLessThan(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
| 417 } | 473 } |
| 418 | 474 |
| 419 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { | 475 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { |
| 420 return IntPtrLessThanOrEqual(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); | 476 return IntPtrLessThanOrEqual(BitcastTaggedToWord(a), BitcastTaggedToWord(b)); |
| 421 } | 477 } |
| 422 | 478 |
| 423 Node* CodeStubAssembler::SmiMax(Node* a, Node* b) { | 479 Node* CodeStubAssembler::SmiMax(Node* a, Node* b) { |
| 424 return Select(SmiLessThan(a, b), b, a); | 480 return SelectTaggedConstant(SmiLessThan(a, b), b, a); |
| 425 } | 481 } |
| 426 | 482 |
| 427 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { | 483 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { |
| 428 return Select(SmiLessThan(a, b), a, b); | 484 return SelectTaggedConstant(SmiLessThan(a, b), a, b); |
| 429 } | 485 } |
| 430 | 486 |
| 431 Node* CodeStubAssembler::SmiMod(Node* a, Node* b) { | 487 Node* CodeStubAssembler::SmiMod(Node* a, Node* b) { |
| 432 Variable var_result(this, MachineRepresentation::kTagged); | 488 Variable var_result(this, MachineRepresentation::kTagged); |
| 433 Label return_result(this, &var_result), | 489 Label return_result(this, &var_result), |
| 434 return_minuszero(this, Label::kDeferred), | 490 return_minuszero(this, Label::kDeferred), |
| 435 return_nan(this, Label::kDeferred); | 491 return_nan(this, Label::kDeferred); |
| 436 | 492 |
| 437 // Untag {a} and {b}. | 493 // Untag {a} and {b}. |
| 438 a = SmiToWord32(a); | 494 a = SmiToWord32(a); |
| (...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2781 Bind(&out); | 2837 Bind(&out); |
| 2782 return var_value_map.value(); | 2838 return var_value_map.value(); |
| 2783 } | 2839 } |
| 2784 | 2840 |
| 2785 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { | 2841 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
| 2786 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 2842 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
| 2787 uint32_t mask = | 2843 uint32_t mask = |
| 2788 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; | 2844 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
| 2789 USE(mask); | 2845 USE(mask); |
| 2790 // Interceptors or access checks imply special receiver. | 2846 // Interceptors or access checks imply special receiver. |
| 2791 CSA_ASSERT(this, Select(IsSetWord32(LoadMapBitField(map), mask), is_special, | 2847 CSA_ASSERT(this, |
| 2792 Int32Constant(1), MachineRepresentation::kWord32)); | 2848 SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, |
| 2849 Int32Constant(1), MachineRepresentation::kWord32)); |
| 2793 return is_special; | 2850 return is_special; |
| 2794 } | 2851 } |
| 2795 | 2852 |
| 2796 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | 2853 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
| 2797 CSA_SLOW_ASSERT(this, IsMap(map)); | 2854 CSA_SLOW_ASSERT(this, IsMap(map)); |
| 2798 Node* bit_field3 = LoadMapBitField3(map); | 2855 Node* bit_field3 = LoadMapBitField3(map); |
| 2799 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), | 2856 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), |
| 2800 Int32Constant(0)); | 2857 Int32Constant(0)); |
| 2801 } | 2858 } |
| 2802 | 2859 |
| (...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4260 template Node* CodeStubAssembler::EntryToIndex<SeededNumberDictionary>(Node*, | 4317 template Node* CodeStubAssembler::EntryToIndex<SeededNumberDictionary>(Node*, |
| 4261 int); | 4318 int); |
| 4262 | 4319 |
| 4263 Node* CodeStubAssembler::HashTableComputeCapacity(Node* at_least_space_for) { | 4320 Node* CodeStubAssembler::HashTableComputeCapacity(Node* at_least_space_for) { |
| 4264 Node* capacity = IntPtrRoundUpToPowerOfTwo32( | 4321 Node* capacity = IntPtrRoundUpToPowerOfTwo32( |
| 4265 WordShl(at_least_space_for, IntPtrConstant(1))); | 4322 WordShl(at_least_space_for, IntPtrConstant(1))); |
| 4266 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); | 4323 return IntPtrMax(capacity, IntPtrConstant(HashTableBase::kMinCapacity)); |
| 4267 } | 4324 } |
| 4268 | 4325 |
| 4269 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { | 4326 Node* CodeStubAssembler::IntPtrMax(Node* left, Node* right) { |
| 4270 return Select(IntPtrGreaterThanOrEqual(left, right), left, right, | 4327 return SelectConstant(IntPtrGreaterThanOrEqual(left, right), left, right, |
| 4271 MachineType::PointerRepresentation()); | 4328 MachineType::PointerRepresentation()); |
| 4272 } | 4329 } |
| 4273 | 4330 |
| 4274 template <class Dictionary> | 4331 template <class Dictionary> |
| 4275 Node* CodeStubAssembler::GetNumberOfElements(Node* dictionary) { | 4332 Node* CodeStubAssembler::GetNumberOfElements(Node* dictionary) { |
| 4276 return LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex); | 4333 return LoadFixedArrayElement(dictionary, Dictionary::kNumberOfElementsIndex); |
| 4277 } | 4334 } |
| 4278 | 4335 |
| 4279 template <class Dictionary> | 4336 template <class Dictionary> |
| 4280 void CodeStubAssembler::SetNumberOfElements(Node* dictionary, | 4337 void CodeStubAssembler::SetNumberOfElements(Node* dictionary, |
| 4281 Node* num_elements_smi) { | 4338 Node* num_elements_smi) { |
| (...skipping 3236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7518 Node* const rhs_float = TryTaggedToFloat64(rhs, &strict_equal); | 7575 Node* const rhs_float = TryTaggedToFloat64(rhs, &strict_equal); |
| 7519 | 7576 |
| 7520 Label if_lhsisnan(this), if_lhsnotnan(this); | 7577 Label if_lhsisnan(this), if_lhsnotnan(this); |
| 7521 BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan); | 7578 BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan); |
| 7522 | 7579 |
| 7523 Bind(&if_lhsisnan); | 7580 Bind(&if_lhsisnan); |
| 7524 { | 7581 { |
| 7525 // Return true iff {rhs} is NaN. | 7582 // Return true iff {rhs} is NaN. |
| 7526 | 7583 |
| 7527 Node* const result = | 7584 Node* const result = |
| 7528 Select(Float64Equal(rhs_float, rhs_float), int_false, int_true, | 7585 SelectConstant(Float64Equal(rhs_float, rhs_float), int_false, |
| 7529 MachineType::PointerRepresentation()); | 7586 int_true, MachineType::PointerRepresentation()); |
| 7530 var_result.Bind(result); | 7587 var_result.Bind(result); |
| 7531 Goto(&out); | 7588 Goto(&out); |
| 7532 } | 7589 } |
| 7533 | 7590 |
| 7534 Bind(&if_lhsnotnan); | 7591 Bind(&if_lhsnotnan); |
| 7535 { | 7592 { |
| 7536 Label if_floatisequal(this), if_floatnotequal(this); | 7593 Label if_floatisequal(this), if_floatnotequal(this); |
| 7537 Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal, | 7594 Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal, |
| 7538 &if_floatnotequal); | 7595 &if_floatnotequal); |
| 7539 | 7596 |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8149 | 8206 |
| 8150 Node* CodeStubAssembler::IsDebugActive() { | 8207 Node* CodeStubAssembler::IsDebugActive() { |
| 8151 Node* is_debug_active = Load( | 8208 Node* is_debug_active = Load( |
| 8152 MachineType::Uint8(), | 8209 MachineType::Uint8(), |
| 8153 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); | 8210 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); |
| 8154 return WordNotEqual(is_debug_active, Int32Constant(0)); | 8211 return WordNotEqual(is_debug_active, Int32Constant(0)); |
| 8155 } | 8212 } |
| 8156 | 8213 |
| 8157 } // namespace internal | 8214 } // namespace internal |
| 8158 } // namespace v8 | 8215 } // namespace v8 |
| OLD | NEW |