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