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 |