OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 435 |
436 // We might be in the middle of incremental marking with compaction. | 436 // We might be in the middle of incremental marking with compaction. |
437 // Tell collector to treat this code object in a special way and | 437 // Tell collector to treat this code object in a special way and |
438 // ignore all slots that might have been recorded on it. | 438 // ignore all slots that might have been recorded on it. |
439 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]); | 439 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]); |
440 } | 440 } |
441 } | 441 } |
442 } | 442 } |
443 | 443 |
444 | 444 |
445 static int FindPatchAddressForReturnAddress(Code* code, int pc) { | |
446 DeoptimizationInputData* input_data = | |
447 DeoptimizationInputData::cast(code->deoptimization_data()); | |
448 int patch_count = input_data->ReturnAddressPatchCount(); | |
449 for (int i = 0; i < patch_count; i++) { | |
450 int return_pc = input_data->ReturnAddressPc(i)->value(); | |
451 int patch_pc = input_data->PatchedAddressPc(i)->value(); | |
452 // If the supplied pc matches the return pc or if the address | |
453 // has been already patched, return the patch pc. | |
454 if (pc == return_pc || pc == patch_pc) { | |
455 return patch_pc; | |
456 } | |
457 } | |
458 return -1; | |
459 } | |
460 | |
461 | |
462 // For all marked Turbofanned code on stack, change the return address to go | 445 // For all marked Turbofanned code on stack, change the return address to go |
463 // to the deoptimization block. | 446 // to the deoptimization block. |
464 void Deoptimizer::PatchStackForMarkedCode(Isolate* isolate) { | 447 void Deoptimizer::PatchStackForMarkedCode(Isolate* isolate) { |
465 // TODO(jarin) We should tolerate missing patch entry for the topmost frame. | 448 // TODO(jarin) We should tolerate missing patch entry for the topmost frame. |
466 for (StackFrameIterator it(isolate, isolate->thread_local_top()); !it.done(); | 449 for (StackFrameIterator it(isolate, isolate->thread_local_top()); !it.done(); |
467 it.Advance()) { | 450 it.Advance()) { |
468 StackFrame::Type type = it.frame()->type(); | 451 StackFrame::Type type = it.frame()->type(); |
469 if (type == StackFrame::OPTIMIZED) { | 452 if (type == StackFrame::OPTIMIZED) { |
470 Code* code = it.frame()->LookupCode(); | 453 Code* code = it.frame()->LookupCode(); |
471 if (code->is_turbofanned() && code->marked_for_deoptimization()) { | 454 if (code->is_turbofanned() && code->marked_for_deoptimization()) { |
472 JSFunction* function = | 455 JSFunction* function = |
473 static_cast<OptimizedFrame*>(it.frame())->function(); | 456 static_cast<OptimizedFrame*>(it.frame())->function(); |
474 Address* pc_address = it.frame()->pc_address(); | 457 Address* pc_address = it.frame()->pc_address(); |
475 int pc_offset = | 458 int pc_offset = |
476 static_cast<int>(*pc_address - code->instruction_start()); | 459 static_cast<int>(*pc_address - code->instruction_start()); |
477 int new_pc_offset = FindPatchAddressForReturnAddress(code, pc_offset); | 460 SafepointEntry safepoint_entry = code->GetSafepointEntry(*pc_address); |
| 461 unsigned new_pc_offset = safepoint_entry.deoptimization_pc(); |
478 | 462 |
479 if (FLAG_trace_deopt) { | 463 if (FLAG_trace_deopt) { |
480 CodeTracer::Scope scope(isolate->GetCodeTracer()); | 464 CodeTracer::Scope scope(isolate->GetCodeTracer()); |
481 PrintF(scope.file(), "[patching stack address for function: "); | 465 PrintF(scope.file(), "[patching stack address for function: "); |
482 function->PrintName(scope.file()); | 466 function->PrintName(scope.file()); |
483 PrintF(scope.file(), " (Pc offset %i -> %i)]\n", pc_offset, | 467 PrintF(scope.file(), " (Pc offset %i -> %i)]\n", pc_offset, |
484 new_pc_offset); | 468 new_pc_offset); |
485 } | 469 } |
486 | 470 |
487 CHECK_LE(0, new_pc_offset); | 471 CHECK(new_pc_offset != Safepoint::kNoDeoptimizationPc); |
488 *pc_address += new_pc_offset - pc_offset; | 472 *pc_address += static_cast<int>(new_pc_offset) - pc_offset; |
489 } | 473 } |
490 } | 474 } |
491 } | 475 } |
492 } | 476 } |
493 | 477 |
494 | 478 |
495 void Deoptimizer::DeoptimizeAll(Isolate* isolate) { | 479 void Deoptimizer::DeoptimizeAll(Isolate* isolate) { |
496 if (FLAG_trace_deopt) { | 480 if (FLAG_trace_deopt) { |
497 CodeTracer::Scope scope(isolate->GetCodeTracer()); | 481 CodeTracer::Scope scope(isolate->GetCodeTracer()); |
498 PrintF(scope.file(), "[deoptimize all code in all contexts]\n"); | 482 PrintF(scope.file(), "[deoptimize all code in all contexts]\n"); |
(...skipping 3178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3677 } | 3661 } |
3678 | 3662 |
3679 | 3663 |
3680 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3664 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
3681 v->VisitPointer(BitCast<Object**>(&function_)); | 3665 v->VisitPointer(BitCast<Object**>(&function_)); |
3682 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3666 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
3683 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3667 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
3684 } | 3668 } |
3685 | 3669 |
3686 } } // namespace v8::internal | 3670 } } // namespace v8::internal |
OLD | NEW |