Commit e25a0f7e authored by titzer's avatar titzer Committed by Commit bot

[turbofan] Fix usage of ThisFunction parameter in OSR.

R=mstarzinger@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#26355}
parent 32fe247d
...@@ -35,9 +35,10 @@ struct ArmLinkageHelperTraits { ...@@ -35,9 +35,10 @@ struct ArmLinkageHelperTraits {
typedef LinkageHelper<ArmLinkageHelperTraits> LH; typedef LinkageHelper<ArmLinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, int parameter_count, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
return LH::GetJSCallDescriptor(zone, parameter_count, flags); return LH::GetJSCallDescriptor(zone, is_osr, parameter_count, flags);
} }
......
...@@ -35,9 +35,10 @@ struct Arm64LinkageHelperTraits { ...@@ -35,9 +35,10 @@ struct Arm64LinkageHelperTraits {
typedef LinkageHelper<Arm64LinkageHelperTraits> LH; typedef LinkageHelper<Arm64LinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, int parameter_count, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
return LH::GetJSCallDescriptor(zone, parameter_count, flags); return LH::GetJSCallDescriptor(zone, is_osr, parameter_count, flags);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/compiler.h" #include "src/compiler.h"
#include "src/compiler/ast-loop-assignment-analyzer.h" #include "src/compiler/ast-loop-assignment-analyzer.h"
#include "src/compiler/control-builders.h" #include "src/compiler/control-builders.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
...@@ -35,8 +36,8 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, ...@@ -35,8 +36,8 @@ AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
Node* AstGraphBuilder::GetFunctionClosure() { Node* AstGraphBuilder::GetFunctionClosure() {
if (!function_closure_.is_set()) { if (!function_closure_.is_set()) {
// Parameter -1 is special for the function closure const Operator* op =
const Operator* op = common()->Parameter(-1); common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex);
Node* node = NewNode(op, graph()->start()); Node* node = NewNode(op, graph()->start());
function_closure_.set(node); function_closure_.set(node);
} }
......
...@@ -315,11 +315,11 @@ const Operator* CommonOperatorBuilder::Parameter(int index) { ...@@ -315,11 +315,11 @@ const Operator* CommonOperatorBuilder::Parameter(int index) {
const Operator* CommonOperatorBuilder::OsrValue(int index) { const Operator* CommonOperatorBuilder::OsrValue(int index) {
return new (zone()) Operator1<int>( // -- return new (zone()) Operator1<int>( // --
IrOpcode::kOsrValue, Operator::kPure, // opcode IrOpcode::kOsrValue, Operator::kNoProperties, // opcode
"OsrValue", // name "OsrValue", // name
0, 0, 1, 1, 0, 0, // counts 0, 0, 1, 1, 0, 0, // counts
index); // parameter index); // parameter
} }
......
...@@ -30,9 +30,10 @@ struct IA32LinkageHelperTraits { ...@@ -30,9 +30,10 @@ struct IA32LinkageHelperTraits {
typedef LinkageHelper<IA32LinkageHelperTraits> LH; typedef LinkageHelper<IA32LinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, int parameter_count, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
return LH::GetJSCallDescriptor(zone, parameter_count, flags); return LH::GetJSCallDescriptor(zone, is_osr, parameter_count, flags);
} }
......
...@@ -410,8 +410,8 @@ bool JSGenericLowering::TryLowerDirectJSCall(Node* node) { ...@@ -410,8 +410,8 @@ bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
context = jsgraph()->HeapConstant(Handle<Context>(function->context())); context = jsgraph()->HeapConstant(Handle<Context>(function->context()));
} }
node->ReplaceInput(index, context); node->ReplaceInput(index, context);
CallDescriptor* desc = linkage()->GetJSCallDescriptor( CallDescriptor* desc =
jsgraph()->zone(), 1 + arg_count, FlagsForNode(node)); linkage()->GetJSCallDescriptor(1 + arg_count, FlagsForNode(node));
PatchOperator(node, common()->Call(desc)); PatchOperator(node, common()->Call(desc));
return true; return true;
} }
......
...@@ -29,7 +29,8 @@ class LinkageHelper { ...@@ -29,7 +29,8 @@ class LinkageHelper {
} }
// TODO(turbofan): cache call descriptors for JSFunction calls. // TODO(turbofan): cache call descriptors for JSFunction calls.
static CallDescriptor* GetJSCallDescriptor(Zone* zone, int js_parameter_count, static CallDescriptor* GetJSCallDescriptor(Zone* zone, bool is_osr,
int js_parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
const size_t return_count = 1; const size_t return_count = 1;
const size_t context_count = 1; const size_t context_count = 1;
...@@ -56,7 +57,12 @@ class LinkageHelper { ...@@ -56,7 +57,12 @@ class LinkageHelper {
// The target for JS function calls is the JSFunction object. // The target for JS function calls is the JSFunction object.
MachineType target_type = kMachAnyTagged; MachineType target_type = kMachAnyTagged;
LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg()); // Unoptimized code doesn't preserve the JSCallFunctionReg, so expect the
// closure on the stack.
LinkageLocation target_loc =
is_osr ? stackloc(Linkage::kJSFunctionCallClosureParamIndex -
js_parameter_count)
: regloc(LinkageTraits::JSCallFunctionReg());
return new (zone) CallDescriptor( // -- return new (zone) CallDescriptor( // --
CallDescriptor::kCallJSFunction, // kind CallDescriptor::kCallJSFunction, // kind
target_type, // target MachineType target_type, // target MachineType
......
...@@ -42,14 +42,16 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) { ...@@ -42,14 +42,16 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
if (info->function() != NULL) { if (info->function() != NULL) {
// If we already have the function literal, use the number of parameters // If we already have the function literal, use the number of parameters
// plus the receiver. // plus the receiver.
return GetJSCallDescriptor(zone, 1 + info->function()->parameter_count(), return GetJSCallDescriptor(zone, info->is_osr(),
1 + info->function()->parameter_count(),
CallDescriptor::kNoFlags); CallDescriptor::kNoFlags);
} }
if (!info->closure().is_null()) { if (!info->closure().is_null()) {
// If we are compiling a JS function, use a JS call descriptor, // If we are compiling a JS function, use a JS call descriptor,
// plus the receiver. // plus the receiver.
SharedFunctionInfo* shared = info->closure()->shared(); SharedFunctionInfo* shared = info->closure()->shared();
return GetJSCallDescriptor(zone, 1 + shared->formal_parameter_count(), return GetJSCallDescriptor(zone, info->is_osr(),
1 + shared->formal_parameter_count(),
CallDescriptor::kNoFlags); CallDescriptor::kNoFlags);
} }
if (info->code_stub() != NULL) { if (info->code_stub() != NULL) {
...@@ -94,7 +96,7 @@ FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame, ...@@ -94,7 +96,7 @@ FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame,
CallDescriptor* Linkage::GetJSCallDescriptor( CallDescriptor* Linkage::GetJSCallDescriptor(
int parameter_count, CallDescriptor::Flags flags) const { int parameter_count, CallDescriptor::Flags flags) const {
return GetJSCallDescriptor(zone_, parameter_count, flags); return GetJSCallDescriptor(zone_, false, parameter_count, flags);
} }
...@@ -232,7 +234,7 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) { ...@@ -232,7 +234,7 @@ bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
// Provide unimplemented methods on unsupported architectures, to at least link. // Provide unimplemented methods on unsupported architectures, to at least link.
//============================================================================== //==============================================================================
#if !V8_TURBOFAN_BACKEND #if !V8_TURBOFAN_BACKEND
CallDescriptor* Linkage::GetJSCallDescriptor(Isolate* isolate, Zone* zone, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count, int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
UNIMPLEMENTED(); UNIMPLEMENTED();
...@@ -247,17 +249,17 @@ LinkageLocation Linkage::GetOsrValueLocation(int index) const { ...@@ -247,17 +249,17 @@ LinkageLocation Linkage::GetOsrValueLocation(int index) const {
CallDescriptor* Linkage::GetRuntimeCallDescriptor( CallDescriptor* Linkage::GetRuntimeCallDescriptor(
Runtime::FunctionId function, int parameter_count, Zone* zone, Runtime::FunctionId function, int parameter_count,
Operator::Properties properties, Zone* zone) { Operator::Properties properties) {
UNIMPLEMENTED(); UNIMPLEMENTED();
return NULL; return NULL;
} }
CallDescriptor* Linkage::GetStubCallDescriptor( CallDescriptor* Linkage::GetStubCallDescriptor(
const CallInterfaceDescriptor& descriptor, int stack_parameter_count, Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
CallDescriptor::Flags flags, Operator::Properties properties, int stack_parameter_count, CallDescriptor::Flags flags,
Zone* zone) { Operator::Properties properties) {
UNIMPLEMENTED(); UNIMPLEMENTED();
return NULL; return NULL;
} }
......
...@@ -185,7 +185,8 @@ class Linkage : public ZoneObject { ...@@ -185,7 +185,8 @@ class Linkage : public ZoneObject {
CallDescriptor* GetIncomingDescriptor() const { return incoming_; } CallDescriptor* GetIncomingDescriptor() const { return incoming_; }
CallDescriptor* GetJSCallDescriptor(int parameter_count, CallDescriptor* GetJSCallDescriptor(int parameter_count,
CallDescriptor::Flags flags) const; CallDescriptor::Flags flags) const;
static CallDescriptor* GetJSCallDescriptor(Zone* zone, int parameter_count, static CallDescriptor* GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags); CallDescriptor::Flags flags);
CallDescriptor* GetRuntimeCallDescriptor( CallDescriptor* GetRuntimeCallDescriptor(
Runtime::FunctionId function, int parameter_count, Runtime::FunctionId function, int parameter_count,
...@@ -240,6 +241,9 @@ class Linkage : public ZoneObject { ...@@ -240,6 +241,9 @@ class Linkage : public ZoneObject {
// Get the location where an incoming OSR value is stored. // Get the location where an incoming OSR value is stored.
LinkageLocation GetOsrValueLocation(int index) const; LinkageLocation GetOsrValueLocation(int index) const;
// A special parameter index for JSCalls that represents the closure.
static const int kJSFunctionCallClosureParamIndex = -1;
private: private:
Isolate* isolate_; Isolate* isolate_;
Zone* const zone_; Zone* const zone_;
......
...@@ -35,9 +35,10 @@ struct MipsLinkageHelperTraits { ...@@ -35,9 +35,10 @@ struct MipsLinkageHelperTraits {
typedef LinkageHelper<MipsLinkageHelperTraits> LH; typedef LinkageHelper<MipsLinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, int parameter_count, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
return LH::GetJSCallDescriptor(zone, parameter_count, flags); return LH::GetJSCallDescriptor(zone, is_osr, parameter_count, flags);
} }
......
...@@ -35,9 +35,10 @@ struct MipsLinkageHelperTraits { ...@@ -35,9 +35,10 @@ struct MipsLinkageHelperTraits {
typedef LinkageHelper<MipsLinkageHelperTraits> LH; typedef LinkageHelper<MipsLinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, int parameter_count, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
return LH::GetJSCallDescriptor(zone, parameter_count, flags); return LH::GetJSCallDescriptor(zone, is_osr, parameter_count, flags);
} }
......
...@@ -99,8 +99,8 @@ Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver, ...@@ -99,8 +99,8 @@ Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver,
Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver, Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver,
Node* context, Node* frame_state) { Node* context, Node* frame_state) {
CallDescriptor* descriptor = CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(
Linkage::GetJSCallDescriptor(zone(), 1, CallDescriptor::kNeedsFrameState); zone(), false, 1, CallDescriptor::kNeedsFrameState);
Node* call = graph()->NewNode(common()->Call(descriptor), function, receiver, Node* call = graph()->NewNode(common()->Call(descriptor), function, receiver,
context, frame_state); context, frame_state);
schedule()->AddNode(CurrentBlock(), call); schedule()->AddNode(CurrentBlock(), call);
......
...@@ -49,9 +49,10 @@ struct X64LinkageHelperTraits { ...@@ -49,9 +49,10 @@ struct X64LinkageHelperTraits {
typedef LinkageHelper<X64LinkageHelperTraits> LH; typedef LinkageHelper<X64LinkageHelperTraits> LH;
CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, int parameter_count, CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
int parameter_count,
CallDescriptor::Flags flags) { CallDescriptor::Flags flags) {
return LH::GetJSCallDescriptor(zone, parameter_count, flags); return LH::GetJSCallDescriptor(zone, is_osr, parameter_count, flags);
} }
......
// Copyright 2015 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: --use-osr --turbo-osr
function foo(a) {
var sum = 0;
var inc = a ? 100 : 200;
for (var i = 0; i < 100000; i++) {
sum += inc;
}
return sum + inc;
}
function bar(a) {
var sum = 0;
var inc = a ? 100 : 200;
var x = a ? 5 : 6;
var y = a ? 7 : 8;
for (var i = 0; i < 100000; i++) {
sum += inc;
}
return sum ? x : y;
}
function baz(a) {
var limit = a ? 100001 : 100002;
var r = 1;
var x = a ? 1 : 2;
var y = a ? 3 : 4;
for (var i = 0; i < limit; i++) {
r = r * -1;
}
return r > 0 ? x == y : x != y;
}
function qux(a) {
var limit = a ? 100001 : 100002;
var r = 1;
var x = a ? 1 : 2;
var y = a ? 3 : 4;
for (var i = 0; i < limit; i++) {
r = r * -1;
}
var w = r > 0 ? x : y;
var z = r > 0 ? y : x;
return w === z;
}
function test(func, tv, fv) {
assertEquals(tv, func(true));
assertEquals(fv, func(false));
assertEquals(tv, func(true));
assertEquals(fv, func(false));
}
test(foo, 10000100, 20000200);
test(bar, 5, 6);
test(baz, true, false);
test(qux, false, false);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --use-osr --turbo-osr // Flags: --use-osr --turbo-osr
function f(a) { function f(a) {
var sum = 0; var sum = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --use-osr --turbo-osr // Flags: --use-osr --turbo-osr
function f(a) { function f(a) {
var sum = 0; var sum = 0;
......
// Copyright 2015 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: --use-osr --turbo-osr
function id(f) { return f; }
function foo() {
var sum = 0;
var r = id(foo);
for (var i = 0; i < 100000; i++) {
sum += i;
}
return foo == r;
}
assertEquals(true, foo());
assertEquals(true, foo());
assertEquals(true, foo());
function bar() {
var sum = 0;
for (var i = 0; i < 90000; i++) {
sum += i;
}
return id(bar,sum);
}
assertEquals(bar, bar());
assertEquals(bar, bar());
assertEquals(bar, bar());
// Copyright 2015 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: --use-osr --turbo-osr
function id(f) { return f; }
var x = (function foo() {
var sum = 0;
var r = id(foo);
for (var i = 0; i < 100000; i++) {
sum += i;
}
return foo == r;
})();
assertEquals(true, x);
var x = (function bar() {
var sum = 0;
for (var i = 0; i < 90000; i++) {
sum += i;
}
return bar;
})();
assertEquals("function", typeof x);
// Copyright 2015 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: --use-osr --turbo-osr
function foo() {
var sum = 0;
for (var i = 0; i < 100000; i++) {
sum += i;
}
return function() { return sum; }
}
assertEquals(4999950000, foo()());
assertEquals(4999950000, foo()());
assertEquals(4999950000, foo()());
function bar() {
var sum = 0;
var ret = 0;
for (var i = 0; i < 90000; i++) {
sum += i;
if (i == 0) ret = function() { return sum; }
}
return ret;
}
assertEquals(4049955000, bar()());
assertEquals(4049955000, bar()());
assertEquals(4049955000, bar()());
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --use-osr --turbo-osr // Flags: --use-osr --turbo-osr
function f() { function f() {
var sum = 0; var sum = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax --use-osr --turbo-osr // Flags: --use-osr --turbo-osr
function f() { function f() {
var sum = 0; var sum = 0;
......
// Copyright 2015 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 --use-osr --turbo-osr
function id(f) { return f; }
function foo(a) {
var r = /\0/;
for (var i = 0; i < 10; i++) {
if (a) %OptimizeFunctionOnNextCall(foo, "osr");
}
return r;
}
function bar(a) {
for (var i = 0; i < 10; i++) {
if (a) %OptimizeFunctionOnNextCall(bar, "osr");
var r = /\0/;
}
return r;
}
function baz(a) {
for (var i = 0; i < 10; i++) {
if (a) %OptimizeFunctionOnNextCall(baz, "osr");
}
return /\0/;
}
function qux(a) {
for (var i = 0; i < 10; i++) {
if (i > 5 && a) {
%OptimizeFunctionOnNextCall(qux, "osr");
} else {
var r = /\0/;
}
}
return r;
}
function test(f) {
// Test the reference equality of regex's created in OSR'd function.
var x = f(false);
assertEquals(x, f(true));
assertEquals(x, f(true));
assertEquals(x, f(true));
}
test(foo);
test(bar);
test(baz);
test(qux);
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