| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/code_generator.h" | 5 #include "vm/code_generator.h" |
| 6 | 6 |
| 7 #include "vm/code_index_table.h" | 7 #include "vm/code_index_table.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 } | 858 } |
| 859 } | 859 } |
| 860 | 860 |
| 861 | 861 |
| 862 // The top Dart frame belongs to the optimized method that needs to be | 862 // The top Dart frame belongs to the optimized method that needs to be |
| 863 // deoptimized. The pc of the Dart frame points to the deoptimization point. | 863 // deoptimized. The pc of the Dart frame points to the deoptimization point. |
| 864 // Find the node id of the deoptimization point and find the continuation | 864 // Find the node id of the deoptimization point and find the continuation |
| 865 // pc in the unoptimized code. | 865 // pc in the unoptimized code. |
| 866 // Since both unoptimized and optimized code have the same layout, we need only | 866 // Since both unoptimized and optimized code have the same layout, we need only |
| 867 // to patch the pc of the Dart frame and to disable/enable appropriate code. | 867 // to patch the pc of the Dart frame and to disable/enable appropriate code. |
| 868 DEFINE_RUNTIME_ENTRY(Deoptimize, 0) { | 868 DEFINE_RUNTIME_ENTRY(Deoptimize, 1) { |
| 869 ASSERT(arguments.Count() == kDeoptimizeRuntimeEntry.argument_count()); | 869 ASSERT(arguments.Count() == kDeoptimizeRuntimeEntry.argument_count()); |
| 870 const Smi& deoptimization_reason_id = Smi::CheckedHandle(arguments.At(0)); |
| 870 DartFrameIterator iterator; | 871 DartFrameIterator iterator; |
| 871 DartFrame* caller_frame = iterator.NextFrame(); | 872 DartFrame* caller_frame = iterator.NextFrame(); |
| 872 ASSERT(caller_frame != NULL); | 873 ASSERT(caller_frame != NULL); |
| 873 CodeIndexTable* ci_table = isolate->code_index_table(); | 874 CodeIndexTable* ci_table = isolate->code_index_table(); |
| 874 const Code& optimized_code = | 875 const Code& optimized_code = |
| 875 Code::Handle(ci_table->LookupCode(caller_frame->pc())); | 876 Code::Handle(ci_table->LookupCode(caller_frame->pc())); |
| 876 const Function& function = Function::Handle(optimized_code.function()); | 877 const Function& function = Function::Handle(optimized_code.function()); |
| 877 ASSERT(!function.IsNull()); | 878 ASSERT(!function.IsNull()); |
| 878 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); | 879 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); |
| 879 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); | 880 ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized()); |
| 880 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); | 881 ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized()); |
| 881 const PcDescriptors& descriptors = | 882 const PcDescriptors& descriptors = |
| 882 PcDescriptors::Handle(optimized_code.pc_descriptors()); | 883 PcDescriptors::Handle(optimized_code.pc_descriptors()); |
| 883 ASSERT(!descriptors.IsNull()); | 884 ASSERT(!descriptors.IsNull()); |
| 884 // Locate node id at deoptimization point inside optimized code. | 885 // Locate node id at deoptimization point inside optimized code. |
| 885 intptr_t deopt_node_id = AstNode::kNoId; | 886 intptr_t deopt_node_id = AstNode::kNoId; |
| 887 intptr_t deopt_token_index = 0; |
| 886 for (int i = 0; i < descriptors.Length(); i++) { | 888 for (int i = 0; i < descriptors.Length(); i++) { |
| 887 if (static_cast<uword>(descriptors.PC(i)) == caller_frame->pc()) { | 889 if (static_cast<uword>(descriptors.PC(i)) == caller_frame->pc()) { |
| 888 deopt_node_id = descriptors.NodeId(i); | 890 deopt_node_id = descriptors.NodeId(i); |
| 891 deopt_token_index = descriptors.TokenIndex(i); |
| 889 break; | 892 break; |
| 890 } | 893 } |
| 891 } | 894 } |
| 892 ASSERT(deopt_node_id != AstNode::kNoId); | 895 ASSERT(deopt_node_id != AstNode::kNoId); |
| 893 uword continue_at_pc = | 896 uword continue_at_pc = |
| 894 unoptimized_code.GetDeoptPcAtNodeId(deopt_node_id); | 897 unoptimized_code.GetDeoptPcAtNodeId(deopt_node_id); |
| 895 ASSERT(continue_at_pc != 0); | 898 ASSERT(continue_at_pc != 0); |
| 896 if (FLAG_trace_deopt) { | 899 if (FLAG_trace_deopt) { |
| 897 OS::Print("Deoptimizing at pc 0x%x id %d '%s' -> continue at 0x%x \n", | 900 OS::Print("Deoptimizing (reason %d) at pc 0x%x id %d '%s' " |
| 898 caller_frame->pc(), deopt_node_id, function.ToFullyQualifiedCString(), | 901 "-> continue at 0x%x \n", |
| 902 deoptimization_reason_id.Value(), |
| 903 caller_frame->pc(), |
| 904 deopt_node_id, |
| 905 function.ToFullyQualifiedCString(), |
| 899 continue_at_pc); | 906 continue_at_pc); |
| 907 const Class& cls = Class::Handle(function.owner()); |
| 908 const Script& script = Script::Handle(cls.script()); |
| 909 intptr_t line, column; |
| 910 script.GetTokenLocation(deopt_token_index, &line, &column); |
| 911 OS::Print(" Line: %d Column: %d ", line, column); |
| 912 OS::Print(">> %s\n", String::Handle(script.GetLine(line)).ToCString()); |
| 900 } | 913 } |
| 901 caller_frame->set_pc(continue_at_pc); | 914 caller_frame->set_pc(continue_at_pc); |
| 902 // Clear invocation counter so that the function gets optimized after | 915 // Clear invocation counter so that the function gets optimized after |
| 903 // types/classes have been collected. | 916 // types/classes have been collected. |
| 904 function.set_invocation_counter(0); | 917 function.set_invocation_counter(0); |
| 905 function.set_deoptimization_counter(function.deoptimization_counter() + 1); | 918 function.set_deoptimization_counter(function.deoptimization_counter() + 1); |
| 906 | 919 |
| 907 // We have to skip the following otherwise the compiler will complain | 920 // We have to skip the following otherwise the compiler will complain |
| 908 // when it attempts to install unoptimized code into a function that | 921 // when it attempts to install unoptimized code into a function that |
| 909 // was already deoptimized. | 922 // was already deoptimized. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 } | 1007 } |
| 995 } | 1008 } |
| 996 } | 1009 } |
| 997 // The cache is null terminated, therefore the loop above should never | 1010 // The cache is null terminated, therefore the loop above should never |
| 998 // terminate by itself. | 1011 // terminate by itself. |
| 999 UNREACHABLE(); | 1012 UNREACHABLE(); |
| 1000 return Code::null(); | 1013 return Code::null(); |
| 1001 } | 1014 } |
| 1002 | 1015 |
| 1003 } // namespace dart | 1016 } // namespace dart |
| OLD | NEW |