Commit 4d4bd54f authored by jarin's avatar jarin Committed by Commit bot

[turbofan] Fix operand calculation for constant materialization from frame.

BUG=chromium:582702
LOG=N

Review URL: https://codereview.chromium.org/1781393002

Cr-Commit-Position: refs/heads/master@{#34736}
parent 7b48773d
......@@ -150,8 +150,11 @@ class ArmOperandConverter final : public InstructionOperandConverter {
MemOperand ToMemOperand(InstructionOperand* op) const {
DCHECK_NOT_NULL(op);
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToMemOperand(AllocatedOperand::cast(op)->index());
}
MemOperand SlotToMemOperand(int slot) const {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
}
};
......@@ -1364,9 +1367,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ ldr(dst, MemOperand(fp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ ldr(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -207,8 +207,11 @@ class Arm64OperandConverter final : public InstructionOperandConverter {
MemOperand ToMemOperand(InstructionOperand* op, MacroAssembler* masm) const {
DCHECK_NOT_NULL(op);
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToMemOperand(AllocatedOperand::cast(op)->index(), masm);
}
MemOperand SlotToMemOperand(int slot, MacroAssembler* masm) const {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
if (offset.from_frame_pointer()) {
int from_sp = offset.offset() + frame_access_state()->GetSPToFPOffset();
// Convert FP-offsets to SP-offsets if it results in better code.
......@@ -1613,9 +1616,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
if (src.type() == Constant::kHeapObject) {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ Ldr(dst, MemOperand(fp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ Ldr(dst, g.SlotToMemOperand(slot, masm()));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -259,16 +259,15 @@ void CodeGenerator::RecordSafepoint(ReferenceMap* references,
}
}
bool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object,
int* offset_return) {
int* slot_return) {
if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
if (info()->has_context() && object.is_identical_to(info()->context()) &&
!info()->is_osr()) {
*offset_return = StandardFrameConstants::kContextOffset;
*slot_return = Frame::kContextSlot;
return true;
} else if (object.is_identical_to(info()->closure())) {
*offset_return = JavaScriptFrameConstants::kFunctionOffset;
*slot_return = Frame::kJSFunctionSlot;
return true;
}
}
......
......@@ -77,7 +77,7 @@ class CodeGenerator final : public GapResolver::Assembler {
// Check if a heap object can be materialized by loading from the frame, which
// is usually way cheaper than materializing the actual heap object constant.
bool IsMaterializableFromFrame(Handle<HeapObject> object, int* offset_return);
bool IsMaterializableFromFrame(Handle<HeapObject> object, int* slot_return);
// Check if a heap object can be materialized by loading from a heap root,
// which is cheaper on some platforms than materializing the actual heap
// object constant.
......
......@@ -49,16 +49,13 @@ class IA32OperandConverter : public InstructionOperandConverter {
return Operand(ToDoubleRegister(op));
}
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return Operand(offset.from_stack_pointer() ? esp : ebp,
offset.offset() + extra);
return SlotToOperand(AllocatedOperand::cast(op)->index(), extra);
}
Operand ToMaterializableOperand(int materializable_offset) {
FrameOffset offset = frame_access_state()->GetFrameOffset(
FPOffsetToFrameSlot(materializable_offset));
return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset());
Operand SlotToOperand(int slot, int extra = 0) {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return Operand(offset.from_stack_pointer() ? esp : ebp,
offset.offset() + extra);
}
Operand HighOperand(InstructionOperand* op) {
......@@ -1652,15 +1649,15 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
Constant src_constant = g.ToConstant(source);
if (src_constant.type() == Constant::kHeapObject) {
Handle<HeapObject> src = src_constant.ToHeapObject();
int offset;
if (IsMaterializableFromFrame(src, &offset)) {
int slot;
if (IsMaterializableFromFrame(src, &slot)) {
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ mov(dst, g.ToMaterializableOperand(offset));
__ mov(dst, g.SlotToOperand(slot));
} else {
DCHECK(destination->IsStackSlot());
Operand dst = g.ToOperand(destination);
__ push(g.ToMaterializableOperand(offset));
__ push(g.SlotToOperand(slot));
__ pop(dst);
}
} else if (destination->IsRegister()) {
......
......@@ -120,8 +120,11 @@ class MipsOperandConverter final : public InstructionOperandConverter {
MemOperand ToMemOperand(InstructionOperand* op) const {
DCHECK_NOT_NULL(op);
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToMemOperand(AllocatedOperand::cast(op)->index());
}
MemOperand SlotToMemOperand(int slot) const {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
}
};
......@@ -1703,9 +1706,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ lw(dst, MemOperand(fp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ lw(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -120,8 +120,11 @@ class MipsOperandConverter final : public InstructionOperandConverter {
MemOperand ToMemOperand(InstructionOperand* op) const {
DCHECK_NOT_NULL(op);
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToMemOperand(AllocatedOperand::cast(op)->index());
}
MemOperand SlotToMemOperand(int slot) const {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
}
};
......@@ -2007,9 +2010,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ ld(dst, MemOperand(fp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ ld(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -104,8 +104,11 @@ class PPCOperandConverter final : public InstructionOperandConverter {
MemOperand ToMemOperand(InstructionOperand* op) const {
DCHECK_NOT_NULL(op);
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToMemOperand(AllocatedOperand::cast(op)->index());
}
MemOperand SlotToMemOperand(int slot) const {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
}
};
......@@ -1832,9 +1835,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ LoadP(dst, MemOperand(fp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ LoadP(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -89,8 +89,11 @@ class S390OperandConverter final : public InstructionOperandConverter {
MemOperand ToMemOperand(InstructionOperand* op) const {
DCHECK_NOT_NULL(op);
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToMemOperand(AllocatedOperand::cast(op)->index());
}
MemOperand SlotToMemOperand(int slot) {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
}
};
......@@ -1791,9 +1794,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ LoadP(dst, MemOperand(fp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ LoadP(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -49,8 +49,11 @@ class X64OperandConverter : public InstructionOperandConverter {
Operand ToOperand(InstructionOperand* op, int extra = 0) {
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return SlotToOperand(AllocatedOperand::cast(op)->index());
}
Operand SlotToOperand(int slot_index, int extra = 0) {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot_index);
return Operand(offset.from_stack_pointer() ? rsp : rbp,
offset.offset() + extra);
}
......@@ -2082,9 +2085,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int offset;
if (IsMaterializableFromFrame(src_object, &offset)) {
__ movp(dst, Operand(rbp, offset));
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ movp(dst, g.SlotToOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
......
......@@ -43,16 +43,13 @@ class X87OperandConverter : public InstructionOperandConverter {
return Operand(ToRegister(op));
}
DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
FrameOffset offset = frame_access_state()->GetFrameOffset(
AllocatedOperand::cast(op)->index());
return Operand(offset.from_stack_pointer() ? esp : ebp,
offset.offset() + extra);
return SlotToOperand(AllocatedOperand::cast(op)->index(), extra);
}
Operand ToMaterializableOperand(int materializable_offset) {
FrameOffset offset = frame_access_state()->GetFrameOffset(
FPOffsetToFrameSlot(materializable_offset));
return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset());
Operand SlotToOperand(int slot, int extra = 0) {
FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
return Operand(offset.from_stack_pointer() ? esp : ebp,
offset.offset() + extra);
}
Operand HighOperand(InstructionOperand* op) {
......@@ -2147,15 +2144,15 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
Constant src_constant = g.ToConstant(source);
if (src_constant.type() == Constant::kHeapObject) {
Handle<HeapObject> src = src_constant.ToHeapObject();
int offset;
if (IsMaterializableFromFrame(src, &offset)) {
int slot;
if (IsMaterializableFromFrame(src, &slot)) {
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ mov(dst, g.ToMaterializableOperand(offset));
__ mov(dst, g.SlotToOperand(slot));
} else {
DCHECK(destination->IsStackSlot());
Operand dst = g.ToOperand(destination);
__ push(g.ToMaterializableOperand(offset));
__ push(g.SlotToOperand(slot));
__ pop(dst);
}
} else if (destination->IsRegister()) {
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-tailcalls
"use strict";
function h(global) { return global.boom(); }
function g() { var r = h({}); return r; }
function f() {
var o = {};
o.__defineGetter__('prop1', g);
o.prop1;
}
assertThrows(f);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment