OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/debugger.h" | 10 #include "vm/debugger.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 } | 38 } |
39 | 39 |
40 | 40 |
41 void CompilerDeoptInfoWithStub::BuildReturnAddress(DeoptInfoBuilder* builder, | 41 void CompilerDeoptInfoWithStub::BuildReturnAddress(DeoptInfoBuilder* builder, |
42 const Function& function, | 42 const Function& function, |
43 intptr_t slot_ix) { | 43 intptr_t slot_ix) { |
44 builder->AddReturnAddressBefore(function, deopt_id(), slot_ix); | 44 builder->AddReturnAddressBefore(function, deopt_id(), slot_ix); |
45 } | 45 } |
46 | 46 |
47 | 47 |
| 48 // Assign locations to incoming arguments, i.e., values pushed above spill slots |
| 49 // with PushArgument. Recursively allocates from outermost to innermost |
| 50 // environment. |
| 51 void CompilerDeoptInfo::AllocateIncomingParametersRecursive( |
| 52 Environment* env, |
| 53 intptr_t* stack_height) { |
| 54 if (env == NULL) return; |
| 55 AllocateIncomingParametersRecursive(env->outer(), stack_height); |
| 56 for (Environment::ShallowIterator it(env); !it.Done(); it.Advance()) { |
| 57 if (it.CurrentLocation().IsInvalid()) { |
| 58 ASSERT(it.CurrentValue()->definition()->IsPushArgument()); |
| 59 it.SetCurrentLocation(Location::StackSlot((*stack_height)++)); |
| 60 } |
| 61 } |
| 62 } |
| 63 |
| 64 |
48 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { | 65 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler) { |
49 if (deoptimization_env_ == NULL) return DeoptInfo::null(); | 66 if (deoptimization_env_ == NULL) return DeoptInfo::null(); |
| 67 |
| 68 intptr_t stack_height = compiler->StackSize(); |
| 69 AllocateIncomingParametersRecursive(deoptimization_env_, &stack_height); |
| 70 |
50 const Function& function = compiler->parsed_function().function(); | 71 const Function& function = compiler->parsed_function().function(); |
51 // For functions with optional arguments, all incoming are copied to local | 72 // For functions with optional arguments, all incoming arguments are copied |
52 // area below FP, deoptimization environment does not track them. | 73 // to spill slots. The deoptimization environment does not track them. |
53 const intptr_t num_args = | 74 const intptr_t incoming_arg_count = |
54 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); | 75 function.HasOptionalParameters() ? 0 : function.num_fixed_parameters(); |
55 const intptr_t fixed_parameter_count = | 76 DeoptInfoBuilder builder(compiler->object_table(), incoming_arg_count); |
56 deoptimization_env_->fixed_parameter_count(); | |
57 DeoptInfoBuilder builder(compiler->object_table(), num_args); | |
58 | 77 |
59 intptr_t slot_ix = 0; | 78 intptr_t slot_ix = 0; |
60 BuildReturnAddress(&builder, function, slot_ix++); | 79 Environment* env = deoptimization_env_; |
| 80 while (env != NULL) { |
| 81 const Function& function = env->function(); |
| 82 const intptr_t fixed_parameter_count = env->fixed_parameter_count(); |
61 | 83 |
62 // Assign locations to values pushed above spill slots with PushArgument. | 84 if (slot_ix == 0) { |
63 intptr_t height = compiler->StackSize(); | 85 // For the innermost environment call the virtual return builder. |
64 for (intptr_t i = 0; i < deoptimization_env_->Length(); i++) { | 86 BuildReturnAddress(&builder, function, slot_ix++); |
65 if (deoptimization_env_->LocationAt(i).IsInvalid()) { | 87 } else { |
66 ASSERT(deoptimization_env_->ValueAt(i)->definition()->IsPushArgument()); | 88 // For any outer environment the deopt id is that of the call instruction |
67 *deoptimization_env_->LocationSlotAt(i) = Location::StackSlot(height++); | 89 // which is recorded in the outer environment. |
| 90 builder.AddReturnAddressAfter(function, env->deopt_id(), slot_ix++); |
68 } | 91 } |
69 } | |
70 | 92 |
71 for (intptr_t i = deoptimization_env_->Length() - 1; | 93 for (intptr_t i = env->Length() - 1; i >= fixed_parameter_count; i--) { |
72 i >= fixed_parameter_count; | 94 builder.AddCopy(env->LocationAt(i), *env->ValueAt(i), slot_ix++); |
73 i--) { | 95 } |
74 builder.AddCopy(deoptimization_env_->LocationAt(i), | |
75 *deoptimization_env_->ValueAt(i), | |
76 slot_ix++); | |
77 } | |
78 | 96 |
79 // PC marker, caller-fp, caller-pc. | 97 // PC marker and caller FP. |
80 builder.AddPcMarker(function, slot_ix++); | 98 builder.AddPcMarker(function, slot_ix++); |
81 builder.AddCallerFp(slot_ix++); | 99 builder.AddCallerFp(slot_ix++); |
82 builder.AddCallerPc(slot_ix++); | 100 |
83 // Incoming arguments. | 101 // On the outermost environment set caller PC and incoming arguments. |
84 for (intptr_t i = fixed_parameter_count - 1; i >= 0; i--) { | 102 if (env->outer() == NULL) { |
85 builder.AddCopy(deoptimization_env_->LocationAt(i), | 103 builder.AddCallerPc(slot_ix++); |
86 *deoptimization_env_->ValueAt(i), | 104 for (intptr_t i = fixed_parameter_count - 1; i >= 0; i--) { |
87 slot_ix++); | 105 builder.AddCopy(env->LocationAt(i), *env->ValueAt(i), slot_ix++); |
| 106 } |
| 107 } |
| 108 |
| 109 // Iterate on the outer environment. |
| 110 env = env->outer(); |
88 } | 111 } |
89 | 112 |
90 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); | 113 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder.CreateDeoptInfo()); |
91 return deopt_info.raw(); | 114 return deopt_info.raw(); |
92 } | 115 } |
93 | 116 |
94 | 117 |
95 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, | 118 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, |
96 const FlowGraph& flow_graph, | 119 const FlowGraph& flow_graph, |
97 bool is_optimizing, | 120 bool is_optimizing, |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( | 358 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( |
336 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); | 359 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); |
337 code.set_exception_handlers(handlers); | 360 code.set_exception_handlers(handlers); |
338 } | 361 } |
339 | 362 |
340 | 363 |
341 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { | 364 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) { |
342 ASSERT(pc_descriptors_list_ != NULL); | 365 ASSERT(pc_descriptors_list_ != NULL); |
343 const PcDescriptors& descriptors = PcDescriptors::Handle( | 366 const PcDescriptors& descriptors = PcDescriptors::Handle( |
344 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); | 367 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint())); |
345 descriptors.Verify(parsed_function_.function().is_optimizable()); | 368 if (!is_optimizing_) descriptors.Verify(parsed_function_.function()); |
346 code.set_pc_descriptors(descriptors); | 369 code.set_pc_descriptors(descriptors); |
347 } | 370 } |
348 | 371 |
349 | 372 |
350 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { | 373 void FlowGraphCompiler::FinalizeDeoptInfo(const Code& code) { |
351 const Array& array = | 374 const Array& array = |
352 Array::Handle(Array::New(deopt_infos_.length(), Heap::kOld)); | 375 Array::Handle(Array::New(deopt_infos_.length(), Heap::kOld)); |
353 DeoptInfo& info = DeoptInfo::Handle(); | 376 DeoptInfo& info = DeoptInfo::Handle(); |
354 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { | 377 for (intptr_t i = 0; i < deopt_infos_.length(); i++) { |
355 info = deopt_infos_[i]->CreateDeoptInfo(this); | 378 info = deopt_infos_[i]->CreateDeoptInfo(this); |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 case ABOVE: return unsigned_left > unsigned_right; | 876 case ABOVE: return unsigned_left > unsigned_right; |
854 case ABOVE_EQUAL: return unsigned_left >= unsigned_right; | 877 case ABOVE_EQUAL: return unsigned_left >= unsigned_right; |
855 default: | 878 default: |
856 UNIMPLEMENTED(); | 879 UNIMPLEMENTED(); |
857 return false; | 880 return false; |
858 } | 881 } |
859 } | 882 } |
860 | 883 |
861 | 884 |
862 } // namespace dart | 885 } // namespace dart |
OLD | NEW |