Commit 9ac62c4d authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

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: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65240}
parent 5115bea2
...@@ -31,8 +31,12 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) { ...@@ -31,8 +31,12 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange(); if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
const Runtime::Function* const f = const Runtime::Function* const f =
Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id()); Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
if (f->function_id == Runtime::kTurbofanStaticAssert) if (f->function_id == Runtime::kTurbofanStaticAssert) {
return ReduceTurbofanStaticAssert(node); return ReduceTurbofanStaticAssert(node);
}
if (f->function_id == Runtime::kIsBeingInterpreted) {
return ReduceIsBeingInterpreted(node);
}
if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange(); if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
switch (f->function_id) { switch (f->function_id) {
case Runtime::kInlineCopyDataProperties: case Runtime::kInlineCopyDataProperties:
...@@ -284,6 +288,11 @@ Reduction JSIntrinsicLowering::ReduceTurbofanStaticAssert(Node* node) { ...@@ -284,6 +288,11 @@ Reduction JSIntrinsicLowering::ReduceTurbofanStaticAssert(Node* node) {
return Changed(jsgraph_->UndefinedConstant()); return Changed(jsgraph_->UndefinedConstant());
} }
Reduction JSIntrinsicLowering::ReduceIsBeingInterpreted(Node* node) {
RelaxEffectsAndControls(node);
return Changed(jsgraph_->FalseConstant());
}
Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) { Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
// Replace all effect uses of {node} with the effect dependency. // Replace all effect uses of {node} with the effect dependency.
RelaxEffectsAndControls(node); RelaxEffectsAndControls(node);
......
...@@ -58,6 +58,7 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final ...@@ -58,6 +58,7 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type); Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
Reduction ReduceIsJSReceiver(Node* node); Reduction ReduceIsJSReceiver(Node* node);
Reduction ReduceIsSmi(Node* node); Reduction ReduceIsSmi(Node* node);
Reduction ReduceIsBeingInterpreted(Node* node);
Reduction ReduceTurbofanStaticAssert(Node* node); Reduction ReduceTurbofanStaticAssert(Node* node);
Reduction ReduceToLength(Node* node); Reduction ReduceToLength(Node* node);
Reduction ReduceToObject(Node* node); Reduction ReduceToObject(Node* node);
......
...@@ -1413,11 +1413,17 @@ RUNTIME_FUNCTION(Runtime_FreezeWasmLazyCompilation) { ...@@ -1413,11 +1413,17 @@ RUNTIME_FUNCTION(Runtime_FreezeWasmLazyCompilation) {
RUNTIME_FUNCTION(Runtime_TurbofanStaticAssert) { RUNTIME_FUNCTION(Runtime_TurbofanStaticAssert) {
SealHandleScope shs(isolate); SealHandleScope shs(isolate);
// Always lowered to StaticAssert node in Turbofan, so we should never get // Always lowered to StaticAssert node in Turbofan, so we never get here in
// here in compiled code. // compiled code.
return ReadOnlyRoots(isolate).undefined_value(); 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) { RUNTIME_FUNCTION(Runtime_EnableCodeLoggingForTesting) {
// The {NoopListener} currently does nothing on any callback, but reports // The {NoopListener} currently does nothing on any callback, but reports
// {true} on {is_listening_to_code_events()}. Feel free to add assertions to // {true} on {is_listening_to_code_events()}. Feel free to add assertions to
......
...@@ -33,7 +33,7 @@ namespace internal { ...@@ -33,7 +33,7 @@ namespace internal {
// * Each compiler has an explicit list of intrisics it supports, falling back // * Each compiler has an explicit list of intrisics it supports, falling back
// to a simple runtime call if necessary. // 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 // A variable number of arguments is specified by a -1, additional restrictions
// are specified by inline comments. To declare only the runtime version (no // 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 // inline), use the F macro below. To declare the runtime version and the inline
...@@ -500,6 +500,7 @@ namespace internal { ...@@ -500,6 +500,7 @@ namespace internal {
F(ICsAreEnabled, 0, 1) \ F(ICsAreEnabled, 0, 1) \
F(InYoungGeneration, 1, 1) \ F(InYoungGeneration, 1, 1) \
F(IsAsmWasmCode, 1, 1) \ F(IsAsmWasmCode, 1, 1) \
F(IsBeingInterpreted, 0, 1) \
F(IsConcurrentRecompilationSupported, 0, 1) \ F(IsConcurrentRecompilationSupported, 0, 1) \
F(IsLiftoffFunction, 1, 1) \ F(IsLiftoffFunction, 1, 1) \
F(IsThreadInWasm, 0, 1) \ F(IsThreadInWasm, 0, 1) \
......
// 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());
// 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());
...@@ -2,13 +2,16 @@ ...@@ -2,13 +2,16 @@
// 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 // Flags: --allow-natives-syntax --opt --no-always-opt
var expect_interpreted = true;
class C { class C {
get prop() { get prop() {
return 42; return 42;
} }
set prop(v) { set prop(v) {
assertEquals(expect_interpreted, %IsBeingInterpreted());
%TurbofanStaticAssert(v === 43); %TurbofanStaticAssert(v === 43);
} }
} }
...@@ -16,6 +19,7 @@ class C { ...@@ -16,6 +19,7 @@ class C {
const c = new C(); const c = new C();
function foo() { function foo() {
assertEquals(expect_interpreted, %IsBeingInterpreted());
%TurbofanStaticAssert(c.prop === 42); %TurbofanStaticAssert(c.prop === 42);
c.prop = 43; c.prop = 43;
} }
...@@ -25,7 +29,9 @@ function foo() { ...@@ -25,7 +29,9 @@ function foo() {
%PrepareFunctionForOptimization( %PrepareFunctionForOptimization(
Object.getOwnPropertyDescriptor(C.prototype, 'prop').set); Object.getOwnPropertyDescriptor(C.prototype, 'prop').set);
%PrepareFunctionForOptimization(foo); %PrepareFunctionForOptimization(foo);
foo(); foo();
foo(); foo();
%OptimizeFunctionOnNextCall(foo); %OptimizeFunctionOnNextCall(foo);
expect_interpreted = false;
foo(); foo();
...@@ -2,10 +2,13 @@ ...@@ -2,10 +2,13 @@
// 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 // Flags: --allow-natives-syntax --opt --no-always-opt
var expect_interpreted = true;
function C() { function C() {
this.a = 1; this.a = 1;
assertEquals(expect_interpreted, %IsBeingInterpreted());
%TurbofanStaticAssert(this.x == 42); %TurbofanStaticAssert(this.x == 42);
}; };
...@@ -47,4 +50,5 @@ new G; ...@@ -47,4 +50,5 @@ new G;
foo(); foo();
foo(); foo();
%OptimizeFunctionOnNextCall(foo); %OptimizeFunctionOnNextCall(foo);
expect_interpreted = false;
foo(); foo();
...@@ -404,6 +404,11 @@ ...@@ -404,6 +404,11 @@
'regexp-tier-up-multiple': [SKIP], 'regexp-tier-up-multiple': [SKIP],
'regress/regress-996234': [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. # These tests check that we can trace the compiler.
'tools/compiler-trace-flags': [SKIP], 'tools/compiler-trace-flags': [SKIP],
'tools/compiler-trace-flags-wasm': [SKIP], 'tools/compiler-trace-flags-wasm': [SKIP],
...@@ -1082,11 +1087,13 @@ ...@@ -1082,11 +1087,13 @@
# phases. # phases.
'compiler/concurrent-inlining-1': [SKIP], 'compiler/concurrent-inlining-1': [SKIP],
'compiler/concurrent-inlining-2': [SKIP], 'compiler/concurrent-inlining-2': [SKIP],
'compiler/constant-fold-add-static': [SKIP],
'compiler/diamond-followedby-branch': [SKIP], 'compiler/diamond-followedby-branch': [SKIP],
'compiler/is-being-interpreted-*': [SKIP],
'compiler/load-elimination-const-field': [SKIP], 'compiler/load-elimination-const-field': [SKIP],
'compiler/constant-fold-add-static': [SKIP],
'compiler/serializer-feedback-propagation-*': [SKIP],
'compiler/serializer-accessors': [SKIP], 'compiler/serializer-accessors': [SKIP],
'compiler/serializer-feedback-propagation-*': [SKIP],
'compiler/serializer-transition-propagation': [SKIP],
# Some tests rely on inlining. # Some tests rely on inlining.
'compiler/opt-higher-order-functions': [SKIP], 'compiler/opt-higher-order-functions': [SKIP],
......
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