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