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

Side by Side Diff: src/deoptimizer.cc

Issue 1936043002: [es6] Properly handle the case when an inlined getter/setter/constructor does a tail call. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Complete rework Created 4 years, 7 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
OLDNEW
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/deoptimizer.h" 5 #include "src/deoptimizer.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/ast/prettyprinter.h" 8 #include "src/ast/prettyprinter.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/disasm.h" 10 #include "src/disasm.h"
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 value = output_[frame_index - 1]->GetConstantPool(); 961 value = output_[frame_index - 1]->GetConstantPool();
962 } 962 }
963 output_frame->SetCallerConstantPool(output_offset, value); 963 output_frame->SetCallerConstantPool(output_offset, value);
964 DebugPrintOutputSlot(value, frame_index, output_offset, 964 DebugPrintOutputSlot(value, frame_index, output_offset,
965 "caller's constant_pool\n"); 965 "caller's constant_pool\n");
966 } 966 }
967 967
968 // For the bottommost output frame the context can be gotten from the input 968 // For the bottommost output frame the context can be gotten from the input
969 // frame. For all subsequent output frames it can be gotten from the function 969 // frame. For all subsequent output frames it can be gotten from the function
970 // so long as we don't inline functions that need local contexts. 970 // so long as we don't inline functions that need local contexts.
971 Register context_reg = JavaScriptFrame::context_register();
972 output_offset -= kPointerSize; 971 output_offset -= kPointerSize;
973 972
974 TranslatedFrame::iterator context_pos = value_iterator; 973 TranslatedFrame::iterator context_pos = value_iterator;
975 int context_input_index = input_index; 974 int context_input_index = input_index;
976 // When deoptimizing into a catch block, we need to take the context 975 // When deoptimizing into a catch block, we need to take the context
977 // from just above the top of the operand stack (we push the context 976 // from just above the top of the operand stack (we push the context
978 // at the entry of the try block). 977 // at the entry of the try block).
979 if (goto_catch_handler) { 978 if (goto_catch_handler) {
980 for (unsigned i = 0; i < height + 1; ++i) { 979 for (unsigned i = 0; i < height + 1; ++i) {
981 context_pos++; 980 context_pos++;
982 context_input_index++; 981 context_input_index++;
983 } 982 }
984 } 983 }
985 // Read the context from the translations. 984 // Read the context from the translations.
986 Object* context = context_pos->GetRawValue(); 985 Object* context = context_pos->GetRawValue();
987 if (context == isolate_->heap()->undefined_value()) { 986 if (context == isolate_->heap()->undefined_value()) {
988 // If the context was optimized away, just use the context from 987 // If the context was optimized away, just use the context from
989 // the activation. This should only apply to Crankshaft code. 988 // the activation. This should only apply to Crankshaft code.
990 CHECK(!compiled_code_->is_turbofanned()); 989 CHECK(!compiled_code_->is_turbofanned());
991 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_) 990 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_)
992 : function->context(); 991 : function->context();
993 } 992 }
994 value = reinterpret_cast<intptr_t>(context); 993 value = reinterpret_cast<intptr_t>(context);
995 output_frame->SetContext(value); 994 output_frame->SetContext(value);
996 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); 995 if (is_topmost) {
996 Register context_reg = JavaScriptFrame::context_register();
997 output_frame->SetRegister(context_reg.code(), value);
998 }
997 WriteValueToOutput(context, context_input_index, frame_index, output_offset, 999 WriteValueToOutput(context, context_input_index, frame_index, output_offset,
998 "context "); 1000 "context ");
999 if (context == isolate_->heap()->arguments_marker()) { 1001 if (context == isolate_->heap()->arguments_marker()) {
1000 Address output_address = 1002 Address output_address =
1001 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + 1003 reinterpret_cast<Address>(output_[frame_index]->GetTop()) +
1002 output_offset; 1004 output_offset;
1003 values_to_materialize_.push_back({output_address, context_pos}); 1005 values_to_materialize_.push_back({output_address, context_pos});
1004 } 1006 }
1005 value_iterator++; 1007 value_iterator++;
1006 input_index++; 1008 input_index++;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 new_caller_frame_top); 1488 new_caller_frame_top);
1487 } 1489 }
1488 caller_frame_top_ = new_caller_frame_top; 1490 caller_frame_top_ = new_caller_frame_top;
1489 caller_fp_ = adaptor_caller_fp; 1491 caller_fp_ = adaptor_caller_fp;
1490 caller_pc_ = adaptor_caller_pc; 1492 caller_pc_ = adaptor_caller_pc;
1491 } 1493 }
1492 1494
1493 void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame, 1495 void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
1494 int frame_index) { 1496 int frame_index) {
1495 TranslatedFrame::iterator value_iterator = translated_frame->begin(); 1497 TranslatedFrame::iterator value_iterator = translated_frame->begin();
1498 bool is_topmost = (output_count_ - 1 == frame_index);
1496 int input_index = 0; 1499 int input_index = 0;
1497 1500
1498 Builtins* builtins = isolate_->builtins(); 1501 Builtins* builtins = isolate_->builtins();
1499 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 1502 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
1500 unsigned height = translated_frame->height(); 1503 unsigned height = translated_frame->height();
1501 unsigned height_in_bytes = height * kPointerSize; 1504 unsigned height_in_bytes = height * kPointerSize;
1505
1506 // We need to restore the result returned from the constructor before
1507 // we return to the construct stub.
1508 if (is_topmost) {
1509 height_in_bytes += kPointerSize;
1510 }
1511
1502 // Skip function. 1512 // Skip function.
1503 value_iterator++; 1513 value_iterator++;
1504 input_index++; 1514 input_index++;
1505 if (trace_scope_ != NULL) { 1515 if (trace_scope_ != NULL) {
1506 PrintF(trace_scope_->file(), 1516 PrintF(trace_scope_->file(),
1507 " translating construct stub => height=%d\n", height_in_bytes); 1517 " translating construct stub => height=%d\n", height_in_bytes);
1508 } 1518 }
1509 1519
1510 unsigned fixed_frame_size = ConstructFrameConstants::kFixedFrameSize; 1520 unsigned fixed_frame_size = ConstructFrameConstants::kFixedFrameSize;
1511 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1521 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1512 1522
1513 // Allocate and store the output frame description. 1523 // Allocate and store the output frame description.
1514 FrameDescription* output_frame = 1524 FrameDescription* output_frame =
1515 new (output_frame_size) FrameDescription(output_frame_size); 1525 new (output_frame_size) FrameDescription(output_frame_size);
1516 output_frame->SetFrameType(StackFrame::CONSTRUCT); 1526 output_frame->SetFrameType(StackFrame::CONSTRUCT);
1517 1527
1518 // Construct stub can not be topmost or bottommost. 1528 // Construct stub can not be topmost.
1519 DCHECK(frame_index > 0 && frame_index < output_count_ - 1); 1529 DCHECK(frame_index > 0 && frame_index < output_count_);
1520 DCHECK(output_[frame_index] == NULL); 1530 DCHECK(output_[frame_index] == NULL);
1521 output_[frame_index] = output_frame; 1531 output_[frame_index] = output_frame;
1522 1532
1523 // The top address of the frame is computed from the previous frame's top and 1533 // The top address of the frame is computed from the previous frame's top and
1524 // this frame's size. 1534 // this frame's size.
1525 intptr_t top_address; 1535 intptr_t top_address;
1526 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1536 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1527 output_frame->SetTop(top_address); 1537 output_frame->SetTop(top_address);
1528 1538
1529 // Compute the incoming parameter translation. 1539 // Compute the incoming parameter translation.
(...skipping 14 matching lines...) Expand all
1544 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 1554 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1545 output_frame->SetCallerPc(output_offset, callers_pc); 1555 output_frame->SetCallerPc(output_offset, callers_pc);
1546 DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n"); 1556 DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1547 1557
1548 // Read caller's FP from the previous frame, and set this frame's FP. 1558 // Read caller's FP from the previous frame, and set this frame's FP.
1549 output_offset -= kFPOnStackSize; 1559 output_offset -= kFPOnStackSize;
1550 intptr_t value = output_[frame_index - 1]->GetFp(); 1560 intptr_t value = output_[frame_index - 1]->GetFp();
1551 output_frame->SetCallerFp(output_offset, value); 1561 output_frame->SetCallerFp(output_offset, value);
1552 intptr_t fp_value = top_address + output_offset; 1562 intptr_t fp_value = top_address + output_offset;
1553 output_frame->SetFp(fp_value); 1563 output_frame->SetFp(fp_value);
1564 if (is_topmost) {
1565 Register fp_reg = JavaScriptFrame::fp_register();
1566 output_frame->SetRegister(fp_reg.code(), fp_value);
1567 }
1554 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); 1568 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1555 1569
1556 if (FLAG_enable_embedded_constant_pool) { 1570 if (FLAG_enable_embedded_constant_pool) {
1557 // Read the caller's constant pool from the previous frame. 1571 // Read the caller's constant pool from the previous frame.
1558 output_offset -= kPointerSize; 1572 output_offset -= kPointerSize;
1559 value = output_[frame_index - 1]->GetConstantPool(); 1573 value = output_[frame_index - 1]->GetConstantPool();
1560 output_frame->SetCallerConstantPool(output_offset, value); 1574 output_frame->SetCallerConstantPool(output_offset, value);
1561 DebugPrintOutputSlot(value, frame_index, output_offset, 1575 DebugPrintOutputSlot(value, frame_index, output_offset,
1562 "caller's constant_pool\n"); 1576 "caller's constant_pool\n");
1563 } 1577 }
1564 1578
1565 // A marker value is used to mark the frame. 1579 // A marker value is used to mark the frame.
1566 output_offset -= kPointerSize; 1580 output_offset -= kPointerSize;
1567 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); 1581 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
1568 output_frame->SetFrameSlot(output_offset, value); 1582 output_frame->SetFrameSlot(output_offset, value);
1569 DebugPrintOutputSlot(value, frame_index, output_offset, 1583 DebugPrintOutputSlot(value, frame_index, output_offset,
1570 "typed frame marker\n"); 1584 "typed frame marker\n");
1571 1585
1572 // The context can be gotten from the previous frame. 1586 // The context can be gotten from the previous frame.
1573 output_offset -= kPointerSize; 1587 output_offset -= kPointerSize;
1574 value = output_[frame_index - 1]->GetContext(); 1588 value = output_[frame_index - 1]->GetContext();
1575 output_frame->SetFrameSlot(output_offset, value); 1589 output_frame->SetFrameSlot(output_offset, value);
1590 if (is_topmost) {
1591 Register context_reg = JavaScriptFrame::context_register();
1592 output_frame->SetRegister(context_reg.code(), value);
1593 output_frame->SetRegister(context_reg.code(), 153);
Jarin 2016/05/03 14:42:36 ???
Igor Sheludko 2016/05/06 09:50:03 Oops.
1594 }
1576 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n"); 1595 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1577 1596
1578 // The allocation site. 1597 // The allocation site.
1579 output_offset -= kPointerSize; 1598 output_offset -= kPointerSize;
1580 value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value()); 1599 value = reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value());
1581 output_frame->SetFrameSlot(output_offset, value); 1600 output_frame->SetFrameSlot(output_offset, value);
1582 DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n"); 1601 DebugPrintOutputSlot(value, frame_index, output_offset, "allocation site\n");
1583 1602
1584 // Number of incoming arguments. 1603 // Number of incoming arguments.
1585 output_offset -= kPointerSize; 1604 output_offset -= kPointerSize;
1586 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); 1605 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
1587 output_frame->SetFrameSlot(output_offset, value); 1606 output_frame->SetFrameSlot(output_offset, value);
1588 DebugPrintOutputSlot(value, frame_index, output_offset, "argc "); 1607 DebugPrintOutputSlot(value, frame_index, output_offset, "argc ");
1589 if (trace_scope_ != nullptr) { 1608 if (trace_scope_ != nullptr) {
1590 PrintF(trace_scope_->file(), "(%d)\n", height - 1); 1609 PrintF(trace_scope_->file(), "(%d)\n", height - 1);
1591 } 1610 }
1592 1611
1593 // The newly allocated object was passed as receiver in the artificial 1612 // The newly allocated object was passed as receiver in the artificial
1594 // constructor stub environment created by HEnvironment::CopyForInlining(). 1613 // constructor stub environment created by HEnvironment::CopyForInlining().
1595 output_offset -= kPointerSize; 1614 output_offset -= kPointerSize;
1596 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); 1615 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1597 output_frame->SetFrameSlot(output_offset, value); 1616 output_frame->SetFrameSlot(output_offset, value);
1598 DebugPrintOutputSlot(value, frame_index, output_offset, 1617 DebugPrintOutputSlot(value, frame_index, output_offset,
1599 "allocated receiver\n"); 1618 "allocated receiver\n");
1600 1619
1620 if (is_topmost) {
1621 // Ensure the result is restored back when we return to the stub.
1622 output_offset -= kPointerSize;
1623 Register result_reg = FullCodeGenerator::result_register();
1624 value = input_->GetRegister(result_reg.code());
1625 output_frame->SetFrameSlot(output_offset, value);
1626 DebugPrintOutputSlot(value, frame_index, output_offset,
1627 "constructor result\n");
1628
1629 output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG));
1630 } else {
1631 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
1632 }
1633
1601 CHECK_EQ(0u, output_offset); 1634 CHECK_EQ(0u, output_offset);
1602 1635
1603 intptr_t pc = reinterpret_cast<intptr_t>( 1636 intptr_t pc = reinterpret_cast<intptr_t>(
1604 construct_stub->instruction_start() + 1637 construct_stub->instruction_start() +
1605 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 1638 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1606 output_frame->SetPc(pc); 1639 output_frame->SetPc(pc);
1607 if (FLAG_enable_embedded_constant_pool) { 1640 if (FLAG_enable_embedded_constant_pool) {
1608 intptr_t constant_pool_value = 1641 intptr_t constant_pool_value =
1609 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); 1642 reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1610 output_frame->SetConstantPool(constant_pool_value); 1643 output_frame->SetConstantPool(constant_pool_value);
1644 if (is_topmost) {
1645 Register constant_pool_reg =
1646 JavaScriptFrame::constant_pool_pointer_register();
1647 output_frame->SetRegister(constant_pool_reg.code(), fp_value);
1648 }
1649 }
1650
1651 // Set the continuation for the topmost frame.
1652 if (is_topmost) {
1653 Builtins* builtins = isolate_->builtins();
1654 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1655 if (bailout_type_ == LAZY) {
1656 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1657 } else if (bailout_type_ == SOFT) {
1658 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1659 } else {
1660 CHECK_EQ(bailout_type_, EAGER);
1661 }
1662 output_frame->SetContinuation(
1663 reinterpret_cast<intptr_t>(continuation->entry()));
1611 } 1664 }
1612 } 1665 }
1613 1666
1614 void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame, 1667 void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
1615 int frame_index, 1668 int frame_index,
1616 bool is_setter_stub_frame) { 1669 bool is_setter_stub_frame) {
1617 TranslatedFrame::iterator value_iterator = translated_frame->begin(); 1670 TranslatedFrame::iterator value_iterator = translated_frame->begin();
1671 bool is_topmost = (output_count_ - 1 == frame_index);
1618 int input_index = 0; 1672 int input_index = 0;
1619 1673
1620 // Skip accessor. 1674 // Skip accessor.
1621 value_iterator++; 1675 value_iterator++;
1622 input_index++; 1676 input_index++;
1623 // The receiver (and the implicit return value, if any) are expected in 1677 // The receiver (and the implicit return value, if any) are expected in
1624 // registers by the LoadIC/StoreIC, so they don't belong to the output stack 1678 // registers by the LoadIC/StoreIC, so they don't belong to the output stack
1625 // frame. This means that we have to use a height of 0. 1679 // frame. This means that we have to use a height of 0.
1626 unsigned height = 0; 1680 unsigned height = 0;
1627 unsigned height_in_bytes = height * kPointerSize; 1681 unsigned height_in_bytes = height * kPointerSize;
1682
1683 // We don't need to restore the result in case of setter call because we have
1684 // to return the stored value but not the result of the setter function.
1685 bool should_preserve_result = is_topmost && !is_setter_stub_frame;
1686 if (should_preserve_result) {
1687 height_in_bytes += kPointerSize;
1688 }
1689
1628 const char* kind = is_setter_stub_frame ? "setter" : "getter"; 1690 const char* kind = is_setter_stub_frame ? "setter" : "getter";
1629 if (trace_scope_ != NULL) { 1691 if (trace_scope_ != NULL) {
1630 PrintF(trace_scope_->file(), 1692 PrintF(trace_scope_->file(),
1631 " translating %s stub => height=%u\n", kind, height_in_bytes); 1693 " translating %s stub => height=%u\n", kind, height_in_bytes);
1632 } 1694 }
1633 1695
1634 // We need 1 stack entry for the return address and enough entries for the 1696 // We need 1 stack entry for the return address and enough entries for the
1635 // StackFrame::INTERNAL (FP, frame type, context, code object and constant 1697 // StackFrame::INTERNAL (FP, frame type, context, code object and constant
1636 // pool (if enabled)- see MacroAssembler::EnterFrame). 1698 // pool (if enabled)- see MacroAssembler::EnterFrame).
1637 // For a setter stub frame we need one additional entry for the implicit 1699 // For a setter stub frame we need one additional entry for the implicit
1638 // return value, see StoreStubCompiler::CompileStoreViaSetter. 1700 // return value, see StoreStubCompiler::CompileStoreViaSetter.
1639 unsigned fixed_frame_entries = 1701 unsigned fixed_frame_entries =
1640 (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 + 1702 (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 +
1641 (is_setter_stub_frame ? 1 : 0); 1703 (is_setter_stub_frame ? 1 : 0);
1642 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; 1704 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
1643 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1705 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1644 1706
1645 // Allocate and store the output frame description. 1707 // Allocate and store the output frame description.
1646 FrameDescription* output_frame = 1708 FrameDescription* output_frame =
1647 new (output_frame_size) FrameDescription(output_frame_size); 1709 new (output_frame_size) FrameDescription(output_frame_size);
1648 output_frame->SetFrameType(StackFrame::INTERNAL); 1710 output_frame->SetFrameType(StackFrame::INTERNAL);
1649 1711
1650 // A frame for an accessor stub can not be the topmost or bottommost one. 1712 // A frame for an accessor stub can not be bottommost.
1651 CHECK(frame_index > 0 && frame_index < output_count_ - 1); 1713 CHECK(frame_index > 0 && frame_index < output_count_);
1652 CHECK_NULL(output_[frame_index]); 1714 CHECK_NULL(output_[frame_index]);
1653 output_[frame_index] = output_frame; 1715 output_[frame_index] = output_frame;
1654 1716
1655 // The top address of the frame is computed from the previous frame's top and 1717 // The top address of the frame is computed from the previous frame's top and
1656 // this frame's size. 1718 // this frame's size.
1657 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1719 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1658 output_frame->SetTop(top_address); 1720 output_frame->SetTop(top_address);
1659 1721
1660 unsigned output_offset = output_frame_size; 1722 unsigned output_offset = output_frame_size;
1661 1723
1662 // Read caller's PC from the previous frame. 1724 // Read caller's PC from the previous frame.
1663 output_offset -= kPCOnStackSize; 1725 output_offset -= kPCOnStackSize;
1664 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 1726 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1665 output_frame->SetCallerPc(output_offset, callers_pc); 1727 output_frame->SetCallerPc(output_offset, callers_pc);
1666 DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n"); 1728 DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n");
1667 1729
1668 // Read caller's FP from the previous frame, and set this frame's FP. 1730 // Read caller's FP from the previous frame, and set this frame's FP.
1669 output_offset -= kFPOnStackSize; 1731 output_offset -= kFPOnStackSize;
1670 intptr_t value = output_[frame_index - 1]->GetFp(); 1732 intptr_t value = output_[frame_index - 1]->GetFp();
1671 output_frame->SetCallerFp(output_offset, value); 1733 output_frame->SetCallerFp(output_offset, value);
1672 intptr_t fp_value = top_address + output_offset; 1734 intptr_t fp_value = top_address + output_offset;
1673 output_frame->SetFp(fp_value); 1735 output_frame->SetFp(fp_value);
1736 if (is_topmost) {
1737 Register fp_reg = JavaScriptFrame::fp_register();
1738 output_frame->SetRegister(fp_reg.code(), fp_value);
1739 }
1674 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); 1740 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
1675 1741
1676 if (FLAG_enable_embedded_constant_pool) { 1742 if (FLAG_enable_embedded_constant_pool) {
1677 // Read the caller's constant pool from the previous frame. 1743 // Read the caller's constant pool from the previous frame.
1678 output_offset -= kPointerSize; 1744 output_offset -= kPointerSize;
1679 value = output_[frame_index - 1]->GetConstantPool(); 1745 value = output_[frame_index - 1]->GetConstantPool();
1680 output_frame->SetCallerConstantPool(output_offset, value); 1746 output_frame->SetCallerConstantPool(output_offset, value);
1681 DebugPrintOutputSlot(value, frame_index, output_offset, 1747 DebugPrintOutputSlot(value, frame_index, output_offset,
1682 "caller's constant_pool\n"); 1748 "caller's constant_pool\n");
1683 } 1749 }
(...skipping 14 matching lines...) Expand all
1698 Builtins::kLoadIC_Getter_ForDeopt; 1764 Builtins::kLoadIC_Getter_ForDeopt;
1699 Code* accessor_stub = isolate_->builtins()->builtin(name); 1765 Code* accessor_stub = isolate_->builtins()->builtin(name);
1700 value = reinterpret_cast<intptr_t>(accessor_stub); 1766 value = reinterpret_cast<intptr_t>(accessor_stub);
1701 output_frame->SetFrameSlot(output_offset, value); 1767 output_frame->SetFrameSlot(output_offset, value);
1702 DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n"); 1768 DebugPrintOutputSlot(value, frame_index, output_offset, "code object\n");
1703 1769
1704 // The context can be gotten from the previous frame. 1770 // The context can be gotten from the previous frame.
1705 output_offset -= kPointerSize; 1771 output_offset -= kPointerSize;
1706 value = output_[frame_index - 1]->GetContext(); 1772 value = output_[frame_index - 1]->GetContext();
1707 output_frame->SetFrameSlot(output_offset, value); 1773 output_frame->SetFrameSlot(output_offset, value);
1774 if (is_topmost) {
1775 Register context_reg = JavaScriptFrame::context_register();
1776 output_frame->SetRegister(context_reg.code(), value);
1777 }
1708 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n"); 1778 DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
1709 1779
1710 // Skip receiver. 1780 // Skip receiver.
1711 value_iterator++; 1781 value_iterator++;
1712 input_index++; 1782 input_index++;
1713 1783
1714 if (is_setter_stub_frame) { 1784 if (is_setter_stub_frame) {
1715 // The implicit return value was part of the artificial setter stub 1785 // The implicit return value was part of the artificial setter stub
1716 // environment. 1786 // environment.
1717 output_offset -= kPointerSize; 1787 output_offset -= kPointerSize;
1718 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, 1788 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
1719 output_offset); 1789 output_offset);
1720 } 1790 }
1721 1791
1792 if (should_preserve_result) {
1793 // Ensure the result is restored back when we return to the stub.
1794 output_offset -= kPointerSize;
1795 Register result_reg = FullCodeGenerator::result_register();
1796 value = input_->GetRegister(result_reg.code());
1797 output_frame->SetFrameSlot(output_offset, value);
1798 DebugPrintOutputSlot(value, frame_index, output_offset,
1799 "accessor result\n");
1800
1801 output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG));
1802 } else {
1803 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
1804 }
1805
1722 CHECK_EQ(0u, output_offset); 1806 CHECK_EQ(0u, output_offset);
1723 1807
1724 Smi* offset = is_setter_stub_frame ? 1808 Smi* offset = is_setter_stub_frame ?
1725 isolate_->heap()->setter_stub_deopt_pc_offset() : 1809 isolate_->heap()->setter_stub_deopt_pc_offset() :
1726 isolate_->heap()->getter_stub_deopt_pc_offset(); 1810 isolate_->heap()->getter_stub_deopt_pc_offset();
1727 intptr_t pc = reinterpret_cast<intptr_t>( 1811 intptr_t pc = reinterpret_cast<intptr_t>(
1728 accessor_stub->instruction_start() + offset->value()); 1812 accessor_stub->instruction_start() + offset->value());
1729 output_frame->SetPc(pc); 1813 output_frame->SetPc(pc);
1730 if (FLAG_enable_embedded_constant_pool) { 1814 if (FLAG_enable_embedded_constant_pool) {
1731 intptr_t constant_pool_value = 1815 intptr_t constant_pool_value =
1732 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); 1816 reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
1733 output_frame->SetConstantPool(constant_pool_value); 1817 output_frame->SetConstantPool(constant_pool_value);
1818 if (is_topmost) {
1819 Register constant_pool_reg =
1820 JavaScriptFrame::constant_pool_pointer_register();
1821 output_frame->SetRegister(constant_pool_reg.code(), fp_value);
1822 }
1823 }
1824
1825 // Set the continuation for the topmost frame.
1826 if (is_topmost) {
1827 Builtins* builtins = isolate_->builtins();
1828 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1829 if (bailout_type_ == LAZY) {
1830 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1831 } else if (bailout_type_ == SOFT) {
1832 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1833 } else {
1834 CHECK_EQ(bailout_type_, EAGER);
1835 }
1836 output_frame->SetContinuation(
1837 reinterpret_cast<intptr_t>(continuation->entry()));
1734 } 1838 }
1735 } 1839 }
1736 1840
1737 void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame, 1841 void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame,
1738 int frame_index) { 1842 int frame_index) {
1739 // 1843 //
1740 // FROM TO 1844 // FROM TO
1741 // | .... | | .... | 1845 // | .... | | .... |
1742 // +-------------------------+ +-------------------------+ 1846 // +-------------------------+ +-------------------------+
1743 // | JSFunction continuation | | JSFunction continuation | 1847 // | JSFunction continuation | | JSFunction continuation |
(...skipping 2067 matching lines...) Expand 10 before | Expand all | Expand 10 after
3811 CHECK(value_info->IsMaterializedObject()); 3915 CHECK(value_info->IsMaterializedObject());
3812 3916
3813 value_info->value_ = 3917 value_info->value_ =
3814 Handle<Object>(previously_materialized_objects->get(i), isolate_); 3918 Handle<Object>(previously_materialized_objects->get(i), isolate_);
3815 } 3919 }
3816 } 3920 }
3817 } 3921 }
3818 3922
3819 } // namespace internal 3923 } // namespace internal
3820 } // namespace v8 3924 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698