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 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 } else { | 40 } else { |
41 // We have a deoptimization environment, we have to tear down the | 41 // We have a deoptimization environment, we have to tear down the |
42 // optimized frame and recreate a non-optimized one. | 42 // optimized frame and recreate a non-optimized one. |
43 const intptr_t fixed_parameter_count = | 43 const intptr_t fixed_parameter_count = |
44 deoptimization_env_->fixed_parameter_count(); | 44 deoptimization_env_->fixed_parameter_count(); |
45 | 45 |
46 const GrowableArray<Value*>& values = deoptimization_env_->values(); | 46 const GrowableArray<Value*>& values = deoptimization_env_->values(); |
47 | 47 |
48 // 1. Build a parallel move representing the frame translation. | 48 // 1. Build a parallel move representing the frame translation. |
| 49 intptr_t height = compiler->StackSize(); |
49 ParallelMoveInstr* move = new ParallelMoveInstr(); | 50 ParallelMoveInstr* move = new ParallelMoveInstr(); |
50 for (intptr_t i = 0; i < values.length(); i++) { | 51 for (intptr_t i = 0; i < values.length(); i++) { |
51 Location destination = Location::StackSlot(i - fixed_parameter_count); | 52 Location destination = Location::StackSlot(i - fixed_parameter_count); |
52 Location source = deoptimization_env_->LocationAt(i); | 53 Location source = deoptimization_env_->LocationAt(i); |
53 if (source.IsInvalid()) { | 54 if (source.IsInvalid()) { |
54 ASSERT(values[i]->IsConstant()); | 55 Value* value = values[i]; |
55 source = Location::Constant(values[i]->AsConstant()->value()); | 56 if (value->IsConstant()) { |
| 57 source = Location::Constant(value->AsConstant()->value()); |
| 58 } else { |
| 59 ASSERT(value->IsUse() && |
| 60 value->AsUse()->definition()->IsPushArgument()); |
| 61 source = Location::StackSlot(height++); |
| 62 } |
56 } | 63 } |
57 move->AddMove(destination, source); | 64 move->AddMove(destination, source); |
58 } | 65 } |
59 | 66 |
60 | 67 |
61 const intptr_t local_slot_count = values.length() - fixed_parameter_count; | 68 const intptr_t local_slot_count = values.length() - fixed_parameter_count; |
62 const intptr_t top_offset = | 69 const intptr_t top_offset = |
63 ParsedFunction::kFirstLocalSlotIndex - (local_slot_count - 1); | 70 ParsedFunction::kFirstLocalSlotIndex - (local_slot_count - 1); |
64 | 71 |
| 72 #if defined(DEBUG) |
| 73 intptr_t optimized_top_offset = |
| 74 (ParsedFunction::kFirstLocalSlotIndex - height) * kWordSize; |
| 75 Label height_ok; |
| 76 __ pushl(EAX); |
| 77 __ leal(EAX, Address(EBP, optimized_top_offset)); |
| 78 __ cmpl(EAX, ESP); |
| 79 // Some instructions might push temporary values above an optimized frame. |
| 80 __ j(ABOVE_EQUAL, &height_ok); |
| 81 __ Stop("Optimized frame height mismatch"); |
| 82 __ Bind(&height_ok); |
| 83 __ popl(EAX); |
| 84 #endif |
| 85 |
65 // ParallelMoveResolver will use push and pop to allocate internally a | 86 // ParallelMoveResolver will use push and pop to allocate internally a |
66 // scratch register for memory to memory moves. This means we have to | 87 // scratch register for memory to memory moves. This means we have to |
67 // ensure that these stack manipulations will not interfere with actual | 88 // ensure that these stack manipulations will not interfere with actual |
68 // moves. If number of local slots exceed number of spill slots we need | 89 // moves. If number of local slots exceed number of spill slots we need |
69 // to expand reserved stack area before resolving parallel move. Otherwise | 90 // to expand reserved stack area before resolving parallel move. Otherwise |
70 // we need to shrink stack area after resolving parallel move. This | 91 // we need to shrink stack area after resolving parallel move. This |
71 // guarantees that all moves happen below stack pointer and will not | 92 // guarantees that all moves happen below stack pointer and will not |
72 // interfere with additional push/pops. | 93 // interfere with additional push/pops. |
73 const intptr_t spill_slot_count = compiler->StackSize(); | 94 if (local_slot_count >= height) { |
74 | |
75 if (local_slot_count > spill_slot_count) { | |
76 // Expand reserved stack area. | 95 // Expand reserved stack area. |
77 __ leal(ESP, Address(EBP, top_offset * kWordSize)); | 96 __ leal(ESP, Address(EBP, top_offset * kWordSize)); |
78 } | 97 } |
79 | 98 |
80 compiler->parallel_move_resolver()->EmitNativeCode(move); | 99 compiler->parallel_move_resolver()->EmitNativeCode(move); |
81 | 100 |
82 if (local_slot_count < spill_slot_count) { | 101 if (local_slot_count < height) { |
83 // Shrink reserved stack area. | 102 // Shrink reserved stack area. |
84 __ leal(ESP, Address(EBP, top_offset * kWordSize)); | 103 __ leal(ESP, Address(EBP, top_offset * kWordSize)); |
85 } | 104 } |
86 } | 105 } |
87 | 106 |
88 if (compiler->IsLeaf()) { | 107 if (compiler->IsLeaf()) { |
89 Label L; | 108 Label L; |
90 __ call(&L); | 109 __ call(&L); |
91 const intptr_t offset = assem->CodeSize(); | 110 const intptr_t offset = assem->CodeSize(); |
92 __ Bind(&L); | 111 __ Bind(&L); |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 __ popl(ECX); | 1272 __ popl(ECX); |
1254 __ popl(EAX); | 1273 __ popl(EAX); |
1255 } | 1274 } |
1256 | 1275 |
1257 | 1276 |
1258 #undef __ | 1277 #undef __ |
1259 | 1278 |
1260 } // namespace dart | 1279 } // namespace dart |
1261 | 1280 |
1262 #endif // defined TARGET_ARCH_IA32 | 1281 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |