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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 | 25 |
26 | 26 |
27 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler, | 27 void DeoptimizationStub::GenerateCode(FlowGraphCompiler* compiler, |
28 intptr_t stub_ix) { | 28 intptr_t stub_ix) { |
29 Assembler* assem = compiler->assembler(); | 29 Assembler* assem = compiler->assembler(); |
30 #define __ assem-> | 30 #define __ assem-> |
31 __ Comment("Deopt stub for id %d", deopt_id_); | 31 __ Comment("Deopt stub for id %d", deopt_id_); |
32 __ Bind(entry_label()); | 32 __ Bind(entry_label()); |
33 | 33 |
34 if (deoptimization_env_ == NULL) { | 34 if (deoptimization_env_ == NULL) { |
35 // TODO(srdjan): Deprecate once non-SSA optimizing compiler is removed. | |
35 for (intptr_t i = 0; i < registers_.length(); i++) { | 36 for (intptr_t i = 0; i < registers_.length(); i++) { |
36 if (registers_[i] != kNoRegister) { | 37 if (registers_[i] != kNoRegister) { |
37 __ pushq(registers_[i]); | 38 __ pushq(registers_[i]); |
38 } | 39 } |
39 } | 40 } |
40 } else { | |
41 // We have a deoptimization environment, we have to tear down the | |
42 // optimized frame and recreate a non-optimized one. | |
43 const intptr_t fixed_parameter_count = | |
44 deoptimization_env_->fixed_parameter_count(); | |
45 | |
46 // 1. Set the stack pointer to the top of the non-optimized frame. | |
47 const GrowableArray<Value*>& values = deoptimization_env_->values(); | |
48 const intptr_t local_slot_count = values.length() - fixed_parameter_count; | |
49 const intptr_t top_offset = | |
50 ParsedFunction::kFirstLocalSlotIndex - (local_slot_count - 1); | |
51 __ leaq(RSP, Address(RBP, top_offset * kWordSize)); | |
52 | |
53 // 2. Build and emit a parallel move representing the frame translation. | |
54 ParallelMoveInstr* move = new ParallelMoveInstr(); | |
55 for (intptr_t i = 0; i < values.length(); i++) { | |
56 Location destination = Location::StackSlot(i - fixed_parameter_count); | |
57 Location source = deoptimization_env_->LocationAt(i); | |
58 if (source.IsInvalid()) { | |
59 ASSERT(values[i]->IsConstant()); | |
60 source = Location::Constant(values[i]->AsConstant()->value()); | |
61 } | |
62 move->AddMove(destination, source); | |
63 } | |
64 compiler->parallel_move_resolver()->EmitNativeCode(move); | |
65 } | 41 } |
66 | |
67 if (compiler->IsLeaf()) { | 42 if (compiler->IsLeaf()) { |
68 __ Comment("Leaf method, lazy PC marker setup"); | 43 __ Comment("Leaf method, lazy PC marker setup"); |
44 // TODO(srdjan): Can we use TMP instead of RAX? We must guarantee that | |
45 // TMP is never part od deoptimization environment. | |
siva
2012/08/09 21:38:19
od -> of
srdjan
2012/08/09 23:28:30
Done.
| |
46 __ pushq(RAX); // Preserve RAX. | |
69 Label L; | 47 Label L; |
70 __ call(&L); | 48 __ call(&L); |
71 const intptr_t offset = assem->CodeSize(); | 49 const intptr_t offset = assem->CodeSize(); |
72 __ Bind(&L); | 50 __ Bind(&L); |
73 __ popq(RAX); | 51 __ popq(RAX); |
74 __ subq(RAX, | 52 __ subq(RAX, |
75 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint)); | 53 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint)); |
76 __ movq(Address(RBP, -kWordSize), RAX); | 54 __ movq(Address(RBP, -kWordSize), RAX); |
55 __ popq(RAX); // Restore RAX. | |
77 } | 56 } |
78 __ call(&StubCode::DeoptimizeLabel()); | 57 __ call(&StubCode::DeoptimizeLabel()); |
79 const intptr_t deopt_info_index = stub_ix; | 58 const intptr_t deopt_info_index = stub_ix; |
80 compiler->pc_descriptors_list()-> AddDeoptInfo( | 59 compiler->pc_descriptors_list()->AddDeoptInfo( |
81 compiler->assembler()->CodeSize(), | 60 compiler->assembler()->CodeSize(), |
82 deopt_id_, | 61 deopt_id_, |
83 reason_, | 62 reason_, |
84 deopt_info_index); | 63 deopt_info_index); |
85 __ int3(); | 64 __ int3(); |
86 #undef __ | 65 #undef __ |
87 } | 66 } |
88 | 67 |
89 | 68 |
90 #define __ assembler()-> | 69 #define __ assembler()-> |
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1214 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1193 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
1215 __ Exchange(mem1, mem2); | 1194 __ Exchange(mem1, mem2); |
1216 } | 1195 } |
1217 | 1196 |
1218 | 1197 |
1219 #undef __ | 1198 #undef __ |
1220 | 1199 |
1221 } // namespace dart | 1200 } // namespace dart |
1222 | 1201 |
1223 #endif // defined TARGET_ARCH_X64 | 1202 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |