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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 19 matching lines...) Expand all Loading... |
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 for (intptr_t i = 0; i < registers_.length(); i++) { | 35 for (intptr_t i = 0; i < registers_.length(); i++) { |
36 if (registers_[i] != kNoRegister) { | 36 if (registers_[i] != kNoRegister) { |
37 __ pushl(registers_[i]); | 37 __ pushl(registers_[i]); |
38 } | 38 } |
39 } | 39 } |
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 const GrowableArray<Value*>& values = deoptimization_env_->values(); | |
47 | |
48 // 1. Build a parallel move representing the frame translation. | |
49 ParallelMoveInstr* move = new ParallelMoveInstr(); | |
50 for (intptr_t i = 0; i < values.length(); i++) { | |
51 Location destination = Location::StackSlot(i - fixed_parameter_count); | |
52 Location source = deoptimization_env_->LocationAt(i); | |
53 if (source.IsInvalid()) { | |
54 ASSERT(values[i]->IsConstant()); | |
55 source = Location::Constant(values[i]->AsConstant()->value()); | |
56 } | |
57 move->AddMove(destination, source); | |
58 } | |
59 | |
60 | |
61 const intptr_t local_slot_count = values.length() - fixed_parameter_count; | |
62 const intptr_t top_offset = | |
63 ParsedFunction::kFirstLocalSlotIndex - (local_slot_count - 1); | |
64 | |
65 // ParallelMoveResolver will use push and pop to allocate internally a | |
66 // scratch register for memory to memory moves. This means we have to | |
67 // ensure that these stack manipulations will not interfere with actual | |
68 // moves. If number of local slots exceed number of spill slots we need | |
69 // to expand reserved stack area before resolving parallel move. Otherwise | |
70 // we need to shrink stack area after resolving parallel move. This | |
71 // guarantees that all moves happen below stack pointer and will not | |
72 // interfere with additional push/pops. | |
73 const intptr_t spill_slot_count = compiler->StackSize(); | |
74 | |
75 if (local_slot_count > spill_slot_count) { | |
76 // Expand reserved stack area. | |
77 __ leal(ESP, Address(EBP, top_offset * kWordSize)); | |
78 } | |
79 | |
80 compiler->parallel_move_resolver()->EmitNativeCode(move); | |
81 | |
82 if (local_slot_count < spill_slot_count) { | |
83 // Shrink reserved stack area. | |
84 __ leal(ESP, Address(EBP, top_offset * kWordSize)); | |
85 } | |
86 } | 40 } |
87 | 41 |
88 if (compiler->IsLeaf()) { | 42 if (compiler->IsLeaf()) { |
89 Label L; | 43 Label L; |
| 44 __ pushl(EAX); // Preserve EAX. |
90 __ call(&L); | 45 __ call(&L); |
91 const intptr_t offset = assem->CodeSize(); | 46 const intptr_t offset = assem->CodeSize(); |
92 __ Bind(&L); | 47 __ Bind(&L); |
93 __ popl(EAX); | 48 __ popl(EAX); |
94 __ subl(EAX, | 49 __ subl(EAX, |
95 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint)); | 50 Immediate(offset - AssemblerMacros::kOffsetOfSavedPCfromEntrypoint)); |
96 __ movl(Address(EBP, -kWordSize), EAX); | 51 __ movl(Address(EBP, -kWordSize), EAX); |
| 52 __ popl(EAX); |
97 } | 53 } |
98 __ call(&StubCode::DeoptimizeLabel()); | 54 __ call(&StubCode::DeoptimizeLabel()); |
99 const intptr_t deopt_info_index = stub_ix; | 55 const intptr_t deopt_info_index = stub_ix; |
100 compiler->pc_descriptors_list()-> AddDeoptInfo( | 56 compiler->pc_descriptors_list()-> AddDeoptInfo( |
101 compiler->assembler()->CodeSize(), | 57 compiler->assembler()->CodeSize(), |
102 deopt_id_, | 58 deopt_id_, |
103 reason_, | 59 reason_, |
104 deopt_info_index); | 60 deopt_info_index); |
105 #undef __ | 61 #undef __ |
106 } | 62 } |
(...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 __ popl(ECX); | 1208 __ popl(ECX); |
1253 __ popl(EAX); | 1209 __ popl(EAX); |
1254 } | 1210 } |
1255 | 1211 |
1256 | 1212 |
1257 #undef __ | 1213 #undef __ |
1258 | 1214 |
1259 } // namespace dart | 1215 } // namespace dart |
1260 | 1216 |
1261 #endif // defined TARGET_ARCH_IA32 | 1217 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |