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 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 using compiler::Node; | 14 using compiler::Node; |
15 | 15 |
16 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, | 16 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, |
17 const CallInterfaceDescriptor& descriptor, | 17 const CallInterfaceDescriptor& descriptor, |
18 Code::Flags flags, const char* name, | 18 Code::Flags flags, const char* name, |
19 size_t result_size) | 19 size_t result_size) |
20 : compiler::CodeAssembler(isolate, zone, descriptor, flags, name, | 20 : compiler::CodeAssembler(isolate, zone, descriptor, flags, name, |
21 result_size) {} | 21 result_size) {} |
22 | 22 |
23 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, | 23 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, |
24 int parameter_count, Code::Flags flags, | 24 int parameter_count, Code::Flags flags, |
25 const char* name) | 25 const char* name) |
26 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} | 26 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} |
27 | 27 |
28 void CodeStubAssembler::Assert(Node* condition, const char* message, | 28 void CodeStubAssembler::Assert(ConditionBody codition_body, const char* message, |
29 const char* file, int line) { | 29 const char* file, int line) { |
30 #if defined(DEBUG) | 30 #if defined(DEBUG) |
31 Label ok(this); | 31 Label ok(this); |
32 Label not_ok(this, Label::kDeferred); | 32 Label not_ok(this, Label::kDeferred); |
33 if (message != nullptr && FLAG_code_comments) { | 33 if (message != nullptr && FLAG_code_comments) { |
34 Comment("[ Assert: %s", message); | 34 Comment("[ Assert: %s", message); |
35 } else { | 35 } else { |
36 Comment("[ Assert "); | 36 Comment("[ Assert"); |
37 } | 37 } |
38 | 38 Node* condition = codition_body(); |
| 39 DCHECK_NOT_NULL(condition); |
39 Branch(condition, &ok, ¬_ok); | 40 Branch(condition, &ok, ¬_ok); |
40 Bind(¬_ok); | 41 Bind(¬_ok); |
41 if (message != nullptr) { | 42 if (message != nullptr) { |
42 char chars[1024]; | 43 char chars[1024]; |
43 Vector<char> buffer(chars); | 44 Vector<char> buffer(chars); |
44 if (file != nullptr) { | 45 if (file != nullptr) { |
45 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); | 46 SNPrintF(buffer, "CSA_ASSERT failed: %s [%s:%d]\n", message, file, line); |
46 } else { | 47 } else { |
47 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); | 48 SNPrintF(buffer, "CSA_ASSERT failed: %s\n", message); |
48 } | 49 } |
49 CallRuntime( | 50 CallRuntime( |
50 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), | 51 Runtime::kGlobalPrint, SmiConstant(Smi::kZero), |
51 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); | 52 HeapConstant(factory()->NewStringFromAsciiChecked(&(buffer[0])))); |
52 } | 53 } |
53 DebugBreak(); | 54 DebugBreak(); |
54 Goto(&ok); | 55 Goto(&ok); |
55 Bind(&ok); | 56 Bind(&ok); |
56 Comment("] Assert"); | 57 Comment("] Assert"); |
57 #endif | 58 #endif |
58 } | 59 } |
59 | 60 |
| 61 void CodeStubAssembler::SlowAssert(ConditionBody codition_body, |
| 62 const char* message, const char* file, |
| 63 int line) { |
| 64 #ifdef ENABLE_SLOW_DCHECKS |
| 65 if (FLAG_enable_slow_asserts) { |
| 66 Assert(codition_body, message, file, line); |
| 67 } |
| 68 #endif |
| 69 } |
| 70 |
60 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } | 71 Node* CodeStubAssembler::NoContextConstant() { return NumberConstant(0); } |
61 | 72 |
62 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ | 73 #define HEAP_CONSTANT_ACCESSOR(rootName, name) \ |
63 Node* CodeStubAssembler::name##Constant() { \ | 74 Node* CodeStubAssembler::name##Constant() { \ |
64 return LoadRoot(Heap::k##rootName##RootIndex); \ | 75 return LoadRoot(Heap::k##rootName##RootIndex); \ |
65 } | 76 } |
66 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); | 77 HEAP_CONSTANT_LIST(HEAP_CONSTANT_ACCESSOR); |
67 #undef HEAP_CONSTANT_ACCESSOR | 78 #undef HEAP_CONSTANT_ACCESSOR |
68 | 79 |
69 #define HEAP_CONSTANT_TEST(rootName, name) \ | 80 #define HEAP_CONSTANT_TEST(rootName, name) \ |
(...skipping 1553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1623 Bind(&done); | 1634 Bind(&done); |
1624 | 1635 |
1625 return result.value(); | 1636 return result.value(); |
1626 } | 1637 } |
1627 | 1638 |
1628 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, | 1639 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, |
1629 Node* index, Node* input) { | 1640 Node* index, Node* input) { |
1630 Node* const max_length = | 1641 Node* const max_length = |
1631 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); | 1642 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); |
1632 CSA_ASSERT(SmiLessThanOrEqual(length, max_length)); | 1643 CSA_ASSERT(SmiLessThanOrEqual(length, max_length)); |
| 1644 USE(max_length); |
1633 | 1645 |
1634 // Allocate the JSRegExpResult. | 1646 // Allocate the JSRegExpResult. |
1635 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove | 1647 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove |
1636 // unneeded store of elements. | 1648 // unneeded store of elements. |
1637 Node* const result = Allocate(JSRegExpResult::kSize); | 1649 Node* const result = Allocate(JSRegExpResult::kSize); |
1638 | 1650 |
1639 // TODO(jgruber): Store map as Heap constant? | 1651 // TODO(jgruber): Store map as Heap constant? |
1640 Node* const native_context = LoadNativeContext(context); | 1652 Node* const native_context = LoadNativeContext(context); |
1641 Node* const map = | 1653 Node* const map = |
1642 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); | 1654 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); |
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 value); | 2648 value); |
2637 var_value_map.Bind(UndefinedConstant()); | 2649 var_value_map.Bind(UndefinedConstant()); |
2638 Goto(&out); // Never reached. | 2650 Goto(&out); // Never reached. |
2639 | 2651 |
2640 Bind(&out); | 2652 Bind(&out); |
2641 return var_value_map.value(); | 2653 return var_value_map.value(); |
2642 } | 2654 } |
2643 | 2655 |
2644 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { | 2656 Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { |
2645 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); | 2657 Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); |
2646 Node* bit_field = LoadMapBitField(map); | |
2647 uint32_t mask = | 2658 uint32_t mask = |
2648 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; | 2659 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
| 2660 USE(mask); |
2649 // Interceptors or access checks imply special receiver. | 2661 // Interceptors or access checks imply special receiver. |
2650 CSA_ASSERT( | 2662 CSA_ASSERT(Select(IsSetWord32(LoadMapBitField(map), mask), is_special, |
2651 Select(IsSetWord32(bit_field, mask), is_special, Int32Constant(1))); | 2663 Int32Constant(1), MachineRepresentation::kWord32)); |
2652 return is_special; | 2664 return is_special; |
2653 } | 2665 } |
2654 | 2666 |
2655 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { | 2667 Node* CodeStubAssembler::IsDictionaryMap(Node* map) { |
2656 CSA_SLOW_ASSERT(IsMap(map)); | 2668 CSA_SLOW_ASSERT(IsMap(map)); |
2657 Node* bit_field3 = LoadMapBitField3(map); | 2669 Node* bit_field3 = LoadMapBitField3(map); |
2658 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), | 2670 return Word32NotEqual(IsSetWord32<Map::DictionaryMap>(bit_field3), |
2659 Int32Constant(0)); | 2671 Int32Constant(0)); |
2660 } | 2672 } |
2661 | 2673 |
(...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4208 Label* if_bailout) { | 4220 Label* if_bailout) { |
4209 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); | 4221 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); |
4210 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 4222 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
4211 | 4223 |
4212 Label if_objectisspecial(this); | 4224 Label if_objectisspecial(this); |
4213 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 4225 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
4214 GotoIf(Int32LessThanOrEqual(instance_type, | 4226 GotoIf(Int32LessThanOrEqual(instance_type, |
4215 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | 4227 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), |
4216 &if_objectisspecial); | 4228 &if_objectisspecial); |
4217 | 4229 |
4218 Node* bit_field = LoadMapBitField(map); | 4230 uint32_t mask = |
4219 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | | 4231 1 << Map::kHasNamedInterceptor | 1 << Map::kIsAccessCheckNeeded; |
4220 1 << Map::kIsAccessCheckNeeded); | 4232 CSA_ASSERT(Word32BinaryNot(IsSetWord32(LoadMapBitField(map), mask))); |
4221 CSA_ASSERT(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); | 4233 USE(mask); |
4222 | 4234 |
4223 Node* bit_field3 = LoadMapBitField3(map); | 4235 Node* bit_field3 = LoadMapBitField3(map); |
4224 Label if_isfastmap(this), if_isslowmap(this); | 4236 Label if_isfastmap(this), if_isslowmap(this); |
4225 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, | 4237 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap, |
4226 &if_isfastmap); | 4238 &if_isfastmap); |
4227 Bind(&if_isfastmap); | 4239 Bind(&if_isfastmap); |
4228 { | 4240 { |
4229 Comment("DescriptorArrayLookup"); | 4241 Comment("DescriptorArrayLookup"); |
4230 Node* nof = | 4242 Node* nof = |
4231 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3); | 4243 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3); |
(...skipping 4608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8840 } | 8852 } |
8841 | 8853 |
8842 void CodeStubArguments::PopAndReturn(compiler::Node* value) { | 8854 void CodeStubArguments::PopAndReturn(compiler::Node* value) { |
8843 assembler_->PopAndReturn( | 8855 assembler_->PopAndReturn( |
8844 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), | 8856 assembler_->IntPtrAddFoldConstants(argc_, assembler_->IntPtrConstant(1)), |
8845 value); | 8857 value); |
8846 } | 8858 } |
8847 | 8859 |
8848 } // namespace internal | 8860 } // namespace internal |
8849 } // namespace v8 | 8861 } // namespace v8 |
OLD | NEW |