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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 old_saved_ic_data.IsNull() ? 0 : old_saved_ic_data.Length(); | 233 old_saved_ic_data.IsNull() ? 0 : old_saved_ic_data.Length(); |
234 for (intptr_t i = 1; i < saved_len; i++) { | 234 for (intptr_t i = 1; i < saved_len; i++) { |
235 ICData& ic_data = ICData::ZoneHandle(zone()); | 235 ICData& ic_data = ICData::ZoneHandle(zone()); |
236 ic_data ^= old_saved_ic_data.At(i); | 236 ic_data ^= old_saved_ic_data.At(i); |
237 (*deopt_id_to_ic_data_)[ic_data.deopt_id()] = &ic_data; | 237 (*deopt_id_to_ic_data_)[ic_data.deopt_id()] = &ic_data; |
238 } | 238 } |
239 } | 239 } |
240 ASSERT(assembler != NULL); | 240 ASSERT(assembler != NULL); |
241 ASSERT(!list_class_.IsNull()); | 241 ASSERT(!list_class_.IsNull()); |
242 | 242 |
243 code_source_map_builder_ = new (zone_) CodeSourceMapBuilder( | 243 bool stack_traces_only = !FLAG_profiler; |
244 caller_inline_id, inline_id_to_token_pos, inline_id_to_function); | 244 code_source_map_builder_ = new (zone_) |
| 245 CodeSourceMapBuilder(stack_traces_only, caller_inline_id, |
| 246 inline_id_to_token_pos, inline_id_to_function); |
245 } | 247 } |
246 | 248 |
247 | 249 |
248 bool FlowGraphCompiler::IsUnboxedField(const Field& field) { | 250 bool FlowGraphCompiler::IsUnboxedField(const Field& field) { |
249 bool valid_class = | 251 bool valid_class = |
250 (SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) || | 252 (SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) || |
251 (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) || | 253 (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) || |
252 (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)); | 254 (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)); |
253 return field.is_unboxing_candidate() && !field.is_final() && | 255 return field.is_unboxing_candidate() && !field.is_final() && |
254 !field.is_nullable() && valid_class; | 256 !field.is_nullable() && valid_class; |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 exception_handlers_list_->AddHandler(try_index, outer_try_index, pc_offset, | 676 exception_handlers_list_->AddHandler(try_index, outer_try_index, pc_offset, |
675 handler_types, needs_stacktrace); | 677 handler_types, needs_stacktrace); |
676 } | 678 } |
677 | 679 |
678 | 680 |
679 void FlowGraphCompiler::SetNeedsStackTrace(intptr_t try_index) { | 681 void FlowGraphCompiler::SetNeedsStackTrace(intptr_t try_index) { |
680 exception_handlers_list_->SetNeedsStackTrace(try_index); | 682 exception_handlers_list_->SetNeedsStackTrace(try_index); |
681 } | 683 } |
682 | 684 |
683 | 685 |
| 686 void FlowGraphCompiler::AddDescriptor(RawPcDescriptors::Kind kind, |
| 687 intptr_t pc_offset, |
| 688 intptr_t deopt_id, |
| 689 TokenPosition token_pos, |
| 690 intptr_t try_index) { |
| 691 code_source_map_builder_->NoteDescriptor(kind, pc_offset, token_pos); |
| 692 // When running with optimizations disabled, don't emit deopt-descriptors. |
| 693 if (!CanOptimize() && (kind == RawPcDescriptors::kDeopt)) return; |
| 694 pc_descriptors_list_->AddDescriptor(kind, pc_offset, deopt_id, token_pos, |
| 695 try_index); |
| 696 } |
| 697 |
| 698 |
684 // Uses current pc position and try-index. | 699 // Uses current pc position and try-index. |
685 void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind, | 700 void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind, |
686 intptr_t deopt_id, | 701 intptr_t deopt_id, |
687 TokenPosition token_pos) { | 702 TokenPosition token_pos) { |
688 // When running with optimizations disabled, don't emit deopt-descriptors. | 703 AddDescriptor(kind, assembler()->CodeSize(), deopt_id, token_pos, |
689 if (!CanOptimize() && (kind == RawPcDescriptors::kDeopt)) return; | 704 CurrentTryIndex()); |
690 pc_descriptors_list()->AddDescriptor(kind, assembler()->CodeSize(), deopt_id, | |
691 token_pos, CurrentTryIndex()); | |
692 } | 705 } |
693 | 706 |
694 | 707 |
695 void FlowGraphCompiler::AddStaticCallTarget(const Function& func) { | 708 void FlowGraphCompiler::AddStaticCallTarget(const Function& func) { |
696 ASSERT(func.IsZoneHandle()); | 709 ASSERT(func.IsZoneHandle()); |
697 static_calls_target_table_.Add( | 710 static_calls_target_table_.Add( |
698 new (zone()) StaticCallsStruct(assembler()->CodeSize(), &func, NULL)); | 711 new (zone()) StaticCallsStruct(assembler()->CodeSize(), &func, NULL)); |
699 } | 712 } |
700 | 713 |
701 | 714 |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 *static_calls_target_table_[i]->code); | 1033 *static_calls_target_table_[i]->code); |
1021 } | 1034 } |
1022 } | 1035 } |
1023 code.set_static_calls_target_table(targets); | 1036 code.set_static_calls_target_table(targets); |
1024 INC_STAT(Thread::Current(), total_code_size, | 1037 INC_STAT(Thread::Current(), total_code_size, |
1025 targets.Length() * sizeof(uword)); | 1038 targets.Length() * sizeof(uword)); |
1026 } | 1039 } |
1027 | 1040 |
1028 | 1041 |
1029 void FlowGraphCompiler::FinalizeCodeSourceMap(const Code& code) { | 1042 void FlowGraphCompiler::FinalizeCodeSourceMap(const Code& code) { |
1030 #ifdef PRODUCT | |
1031 // This data is only used by the profiler. | |
1032 #else | |
1033 if (FLAG_precompiled_mode) { | 1043 if (FLAG_precompiled_mode) { |
1034 // TODO(rmacnak): Include a filtered verion of this to produce stack traces | 1044 // TODO(rmacnak): Include a filtered verion of this to produce stack traces |
1035 // with inlined frames. | 1045 // with inlined frames. |
1036 return; | 1046 return; |
1037 } | 1047 } |
1038 | 1048 |
1039 const Array& inlined_id_array = | 1049 const Array& inlined_id_array = |
1040 Array::Handle(zone(), code_source_map_builder_->InliningIdToFunction()); | 1050 Array::Handle(zone(), code_source_map_builder_->InliningIdToFunction()); |
1041 INC_STAT(Thread::Current(), total_code_size, | 1051 INC_STAT(Thread::Current(), total_code_size, |
1042 inlined_id_array.Length() * sizeof(uword)); | 1052 inlined_id_array.Length() * sizeof(uword)); |
1043 code.set_inlined_id_to_function(inlined_id_array); | 1053 code.set_inlined_id_to_function(inlined_id_array); |
1044 | 1054 |
1045 const CodeSourceMap& map = | 1055 const CodeSourceMap& map = |
1046 CodeSourceMap::Handle(code_source_map_builder_->Finalize()); | 1056 CodeSourceMap::Handle(code_source_map_builder_->Finalize()); |
1047 INC_STAT(Thread::Current(), total_code_size, map.Length() * sizeof(uint8_t)); | 1057 INC_STAT(Thread::Current(), total_code_size, map.Length() * sizeof(uint8_t)); |
1048 code.set_code_source_map(map); | 1058 code.set_code_source_map(map); |
1049 #endif | |
1050 | 1059 |
1051 #if defined(DEBUG) | 1060 #if defined(DEBUG) |
1052 // Force simulation through the last pc offset. This checks we can decode | 1061 // Force simulation through the last pc offset. This checks we can decode |
1053 // the whole CodeSourceMap without hitting an unknown opcode, stack underflow, | 1062 // the whole CodeSourceMap without hitting an unknown opcode, stack underflow, |
1054 // etc. | 1063 // etc. |
1055 GrowableArray<const Function*> fs; | 1064 GrowableArray<const Function*> fs; |
1056 GrowableArray<TokenPosition> tokens; | 1065 GrowableArray<TokenPosition> tokens; |
1057 code.GetInlinedFunctionsAt(code.Size() - 1, &fs, &tokens); | 1066 code.GetInlinedFunctionsAtInstruction(code.Size() - 1, &fs, &tokens); |
1058 #endif | 1067 #endif |
1059 } | 1068 } |
1060 | 1069 |
1061 | 1070 |
1062 // Returns 'true' if regular code generation should be skipped. | 1071 // Returns 'true' if regular code generation should be skipped. |
1063 bool FlowGraphCompiler::TryIntrinsify() { | 1072 bool FlowGraphCompiler::TryIntrinsify() { |
1064 // Intrinsification skips arguments checks, therefore disable if in checked | 1073 // Intrinsification skips arguments checks, therefore disable if in checked |
1065 // mode. | 1074 // mode. |
1066 if (FLAG_intrinsify && !isolate()->type_checks()) { | 1075 if (FLAG_intrinsify && !isolate()->type_checks()) { |
1067 const Class& owner = Class::Handle(parsed_function().function().Owner()); | 1076 const Class& owner = Class::Handle(parsed_function().function().Owner()); |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 | 1859 |
1851 | 1860 |
1852 void FlowGraphCompiler::FrameStateClear() { | 1861 void FlowGraphCompiler::FrameStateClear() { |
1853 ASSERT(!is_optimizing()); | 1862 ASSERT(!is_optimizing()); |
1854 frame_state_.TruncateTo(0); | 1863 frame_state_.TruncateTo(0); |
1855 } | 1864 } |
1856 #endif // defined(DEBUG) && !defined(TARGET_ARCH_DBC) | 1865 #endif // defined(DEBUG) && !defined(TARGET_ARCH_DBC) |
1857 | 1866 |
1858 | 1867 |
1859 } // namespace dart | 1868 } // namespace dart |
OLD | NEW |