Commit 81f43429 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[turbofan] Remove bogus constant materialization from frame.

This removes an optimization from the code generator that tries to
materialize certain constants (i.e. context and closure) from the
stackframe when possible. This does not work with Harmony tail calls
which are split into several instructions. There have already been
numerous bugs in this optimization, it is too fragile in its current
form.

R=bmeurer@chromium.org
TEST=mjsunit/regress/regress-crbug-648539
BUG=chromium:648539

Review-Url: https://codereview.chromium.org/2357583003
Cr-Commit-Position: refs/heads/master@{#39583}
parent 3d97b804
......@@ -1820,10 +1820,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ ldr(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ Move(dst, src_object);
......
......@@ -1936,10 +1936,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
if (src.type() == Constant::kHeapObject) {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ Ldr(dst, g.SlotToMemOperand(slot, masm()));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ LoadObject(dst, src_object);
......
......@@ -281,21 +281,6 @@ void CodeGenerator::RecordSafepoint(ReferenceMap* references,
}
}
bool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object,
int* slot_return) {
if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
if (*object == info()->context() && !info()->is_osr()) {
*slot_return = Frame::kContextSlot;
return true;
} else if (object.is_identical_to(info()->closure())) {
*slot_return = Frame::kJSFunctionSlot;
return true;
}
}
return false;
}
bool CodeGenerator::IsMaterializableFromRoot(
Handle<HeapObject> object, Heap::RootListIndex* index_return) {
const CallDescriptor* incoming_descriptor =
......
......@@ -86,9 +86,6 @@ class CodeGenerator final : public GapResolver::Assembler {
void RecordSafepoint(ReferenceMap* references, Safepoint::Kind kind,
int arguments, Safepoint::DeoptMode deopt_mode);
// 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* 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.
......
......@@ -2037,18 +2037,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
Constant src_constant = g.ToConstant(source);
if (src_constant.type() == Constant::kHeapObject) {
Handle<HeapObject> src = src_constant.ToHeapObject();
int slot;
if (IsMaterializableFromFrame(src, &slot)) {
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ mov(dst, g.SlotToOperand(slot));
} else {
DCHECK(destination->IsStackSlot());
Operand dst = g.ToOperand(destination);
__ push(g.SlotToOperand(slot));
__ pop(dst);
}
} else if (destination->IsRegister()) {
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ LoadHeapObject(dst, src);
} else {
......
......@@ -2015,10 +2015,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ lw(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ li(dst, src_object);
......
......@@ -2338,10 +2338,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ ld(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ li(dst, src_object);
......
......@@ -2274,10 +2274,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ LoadP(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ Move(dst, src_object);
......
......@@ -2379,10 +2379,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ LoadP(dst, g.SlotToMemOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ Move(dst, src_object);
......
......@@ -2533,10 +2533,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
Heap::RootListIndex index;
int slot;
if (IsMaterializableFromFrame(src_object, &slot)) {
__ movp(dst, g.SlotToOperand(slot));
} else if (IsMaterializableFromRoot(src_object, &index)) {
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ Move(dst, src_object);
......
......@@ -2517,18 +2517,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
Constant src_constant = g.ToConstant(source);
if (src_constant.type() == Constant::kHeapObject) {
Handle<HeapObject> src = src_constant.ToHeapObject();
int slot;
if (IsMaterializableFromFrame(src, &slot)) {
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ mov(dst, g.SlotToOperand(slot));
} else {
DCHECK(destination->IsStackSlot());
Operand dst = g.ToOperand(destination);
__ push(g.SlotToOperand(slot));
__ pop(dst);
}
} else if (destination->IsRegister()) {
if (destination->IsRegister()) {
Register dst = g.ToRegister(destination);
__ LoadHeapObject(dst, src);
} else {
......
// 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: --allow-natives-syntax --harmony-tailcalls
function f() {
"use strict";
return undefined(0, 0);
}
function g() {
return f();
}
assertThrows(g, TypeError);
assertThrows(g, TypeError);
%OptimizeFunctionOnNextCall(g);
assertThrows(g, TypeError);
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