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

Side by Side Diff: src/deoptimizer.cc

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

Powered by Google App Engine
This is Rietveld 408576698