Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: runtime/vm/flow_graph_compiler_dbc.cc

Issue 2587133002: VM: [DBC] Fix lazy deoptimization after calls that return no values. (Closed)
Patch Set: Add test Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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_DBC. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC.
6 #if defined(TARGET_ARCH_DBC) 6 #if defined(TARGET_ARCH_DBC)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 builder->AddCallerFp(slot_ix++); 111 builder->AddCallerFp(slot_ix++);
112 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++); 112 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
113 builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++); 113 builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
114 builder->AddConstant(Function::ZoneHandle(zone), slot_ix++); 114 builder->AddConstant(Function::ZoneHandle(zone), slot_ix++);
115 115
116 // Emit all values that are needed for materialization as a part of the 116 // Emit all values that are needed for materialization as a part of the
117 // expression stack for the bottom-most frame. This guarantees that GC 117 // expression stack for the bottom-most frame. This guarantees that GC
118 // will be able to find them during materialization. 118 // will be able to find them during materialization.
119 slot_ix = builder->EmitMaterializationArguments(slot_ix); 119 slot_ix = builder->EmitMaterializationArguments(slot_ix);
120 120
121 if (lazy_deopt_with_result_) {
122 ASSERT(reason() == ICData::kDeoptAtCall);
123 builder->AddCopy(NULL, Location::StackSlot(stack_height), slot_ix++);
124 }
125
121 // For the innermost environment, set outgoing arguments and the locals. 126 // For the innermost environment, set outgoing arguments and the locals.
122 for (intptr_t i = current->Length() - 1; 127 for (intptr_t i = current->Length() - 1;
123 i >= current->fixed_parameter_count(); i--) { 128 i >= current->fixed_parameter_count(); i--) {
124 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); 129 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
125 } 130 }
126 131
127 builder->AddCallerFp(slot_ix++); 132 builder->AddCallerFp(slot_ix++);
128 133
129 Environment* previous = current; 134 Environment* previous = current;
130 current = current->outer(); 135 current = current->outer();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); 177 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
173 } 178 }
174 179
175 return builder->CreateDeoptInfo(deopt_table); 180 return builder->CreateDeoptInfo(deopt_table);
176 } 181 }
177 182
178 183
179 void FlowGraphCompiler::RecordAfterCallHelper(TokenPosition token_pos, 184 void FlowGraphCompiler::RecordAfterCallHelper(TokenPosition token_pos,
180 intptr_t deopt_id, 185 intptr_t deopt_id,
181 intptr_t argument_count, 186 intptr_t argument_count,
187 CallResult result,
182 LocationSummary* locs) { 188 LocationSummary* locs) {
183 RecordSafepoint(locs); 189 RecordSafepoint(locs);
184 // Marks either the continuation point in unoptimized code or the 190 // Marks either the continuation point in unoptimized code or the
185 // deoptimization point in optimized code, after call. 191 // deoptimization point in optimized code, after call.
186 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); 192 const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
187 if (is_optimizing()) { 193 if (is_optimizing()) {
188 // Return/ReturnTOS instruction drops incoming arguments so 194 // Return/ReturnTOS instruction drops incoming arguments so
189 // we have to drop outgoing arguments from the innermost environment. 195 // we have to drop outgoing arguments from the innermost environment.
190 // On all other architectures caller drops outgoing arguments itself 196 // On all other architectures caller drops outgoing arguments itself
191 // hence the difference. 197 // hence the difference.
192 pending_deoptimization_env_->DropArguments(argument_count); 198 pending_deoptimization_env_->DropArguments(argument_count);
193 AddDeoptIndexAtCall(deopt_id_after); 199 CompilerDeoptInfo* info = AddDeoptIndexAtCall(deopt_id_after);
200 if (result == kHasResult) {
201 info->mark_lazy_deopt_with_result();
202 }
194 // This descriptor is needed for exception handling in optimized code. 203 // This descriptor is needed for exception handling in optimized code.
195 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id_after, token_pos); 204 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id_after, token_pos);
196 } else { 205 } else {
197 // Add deoptimization continuation point after the call and before the 206 // Add deoptimization continuation point after the call and before the
198 // arguments are removed. 207 // arguments are removed.
199 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 208 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
200 } 209 }
201 } 210 }
202 211
203 212
204 void FlowGraphCompiler::RecordAfterCall(Instruction* instr) { 213 void FlowGraphCompiler::RecordAfterCall(Instruction* instr, CallResult result) {
205 RecordAfterCallHelper(instr->token_pos(), instr->deopt_id(), 214 RecordAfterCallHelper(instr->token_pos(), instr->deopt_id(),
206 instr->ArgumentCount(), instr->locs()); 215 instr->ArgumentCount(), result, instr->locs());
207 } 216 }
208 217
209 218
210 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, 219 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
211 intptr_t stub_ix) { 220 intptr_t stub_ix) {
212 UNREACHABLE(); 221 UNREACHABLE();
213 } 222 }
214 223
215 224
216 #define __ assembler()-> 225 #define __ assembler()->
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 // Register allocator does not think that our first input (also used as 265 // Register allocator does not think that our first input (also used as
257 // output) needs to be kept alive across the call because that is how code 266 // output) needs to be kept alive across the call because that is how code
258 // is written on other platforms (where registers are always spilled across 267 // is written on other platforms (where registers are always spilled across
259 // the call): inputs are consumed by operation and output is produced so 268 // the call): inputs are consumed by operation and output is produced so
260 // neither are alive at the safepoint. 269 // neither are alive at the safepoint.
261 // We have to mark the slot alive manually to ensure that GC 270 // We have to mark the slot alive manually to ensure that GC
262 // visits it. 271 // visits it.
263 locs->SetStackBit(locs->out(0).reg()); 272 locs->SetStackBit(locs->out(0).reg());
264 } 273 }
265 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); 274 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
266 RecordAfterCallHelper(token_pos, deopt_id, 0, locs); 275 const intptr_t kArgCount = 0;
276 RecordAfterCallHelper(token_pos, deopt_id, kArgCount,
277 FlowGraphCompiler::kHasResult, locs);
267 if (is_optimizing()) { 278 if (is_optimizing()) {
268 // Assert assignable keeps the instance on the stack as the result, 279 // Assert assignable keeps the instance on the stack as the result,
269 // all other arguments are popped. 280 // all other arguments are popped.
270 ASSERT(locs->out(0).reg() == locs->in(0).reg()); 281 ASSERT(locs->out(0).reg() == locs->in(0).reg());
271 __ Drop1(); 282 __ Drop1();
272 } 283 }
273 } 284 }
274 285
275 286
276 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { 287 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 566 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
556 UNIMPLEMENTED(); 567 UNIMPLEMENTED();
557 } 568 }
558 569
559 570
560 #undef __ 571 #undef __
561 572
562 } // namespace dart 573 } // namespace dart
563 574
564 #endif // defined TARGET_ARCH_DBC 575 #endif // defined TARGET_ARCH_DBC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698