Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 static const intptr_t kArgCount = 0; |
|
zra
2016/12/19 19:15:18
static?
Vyacheslav Egorov (Google)
2016/12/19 21:55:19
Muscle memory
| |
| 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 Loading... | |
| 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 |
| OLD | NEW |