| 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 |