Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: src/x64/deoptimizer-x64.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/debug-x64.cc ('k') | src/x64/disasm-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 PrintF("[forced deoptimization: "); 197 PrintF("[forced deoptimization: ");
198 function->PrintName(); 198 function->PrintName();
199 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function)); 199 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
200 } 200 }
201 } 201 }
202 202
203 203
204 void Deoptimizer::PatchStackCheckCodeAt(Address pc_after, 204 void Deoptimizer::PatchStackCheckCodeAt(Address pc_after,
205 Code* check_code, 205 Code* check_code,
206 Code* replacement_code) { 206 Code* replacement_code) {
207 UNIMPLEMENTED(); 207 Address call_target_address = pc_after - kIntSize;
208 ASSERT(check_code->entry() ==
209 Assembler::target_address_at(call_target_address));
210 // The stack check code matches the pattern:
211 //
212 // cmp rsp, <limit>
213 // jae ok
214 // call <stack guard>
215 // test rax, <loop nesting depth>
216 // ok: ...
217 //
218 // We will patch away the branch so the code is:
219 //
220 // cmp rsp, <limit> ;; Not changed
221 // nop
222 // nop
223 // call <on-stack replacment>
224 // test rax, <loop nesting depth>
225 // ok:
226 //
227 ASSERT(*(call_target_address - 3) == 0x73 && // jae
228 *(call_target_address - 2) == 0x07 && // offset
229 *(call_target_address - 1) == 0xe8); // call
230 *(call_target_address - 3) = 0x90; // nop
231 *(call_target_address - 2) = 0x90; // nop
232 Assembler::set_target_address_at(call_target_address,
233 replacement_code->entry());
208 } 234 }
209 235
210 236
211 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after, 237 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after,
212 Code* check_code, 238 Code* check_code,
213 Code* replacement_code) { 239 Code* replacement_code) {
214 UNIMPLEMENTED(); 240 Address call_target_address = pc_after - kIntSize;
241 ASSERT(replacement_code->entry() ==
242 Assembler::target_address_at(call_target_address));
243 // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to
244 // restore the conditional branch.
245 ASSERT(*(call_target_address - 3) == 0x90 && // nop
246 *(call_target_address - 2) == 0x90 && // nop
247 *(call_target_address - 1) == 0xe8); // call
248 *(call_target_address - 3) = 0x73; // jae
249 *(call_target_address - 2) = 0x07; // offset
250 Assembler::set_target_address_at(call_target_address,
251 check_code->entry());
252 }
253
254
255 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) {
256 ByteArray* translations = data->TranslationByteArray();
257 int length = data->DeoptCount();
258 for (int i = 0; i < length; i++) {
259 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) {
260 TranslationIterator it(translations, data->TranslationIndex(i)->value());
261 int value = it.Next();
262 ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
263 // Read the number of frames.
264 value = it.Next();
265 if (value == 1) return i;
266 }
267 }
268 UNREACHABLE();
269 return -1;
215 } 270 }
216 271
217 272
218 void Deoptimizer::DoComputeOsrOutputFrame() { 273 void Deoptimizer::DoComputeOsrOutputFrame() {
219 UNIMPLEMENTED(); 274 DeoptimizationInputData* data = DeoptimizationInputData::cast(
275 optimized_code_->deoptimization_data());
276 unsigned ast_id = data->OsrAstId()->value();
277 // TODO(kasperl): This should not be the bailout_id_. It should be
278 // the ast id. Confusing.
279 ASSERT(bailout_id_ == ast_id);
280
281 int bailout_id = LookupBailoutId(data, ast_id);
282 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
283 ByteArray* translations = data->TranslationByteArray();
284
285 TranslationIterator iterator(translations, translation_index);
286 Translation::Opcode opcode =
287 static_cast<Translation::Opcode>(iterator.Next());
288 ASSERT(Translation::BEGIN == opcode);
289 USE(opcode);
290 int count = iterator.Next();
291 ASSERT(count == 1);
292 USE(count);
293
294 opcode = static_cast<Translation::Opcode>(iterator.Next());
295 USE(opcode);
296 ASSERT(Translation::FRAME == opcode);
297 unsigned node_id = iterator.Next();
298 USE(node_id);
299 ASSERT(node_id == ast_id);
300 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
301 USE(function);
302 ASSERT(function == function_);
303 unsigned height = iterator.Next();
304 unsigned height_in_bytes = height * kPointerSize;
305 USE(height_in_bytes);
306
307 unsigned fixed_size = ComputeFixedSize(function_);
308 unsigned input_frame_size = static_cast<unsigned>(input_->GetFrameSize());
309 ASSERT(fixed_size + height_in_bytes == input_frame_size);
310
311 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
312 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
313 unsigned outgoing_size = outgoing_height * kPointerSize;
314 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
315 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
316
317 if (FLAG_trace_osr) {
318 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
319 reinterpret_cast<intptr_t>(function_));
320 function_->PrintName();
321 PrintF(" => node=%u, frame=%d->%d]\n",
322 ast_id,
323 input_frame_size,
324 output_frame_size);
325 }
326
327 // There's only one output frame in the OSR case.
328 output_count_ = 1;
329 output_ = new FrameDescription*[1];
330 output_[0] = new(output_frame_size) FrameDescription(
331 output_frame_size, function_);
332
333 // Clear the incoming parameters in the optimized frame to avoid
334 // confusing the garbage collector.
335 unsigned output_offset = output_frame_size - kPointerSize;
336 int parameter_count = function_->shared()->formal_parameter_count() + 1;
337 for (int i = 0; i < parameter_count; ++i) {
338 output_[0]->SetFrameSlot(output_offset, 0);
339 output_offset -= kPointerSize;
340 }
341
342 // Translate the incoming parameters. This may overwrite some of the
343 // incoming argument slots we've just cleared.
344 int input_offset = input_frame_size - kPointerSize;
345 bool ok = true;
346 int limit = input_offset - (parameter_count * kPointerSize);
347 while (ok && input_offset > limit) {
348 ok = DoOsrTranslateCommand(&iterator, &input_offset);
349 }
350
351 // There are no translation commands for the caller's pc and fp, the
352 // context, and the function. Set them up explicitly.
353 for (int i = 0; ok && i < 4; i++) {
354 intptr_t input_value = input_->GetFrameSlot(input_offset);
355 if (FLAG_trace_osr) {
356 PrintF(" [esp + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d] (fixed part)\n",
357 output_offset,
358 input_value,
359 input_offset);
360 }
361 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
362 input_offset -= kPointerSize;
363 output_offset -= kPointerSize;
364 }
365
366 // Translate the rest of the frame.
367 while (ok && input_offset >= 0) {
368 ok = DoOsrTranslateCommand(&iterator, &input_offset);
369 }
370
371 // If translation of any command failed, continue using the input frame.
372 if (!ok) {
373 delete output_[0];
374 output_[0] = input_;
375 output_[0]->SetPc(reinterpret_cast<intptr_t>(from_));
376 } else {
377 // Setup the frame pointer and the context pointer.
378 output_[0]->SetRegister(rbp.code(), input_->GetRegister(rbp.code()));
379 output_[0]->SetRegister(rsi.code(), input_->GetRegister(rsi.code()));
380
381 unsigned pc_offset = data->OsrPcOffset()->value();
382 intptr_t pc = reinterpret_cast<intptr_t>(
383 optimized_code_->entry() + pc_offset);
384 output_[0]->SetPc(pc);
385 }
386 Code* continuation = Isolate::Current()->builtins()->builtin(
387 Builtins::NotifyOSR);
388 output_[0]->SetContinuation(
389 reinterpret_cast<intptr_t>(continuation->entry()));
390
391 if (FLAG_trace_osr) {
392 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
393 ok ? "finished" : "aborted",
394 reinterpret_cast<intptr_t>(function));
395 function->PrintName();
396 PrintF(" => pc=0x%0" V8PRIxPTR "]\n", output_[0]->GetPc());
397 }
220 } 398 }
221 399
222 400
223 void Deoptimizer::DoComputeFrame(TranslationIterator* iterator, 401 void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
224 int frame_index) { 402 int frame_index) {
225 // Read the ast node id, function, and frame height for this output frame. 403 // Read the ast node id, function, and frame height for this output frame.
226 Translation::Opcode opcode = 404 Translation::Opcode opcode =
227 static_cast<Translation::Opcode>(iterator->Next()); 405 static_cast<Translation::Opcode>(iterator->Next());
228 USE(opcode); 406 USE(opcode);
229 ASSERT(Translation::FRAME == opcode); 407 ASSERT(Translation::FRAME == opcode);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 intptr_t fp_value = top_address + output_offset; 493 intptr_t fp_value = top_address + output_offset;
316 ASSERT(!is_bottommost || input_->GetRegister(rbp.code()) == fp_value); 494 ASSERT(!is_bottommost || input_->GetRegister(rbp.code()) == fp_value);
317 output_frame->SetFp(fp_value); 495 output_frame->SetFp(fp_value);
318 if (is_topmost) output_frame->SetRegister(rbp.code(), fp_value); 496 if (is_topmost) output_frame->SetRegister(rbp.code(), fp_value);
319 if (FLAG_trace_deopt) { 497 if (FLAG_trace_deopt) {
320 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 498 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
321 V8PRIxPTR " ; caller's fp\n", 499 V8PRIxPTR " ; caller's fp\n",
322 fp_value, output_offset, value); 500 fp_value, output_offset, value);
323 } 501 }
324 502
325 // The context can be gotten from the function so long as we don't 503 // For the bottommost output frame the context can be gotten from the input
326 // optimize functions that need local contexts. 504 // frame. For all subsequent output frames it can be gotten from the function
505 // so long as we don't inline functions that need local contexts.
327 output_offset -= kPointerSize; 506 output_offset -= kPointerSize;
328 input_offset -= kPointerSize; 507 input_offset -= kPointerSize;
329 value = reinterpret_cast<intptr_t>(function->context()); 508 if (is_bottommost) {
330 // The context for the bottommost output frame should also agree with the 509 value = input_->GetFrameSlot(input_offset);
331 // input frame. 510 } else {
332 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); 511 value = reinterpret_cast<intptr_t>(function->context());
512 }
333 output_frame->SetFrameSlot(output_offset, value); 513 output_frame->SetFrameSlot(output_offset, value);
334 if (is_topmost) output_frame->SetRegister(rsi.code(), value); 514 if (is_topmost) output_frame->SetRegister(rsi.code(), value);
335 if (FLAG_trace_deopt) { 515 if (FLAG_trace_deopt) {
336 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 516 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
337 V8PRIxPTR "; context\n", 517 V8PRIxPTR "; context\n",
338 top_address + output_offset, output_offset, value); 518 top_address + output_offset, output_offset, value);
339 } 519 }
340 520
341 // The function was mentioned explicitly in the BEGIN_FRAME. 521 // The function was mentioned explicitly in the BEGIN_FRAME.
342 output_offset -= kPointerSize; 522 output_offset -= kPointerSize;
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 } 775 }
596 __ bind(&done); 776 __ bind(&done);
597 } 777 }
598 778
599 #undef __ 779 #undef __
600 780
601 781
602 } } // namespace v8::internal 782 } } // namespace v8::internal
603 783
604 #endif // V8_TARGET_ARCH_X64 784 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/debug-x64.cc ('k') | src/x64/disasm-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698