OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 function->ReplaceCode(function->shared()->code()); | 140 function->ReplaceCode(function->shared()->code()); |
141 | 141 |
142 if (FLAG_trace_deopt) { | 142 if (FLAG_trace_deopt) { |
143 PrintF("[forced deoptimization: "); | 143 PrintF("[forced deoptimization: "); |
144 function->PrintName(); | 144 function->PrintName(); |
145 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); | 145 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
149 | 149 |
150 void Deoptimizer::PatchStackCheckAt(Address pc_after, | 150 void Deoptimizer::PatchStackCheckCodeAt(Address pc_after, |
151 Code* check_code, | 151 Code* check_code, |
152 Code* replacement_code) { | 152 Code* replacement_code) { |
153 Address call_target_address = pc_after - kPointerSize; | 153 Address call_target_address = pc_after - kPointerSize; |
154 ASSERT(check_code->entry() == | 154 ASSERT(check_code->entry() == |
155 Assembler::target_address_at(call_target_address)); | 155 Assembler::target_address_at(call_target_address)); |
156 // The stack check code matches the pattern: | 156 // The stack check code matches the pattern: |
157 // | 157 // |
158 // cmp esp, <limit> | 158 // cmp esp, <limit> |
159 // jae ok | 159 // jae ok |
160 // call <stack guard> | 160 // call <stack guard> |
161 // test eax, <loop nesting depth> | 161 // test eax, <loop nesting depth> |
162 // ok: ... | 162 // ok: ... |
163 // | 163 // |
164 // We will patch away the branch so the code is: | 164 // We will patch away the branch so the code is: |
165 // | 165 // |
166 // cmp esp, <limit> ;; Not changed | 166 // cmp esp, <limit> ;; Not changed |
167 // nop | 167 // nop |
168 // nop | 168 // nop |
169 // call <on-stack replacment> | 169 // call <on-stack replacment> |
170 // test eax, <loop nesting depth> | 170 // test eax, <loop nesting depth> |
171 // ok: | 171 // ok: |
172 ASSERT(*(call_target_address - 3) == 0x73 && // jae | 172 ASSERT(*(call_target_address - 3) == 0x73 && // jae |
173 *(call_target_address - 2) == 0x07 && // offset | 173 *(call_target_address - 2) == 0x07 && // offset |
174 *(call_target_address - 1) == 0xe8); // call | 174 *(call_target_address - 1) == 0xe8); // call |
175 *(call_target_address - 3) = 0x90; // nop | 175 *(call_target_address - 3) = 0x90; // nop |
176 *(call_target_address - 2) = 0x90; // nop | 176 *(call_target_address - 2) = 0x90; // nop |
177 Assembler::set_target_address_at(call_target_address, | 177 Assembler::set_target_address_at(call_target_address, |
178 replacement_code->entry()); | 178 replacement_code->entry()); |
179 } | 179 } |
180 | 180 |
181 | 181 |
182 void Deoptimizer::RevertStackCheckCode(Code* unoptimized_code, | 182 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after, |
183 Code* check_code, | 183 Code* check_code, |
184 Code* replacement_code) { | 184 Code* replacement_code) { |
185 // Iterate the unoptimized code and revert all the patched stack checks. | 185 Address call_target_address = pc_after - kPointerSize; |
186 for (RelocIterator it(unoptimized_code, RelocInfo::kCodeTargetMask); | 186 ASSERT(replacement_code->entry() == |
187 !it.done(); | 187 Assembler::target_address_at(call_target_address)); |
188 it.next()) { | 188 // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to |
189 RelocInfo* rinfo = it.rinfo(); | 189 // restore the conditional branch. |
190 if (rinfo->target_address() == replacement_code->entry()) { | 190 ASSERT(*(call_target_address - 3) == 0x90 && // nop |
191 // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to | 191 *(call_target_address - 2) == 0x90 && // nop |
192 // restore the conditional branch. | 192 *(call_target_address - 1) == 0xe8); // call |
193 Address call_target_address = rinfo->pc(); | 193 *(call_target_address - 3) = 0x73; // jae |
194 ASSERT(*(call_target_address - 3) == 0x90 && // nop | 194 *(call_target_address - 2) = 0x07; // offset |
195 *(call_target_address - 2) == 0x90 && // nop | 195 Assembler::set_target_address_at(call_target_address, |
196 *(call_target_address - 1) == 0xe8); // call | 196 check_code->entry()); |
197 *(call_target_address - 3) = 0x73; // jae | |
198 *(call_target_address - 2) = 0x07; // offset | |
199 rinfo->set_target_address(check_code->entry()); | |
200 } | |
201 } | |
202 } | 197 } |
203 | 198 |
204 | 199 |
205 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) { | 200 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) { |
206 ByteArray* translations = data->TranslationByteArray(); | 201 ByteArray* translations = data->TranslationByteArray(); |
207 int length = data->DeoptCount(); | 202 int length = data->DeoptCount(); |
208 for (int i = 0; i < length; i++) { | 203 for (int i = 0; i < length; i++) { |
209 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) { | 204 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) { |
210 TranslationIterator it(translations, data->TranslationIndex(i)->value()); | 205 TranslationIterator it(translations, data->TranslationIndex(i)->value()); |
211 int value = it.Next(); | 206 int value = it.Next(); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 } | 664 } |
670 __ bind(&done); | 665 __ bind(&done); |
671 } | 666 } |
672 | 667 |
673 #undef __ | 668 #undef __ |
674 | 669 |
675 | 670 |
676 } } // namespace v8::internal | 671 } } // namespace v8::internal |
677 | 672 |
678 #endif // V8_TARGET_ARCH_IA32 | 673 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |