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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 } else if (instr->MayThrow() && | 442 } else if (instr->MayThrow() && |
443 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { | 443 (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) { |
444 // Optimized try-block: Sync locals to fixed stack locations. | 444 // Optimized try-block: Sync locals to fixed stack locations. |
445 EmitTrySync(instr, CurrentTryIndex()); | 445 EmitTrySync(instr, CurrentTryIndex()); |
446 } | 446 } |
447 } | 447 } |
448 | 448 |
449 | 449 |
450 | 450 |
451 void FlowGraphCompiler::EmitSourceLine(Instruction* instr) { | 451 void FlowGraphCompiler::EmitSourceLine(Instruction* instr) { |
452 if ((instr->token_pos() < 0) || (instr->env() == NULL)) { | 452 if (!instr->token_pos().IsReal() || (instr->env() == NULL)) { |
453 return; | 453 return; |
454 } | 454 } |
455 const Script& script = | 455 const Script& script = |
456 Script::Handle(zone(), instr->env()->function().script()); | 456 Script::Handle(zone(), instr->env()->function().script()); |
457 intptr_t line_nr; | 457 intptr_t line_nr; |
458 intptr_t column_nr; | 458 intptr_t column_nr; |
459 script.GetTokenLocation(instr->token_pos(), &line_nr, &column_nr); | 459 script.GetTokenLocation(instr->token_pos(), &line_nr, &column_nr); |
460 const String& line = String::Handle(zone(), script.GetLine(line_nr)); | 460 const String& line = String::Handle(zone(), script.GetLine(line_nr)); |
461 assembler()->Comment("Line %" Pd " in '%s':\n %s", | 461 assembler()->Comment("Line %" Pd " in '%s':\n %s", |
462 line_nr, | 462 line_nr, |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 | 757 |
758 | 758 |
759 void FlowGraphCompiler::SetNeedsStacktrace(intptr_t try_index) { | 759 void FlowGraphCompiler::SetNeedsStacktrace(intptr_t try_index) { |
760 exception_handlers_list_->SetNeedsStacktrace(try_index); | 760 exception_handlers_list_->SetNeedsStacktrace(try_index); |
761 } | 761 } |
762 | 762 |
763 | 763 |
764 // Uses current pc position and try-index. | 764 // Uses current pc position and try-index. |
765 void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind, | 765 void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind, |
766 intptr_t deopt_id, | 766 intptr_t deopt_id, |
767 intptr_t token_pos) { | 767 TokenDescriptor token_pos) { |
768 // When running with optimizations disabled, don't emit deopt-descriptors. | 768 // When running with optimizations disabled, don't emit deopt-descriptors. |
769 if (!CanOptimize() && (kind == RawPcDescriptors::kDeopt)) return; | 769 if (!CanOptimize() && (kind == RawPcDescriptors::kDeopt)) return; |
770 pc_descriptors_list()->AddDescriptor(kind, | 770 pc_descriptors_list()->AddDescriptor(kind, |
771 assembler()->CodeSize(), | 771 assembler()->CodeSize(), |
772 deopt_id, | 772 deopt_id, |
773 token_pos, | 773 token_pos, |
774 CurrentTryIndex()); | 774 CurrentTryIndex()); |
775 } | 775 } |
776 | 776 |
777 | 777 |
778 void FlowGraphCompiler::AddStaticCallTarget(const Function& func) { | 778 void FlowGraphCompiler::AddStaticCallTarget(const Function& func) { |
779 ASSERT(func.IsZoneHandle()); | 779 ASSERT(func.IsZoneHandle()); |
780 static_calls_target_table_.Add( | 780 static_calls_target_table_.Add( |
781 new(zone()) StaticCallsStruct(assembler()->CodeSize(), &func, NULL)); | 781 new(zone()) StaticCallsStruct(assembler()->CodeSize(), &func, NULL)); |
782 } | 782 } |
783 | 783 |
784 | 784 |
785 void FlowGraphCompiler::AddStubCallTarget(const Code& code) { | 785 void FlowGraphCompiler::AddStubCallTarget(const Code& code) { |
786 ASSERT(code.IsZoneHandle()); | 786 ASSERT(code.IsZoneHandle()); |
787 static_calls_target_table_.Add( | 787 static_calls_target_table_.Add( |
788 new(zone()) StaticCallsStruct(assembler()->CodeSize(), NULL, &code)); | 788 new(zone()) StaticCallsStruct(assembler()->CodeSize(), NULL, &code)); |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, | 792 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, |
793 intptr_t token_pos) { | 793 TokenDescriptor token_pos) { |
794 ASSERT(is_optimizing()); | 794 ASSERT(is_optimizing()); |
795 ASSERT(!intrinsic_mode()); | 795 ASSERT(!intrinsic_mode()); |
796 CompilerDeoptInfo* info = | 796 CompilerDeoptInfo* info = |
797 new(zone()) CompilerDeoptInfo(deopt_id, | 797 new(zone()) CompilerDeoptInfo(deopt_id, |
798 ICData::kDeoptAtCall, | 798 ICData::kDeoptAtCall, |
799 0, // No flags. | 799 0, // No flags. |
800 pending_deoptimization_env_); | 800 pending_deoptimization_env_); |
801 info->set_pc_offset(assembler()->CodeSize()); | 801 info->set_pc_offset(assembler()->CodeSize()); |
802 deopt_infos_.Add(info); | 802 deopt_infos_.Add(info); |
803 } | 803 } |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 if (parsed_function().node_sequence() == NULL) { | 1042 if (parsed_function().node_sequence() == NULL) { |
1043 // Eager local var descriptors computation for Irregexp function as it is | 1043 // Eager local var descriptors computation for Irregexp function as it is |
1044 // complicated to factor out. | 1044 // complicated to factor out. |
1045 // TODO(srdjan): Consider canonicalizing and reusing the local var | 1045 // TODO(srdjan): Consider canonicalizing and reusing the local var |
1046 // descriptor for IrregexpFunction. | 1046 // descriptor for IrregexpFunction. |
1047 ASSERT(flow_graph().IsIrregexpFunction()); | 1047 ASSERT(flow_graph().IsIrregexpFunction()); |
1048 var_descs = LocalVarDescriptors::New(1); | 1048 var_descs = LocalVarDescriptors::New(1); |
1049 RawLocalVarDescriptors::VarInfo info; | 1049 RawLocalVarDescriptors::VarInfo info; |
1050 info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext); | 1050 info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext); |
1051 info.scope_id = 0; | 1051 info.scope_id = 0; |
1052 info.begin_pos = 0; | 1052 info.begin_pos = TokenDescriptor::kMinSource; |
1053 info.end_pos = 0; | 1053 info.end_pos = TokenDescriptor::kMinSource; |
1054 info.set_index(parsed_function().current_context_var()->index()); | 1054 info.set_index(parsed_function().current_context_var()->index()); |
1055 var_descs.SetVar(0, Symbols::CurrentContextVar(), &info); | 1055 var_descs.SetVar(0, Symbols::CurrentContextVar(), &info); |
1056 } | 1056 } |
1057 code.set_var_descriptors(var_descs); | 1057 code.set_var_descriptors(var_descs); |
1058 } | 1058 } |
1059 | 1059 |
1060 | 1060 |
1061 void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) { | 1061 void FlowGraphCompiler::FinalizeStaticCallTargetsTable(const Code& code) { |
1062 ASSERT(code.static_calls_target_table() == Array::null()); | 1062 ASSERT(code.static_calls_target_table() == Array::null()); |
1063 const Array& targets = Array::Handle(zone(), Array::New( | 1063 const Array& targets = Array::Handle(zone(), Array::New( |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 // This means that there must not be any side-effects in intrinsic code | 1133 // This means that there must not be any side-effects in intrinsic code |
1134 // before any deoptimization point. | 1134 // before any deoptimization point. |
1135 ASSERT(!intrinsic_slow_path_label_.IsBound()); | 1135 ASSERT(!intrinsic_slow_path_label_.IsBound()); |
1136 assembler()->Bind(&intrinsic_slow_path_label_); | 1136 assembler()->Bind(&intrinsic_slow_path_label_); |
1137 return false; | 1137 return false; |
1138 } | 1138 } |
1139 | 1139 |
1140 | 1140 |
1141 void FlowGraphCompiler::GenerateInstanceCall( | 1141 void FlowGraphCompiler::GenerateInstanceCall( |
1142 intptr_t deopt_id, | 1142 intptr_t deopt_id, |
1143 intptr_t token_pos, | 1143 TokenDescriptor token_pos, |
1144 intptr_t argument_count, | 1144 intptr_t argument_count, |
1145 LocationSummary* locs, | 1145 LocationSummary* locs, |
1146 const ICData& ic_data_in) { | 1146 const ICData& ic_data_in) { |
1147 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); | 1147 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); |
1148 if (Compiler::always_optimize()) { | 1148 if (Compiler::always_optimize()) { |
1149 EmitSwitchableInstanceCall(ic_data, argument_count, | 1149 EmitSwitchableInstanceCall(ic_data, argument_count, |
1150 deopt_id, token_pos, locs); | 1150 deopt_id, token_pos, locs); |
1151 return; | 1151 return; |
1152 } | 1152 } |
1153 if (FLAG_always_megamorphic_calls) { | 1153 if (FLAG_always_megamorphic_calls) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 *StubCode::TwoArgsCheckInlineCache_entry(), ic_data, argument_count, | 1199 *StubCode::TwoArgsCheckInlineCache_entry(), ic_data, argument_count, |
1200 deopt_id, token_pos, locs); | 1200 deopt_id, token_pos, locs); |
1201 break; | 1201 break; |
1202 default: | 1202 default: |
1203 UNIMPLEMENTED(); | 1203 UNIMPLEMENTED(); |
1204 } | 1204 } |
1205 } | 1205 } |
1206 | 1206 |
1207 | 1207 |
1208 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, | 1208 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id, |
1209 intptr_t token_pos, | 1209 TokenDescriptor token_pos, |
1210 const Function& function, | 1210 const Function& function, |
1211 intptr_t argument_count, | 1211 intptr_t argument_count, |
1212 const Array& argument_names, | 1212 const Array& argument_names, |
1213 LocationSummary* locs, | 1213 LocationSummary* locs, |
1214 const ICData& ic_data_in) { | 1214 const ICData& ic_data_in) { |
1215 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); | 1215 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); |
1216 const Array& arguments_descriptor = Array::ZoneHandle( | 1216 const Array& arguments_descriptor = Array::ZoneHandle( |
1217 ic_data.IsNull() ? ArgumentsDescriptor::New(argument_count, | 1217 ic_data.IsNull() ? ArgumentsDescriptor::New(argument_count, |
1218 argument_names) | 1218 argument_names) |
1219 : ic_data.arguments_descriptor()); | 1219 : ic_data.arguments_descriptor()); |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1778 } | 1778 } |
1779 return res.raw(); | 1779 return res.raw(); |
1780 } | 1780 } |
1781 | 1781 |
1782 | 1782 |
1783 void FlowGraphCompiler::EmitPolymorphicInstanceCall( | 1783 void FlowGraphCompiler::EmitPolymorphicInstanceCall( |
1784 const ICData& ic_data, | 1784 const ICData& ic_data, |
1785 intptr_t argument_count, | 1785 intptr_t argument_count, |
1786 const Array& argument_names, | 1786 const Array& argument_names, |
1787 intptr_t deopt_id, | 1787 intptr_t deopt_id, |
1788 intptr_t token_pos, | 1788 TokenDescriptor token_pos, |
1789 LocationSummary* locs) { | 1789 LocationSummary* locs) { |
1790 if (FLAG_polymorphic_with_deopt) { | 1790 if (FLAG_polymorphic_with_deopt) { |
1791 Label* deopt = AddDeoptStub(deopt_id, | 1791 Label* deopt = AddDeoptStub(deopt_id, |
1792 ICData::kDeoptPolymorphicInstanceCallTestFail); | 1792 ICData::kDeoptPolymorphicInstanceCallTestFail); |
1793 Label ok; | 1793 Label ok; |
1794 EmitTestAndCall(ic_data, argument_count, argument_names, | 1794 EmitTestAndCall(ic_data, argument_count, argument_names, |
1795 deopt, // No cid match. | 1795 deopt, // No cid match. |
1796 &ok, // Found cid. | 1796 &ok, // Found cid. |
1797 deopt_id, token_pos, locs); | 1797 deopt_id, token_pos, locs); |
1798 assembler()->Bind(&ok); | 1798 assembler()->Bind(&ok); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1883 | 1883 |
1884 | 1884 |
1885 void FlowGraphCompiler::FrameStateClear() { | 1885 void FlowGraphCompiler::FrameStateClear() { |
1886 ASSERT(!is_optimizing()); | 1886 ASSERT(!is_optimizing()); |
1887 frame_state_.TruncateTo(0); | 1887 frame_state_.TruncateTo(0); |
1888 } | 1888 } |
1889 #endif | 1889 #endif |
1890 | 1890 |
1891 | 1891 |
1892 } // namespace dart | 1892 } // namespace dart |
OLD | NEW |