Introduce %IsBeingInterpreted

A call to this intrinsic will produce true in the interpreter and false
in optimized code. This is useful for writing tests.

Change-Id: I64d06ed062027e723eca82d6f879202244f21fdf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1939750
Commit-Queue: Georg Neis <neis@chromium.org>
Auto-Submit: Georg Neis <neis@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65240}
This commit is contained in:
Georg Neis 2019-11-28 10:23:19 +01:00 committed by Commit Bot
parent 5115bea224
commit 9ac62c4dcc
9 changed files with 77 additions and 9 deletions

View File

@ -31,8 +31,12 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
const Runtime::Function* const f =
Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
if (f->function_id == Runtime::kTurbofanStaticAssert)
if (f->function_id == Runtime::kTurbofanStaticAssert) {
return ReduceTurbofanStaticAssert(node);
}
if (f->function_id == Runtime::kIsBeingInterpreted) {
return ReduceIsBeingInterpreted(node);
}
if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
switch (f->function_id) {
case Runtime::kInlineCopyDataProperties:
@ -284,6 +288,11 @@ Reduction JSIntrinsicLowering::ReduceTurbofanStaticAssert(Node* node) {
return Changed(jsgraph_->UndefinedConstant());
}
Reduction JSIntrinsicLowering::ReduceIsBeingInterpreted(Node* node) {
RelaxEffectsAndControls(node);
return Changed(jsgraph_->FalseConstant());
}
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
// Replace all effect uses of {node} with the effect dependency.
RelaxEffectsAndControls(node);

View File

@ -58,6 +58,7 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
Reduction ReduceIsJSReceiver(Node* node);
Reduction ReduceIsSmi(Node* node);
Reduction ReduceIsBeingInterpreted(Node* node);
Reduction ReduceTurbofanStaticAssert(Node* node);
Reduction ReduceToLength(Node* node);
Reduction ReduceToObject(Node* node);

View File

@ -1413,11 +1413,17 @@ RUNTIME_FUNCTION(Runtime_FreezeWasmLazyCompilation) {
RUNTIME_FUNCTION(Runtime_TurbofanStaticAssert) {
SealHandleScope shs(isolate);
// Always lowered to StaticAssert node in Turbofan, so we should never get
// here in compiled code.
// Always lowered to StaticAssert node in Turbofan, so we never get here in
// compiled code.
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_IsBeingInterpreted) {
SealHandleScope shs(isolate);
// Always lowered to false in Turbofan, so we never get here in compiled code.
return ReadOnlyRoots(isolate).true_value();
}
RUNTIME_FUNCTION(Runtime_EnableCodeLoggingForTesting) {
// The {NoopListener} currently does nothing on any callback, but reports
// {true} on {is_listening_to_code_events()}. Feel free to add assertions to

View File

@ -33,7 +33,7 @@ namespace internal {
// * Each compiler has an explicit list of intrisics it supports, falling back
// to a simple runtime call if necessary.
// Entries have the form F(name, number of arguments, number of values):
// Entries have the form F(name, number of arguments, number of return values):
// A variable number of arguments is specified by a -1, additional restrictions
// are specified by inline comments. To declare only the runtime version (no
// inline), use the F macro below. To declare the runtime version and the inline
@ -500,6 +500,7 @@ namespace internal {
F(ICsAreEnabled, 0, 1) \
F(InYoungGeneration, 1, 1) \
F(IsAsmWasmCode, 1, 1) \
F(IsBeingInterpreted, 0, 1) \
F(IsConcurrentRecompilationSupported, 0, 1) \
F(IsLiftoffFunction, 1, 1) \
F(IsThreadInWasm, 0, 1) \

View File

@ -0,0 +1,17 @@
// Copyright 2019 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 --opt --no-always-opt
function bar() { return foo(); }
function foo() { return %IsBeingInterpreted(); }
%PrepareFunctionForOptimization(bar);
%PrepareFunctionForOptimization(foo);
assertTrue(bar());
assertTrue(bar());
%OptimizeFunctionOnNextCall(bar);
assertFalse(bar());

View File

@ -0,0 +1,17 @@
// Copyright 2019 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 --no-turbo-inlining --opt --no-always-opt
function bar() { return foo(); }
function foo() { return %IsBeingInterpreted(); }
%PrepareFunctionForOptimization(bar);
%PrepareFunctionForOptimization(foo);
assertTrue(bar());
assertTrue(bar());
%OptimizeFunctionOnNextCall(bar);
assertTrue(bar());

View File

@ -2,13 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --opt --no-always-opt
var expect_interpreted = true;
class C {
get prop() {
return 42;
}
set prop(v) {
assertEquals(expect_interpreted, %IsBeingInterpreted());
%TurbofanStaticAssert(v === 43);
}
}
@ -16,6 +19,7 @@ class C {
const c = new C();
function foo() {
assertEquals(expect_interpreted, %IsBeingInterpreted());
%TurbofanStaticAssert(c.prop === 42);
c.prop = 43;
}
@ -25,7 +29,9 @@ function foo() {
%PrepareFunctionForOptimization(
Object.getOwnPropertyDescriptor(C.prototype, 'prop').set);
%PrepareFunctionForOptimization(foo);
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
expect_interpreted = false;
foo();

View File

@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --opt --no-always-opt
var expect_interpreted = true;
function C() {
this.a = 1;
assertEquals(expect_interpreted, %IsBeingInterpreted());
%TurbofanStaticAssert(this.x == 42);
};
@ -47,4 +50,5 @@ new G;
foo();
foo();
%OptimizeFunctionOnNextCall(foo);
expect_interpreted = false;
foo();

View File

@ -404,6 +404,11 @@
'regexp-tier-up-multiple': [SKIP],
'regress/regress-996234': [SKIP],
# Tests that depend on optimization (beyond doing assertOptimized).
'compiler/is-being-interpreted-*': [SKIP],
'compiler/serializer-accessors': [SKIP],
'compiler/serializer-transition-propagation': [SKIP],
# These tests check that we can trace the compiler.
'tools/compiler-trace-flags': [SKIP],
'tools/compiler-trace-flags-wasm': [SKIP],
@ -1082,11 +1087,13 @@
# phases.
'compiler/concurrent-inlining-1': [SKIP],
'compiler/concurrent-inlining-2': [SKIP],
'compiler/diamond-followedby-branch': [SKIP],
'compiler/load-elimination-const-field': [SKIP],
'compiler/constant-fold-add-static': [SKIP],
'compiler/serializer-feedback-propagation-*': [SKIP],
'compiler/diamond-followedby-branch': [SKIP],
'compiler/is-being-interpreted-*': [SKIP],
'compiler/load-elimination-const-field': [SKIP],
'compiler/serializer-accessors': [SKIP],
'compiler/serializer-feedback-propagation-*': [SKIP],
'compiler/serializer-transition-propagation': [SKIP],
# Some tests rely on inlining.
'compiler/opt-higher-order-functions': [SKIP],