OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
6 | 6 |
7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
8 | 8 |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1018 } | 1018 } |
1019 } | 1019 } |
1020 code.set_static_calls_target_table(targets); | 1020 code.set_static_calls_target_table(targets); |
1021 INC_STAT(Thread::Current(), | 1021 INC_STAT(Thread::Current(), |
1022 total_code_size, | 1022 total_code_size, |
1023 targets.Length() * sizeof(uword)); | 1023 targets.Length() * sizeof(uword)); |
1024 } | 1024 } |
1025 | 1025 |
1026 | 1026 |
1027 // Returns 'true' if code generation for this function is complete, i.e., | 1027 // Returns 'true' if code generation for this function is complete, i.e., |
1028 // no fall-through to regular code is needed. | 1028 // no fall-through to regular code is needed and regular code contains no |
1029 void FlowGraphCompiler::TryIntrinsify() { | 1029 // deopt ids. |
srdjan
2015/10/05 17:38:25
Please adjust comment even more
rmacnak
2015/10/05 23:43:22
Returns 'true' if regular code generation should b
| |
1030 bool FlowGraphCompiler::TryIntrinsify() { | |
1030 // Intrinsification skips arguments checks, therefore disable if in checked | 1031 // Intrinsification skips arguments checks, therefore disable if in checked |
1031 // mode. | 1032 // mode. |
1032 if (FLAG_intrinsify && !isolate()->flags().type_checks()) { | 1033 if (FLAG_intrinsify && !isolate()->flags().type_checks()) { |
1033 if (parsed_function().function().kind() == RawFunction::kImplicitGetter) { | 1034 if (parsed_function().function().kind() == RawFunction::kImplicitGetter) { |
1034 // An implicit getter must have a specific AST structure. | 1035 // An implicit getter must have a specific AST structure. |
1035 const SequenceNode& sequence_node = *parsed_function().node_sequence(); | 1036 const SequenceNode& sequence_node = *parsed_function().node_sequence(); |
1036 ASSERT(sequence_node.length() == 1); | 1037 ASSERT(sequence_node.length() == 1); |
1037 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); | 1038 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); |
1038 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); | 1039 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); |
1039 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); | 1040 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); |
1040 const LoadInstanceFieldNode& load_node = | 1041 const LoadInstanceFieldNode& load_node = |
1041 *return_node.value()->AsLoadInstanceFieldNode(); | 1042 *return_node.value()->AsLoadInstanceFieldNode(); |
1042 // Only intrinsify getter if the field cannot contain a mutable double. | 1043 // Only intrinsify getter if the field cannot contain a mutable double. |
1043 // Reading from a mutable double box requires allocating a fresh double. | 1044 // Reading from a mutable double box requires allocating a fresh double. |
1044 if (load_node.field().guarded_cid() == kDynamicCid) { | 1045 if (load_node.field().guarded_cid() == kDynamicCid) { |
1045 GenerateInlinedGetter(load_node.field().Offset()); | 1046 GenerateInlinedGetter(load_node.field().Offset()); |
1047 return true; | |
1046 } | 1048 } |
1047 return; | 1049 return false; |
1048 } | 1050 } |
1049 if (parsed_function().function().kind() == RawFunction::kImplicitSetter) { | 1051 if (parsed_function().function().kind() == RawFunction::kImplicitSetter) { |
1050 // An implicit setter must have a specific AST structure. | 1052 // An implicit setter must have a specific AST structure. |
1051 // Sequence node has one store node and one return NULL node. | 1053 // Sequence node has one store node and one return NULL node. |
1052 const SequenceNode& sequence_node = *parsed_function().node_sequence(); | 1054 const SequenceNode& sequence_node = *parsed_function().node_sequence(); |
1053 ASSERT(sequence_node.length() == 2); | 1055 ASSERT(sequence_node.length() == 2); |
1054 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); | 1056 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); |
1055 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); | 1057 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); |
1056 const StoreInstanceFieldNode& store_node = | 1058 const StoreInstanceFieldNode& store_node = |
1057 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); | 1059 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); |
1058 if (store_node.field().guarded_cid() == kDynamicCid) { | 1060 if (store_node.field().guarded_cid() == kDynamicCid) { |
1059 GenerateInlinedSetter(store_node.field().Offset()); | 1061 GenerateInlinedSetter(store_node.field().Offset()); |
1060 return; | 1062 return true; |
1061 } | 1063 } |
1062 } | 1064 } |
1063 } | 1065 } |
1064 | 1066 |
1065 EnterIntrinsicMode(); | 1067 EnterIntrinsicMode(); |
1066 | 1068 |
1067 Intrinsifier::Intrinsify(parsed_function(), this); | 1069 Intrinsifier::Intrinsify(parsed_function(), this); |
1068 | 1070 |
1069 ExitIntrinsicMode(); | 1071 ExitIntrinsicMode(); |
1070 // "Deoptimization" from intrinsic continues here. All deoptimization | 1072 // "Deoptimization" from intrinsic continues here. All deoptimization |
1071 // branches from intrinsic code redirect to here where the slow-path | 1073 // branches from intrinsic code redirect to here where the slow-path |
1072 // (normal function body) starts. | 1074 // (normal function body) starts. |
1073 // This means that there must not be any side-effects in intrinsic code | 1075 // This means that there must not be any side-effects in intrinsic code |
1074 // before any deoptimization point. | 1076 // before any deoptimization point. |
1075 ASSERT(!intrinsic_slow_path_label_.IsBound()); | 1077 ASSERT(!intrinsic_slow_path_label_.IsBound()); |
1076 assembler()->Bind(&intrinsic_slow_path_label_); | 1078 assembler()->Bind(&intrinsic_slow_path_label_); |
1079 return false; | |
1077 } | 1080 } |
1078 | 1081 |
1079 | 1082 |
1080 void FlowGraphCompiler::GenerateInstanceCall( | 1083 void FlowGraphCompiler::GenerateInstanceCall( |
1081 intptr_t deopt_id, | 1084 intptr_t deopt_id, |
1082 intptr_t token_pos, | 1085 intptr_t token_pos, |
1083 intptr_t argument_count, | 1086 intptr_t argument_count, |
1084 LocationSummary* locs, | 1087 LocationSummary* locs, |
1085 const ICData& ic_data) { | 1088 const ICData& ic_data) { |
1086 if (FLAG_always_megamorphic_calls) { | 1089 if (FLAG_always_megamorphic_calls) { |
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1835 | 1838 |
1836 | 1839 |
1837 void FlowGraphCompiler::FrameStateClear() { | 1840 void FlowGraphCompiler::FrameStateClear() { |
1838 ASSERT(!is_optimizing()); | 1841 ASSERT(!is_optimizing()); |
1839 frame_state_.TruncateTo(0); | 1842 frame_state_.TruncateTo(0); |
1840 } | 1843 } |
1841 #endif | 1844 #endif |
1842 | 1845 |
1843 | 1846 |
1844 } // namespace dart | 1847 } // namespace dart |
OLD | NEW |