Skip to content

Commit 7555f5f

Browse files
sstricklcommit-bot@chromium.org
authored andcommitted
Revert "[vm/compiler] Move AssertAssignables out of closure bodies."
This reverts commit 42c76fd. Reason for revert: Failures in flutter/google3. Initial hypothesis is related to product mode and instruction deduplication. Original change's description: > [vm/compiler] Move AssertAssignables out of closure bodies. > > This CL moves the final set of checks out of closure bodies and into > dynamic closure call dispatchers. It also adds stubs for checking top > types and null assignability for types only known at runtime. > > Fixes #40813 . > > Changes in Flutter gallery in release mode: > > * arm7: -3.05% total, +0.99% vmisolate, -0.89% isolate, > -1.20% readonly, -4.43% instructions > * arm8: -3.20% total, +0.99% vmisolate, -0.88% isolate, > -1.18% readonly, -5.05% instructions > > TEST=Run on trybots of all architectures, includes test adjustments where needed. > > Cq-Include-Trybots: luci.dart.try:vm-kernel-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-nnbd-linux-debug-ia32-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-nnbd-linux-debug-simarm_x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-linux-release-simarm-try,vm-kernel-linux-release-simarm64-try,vm-kernel-nnbd-linux-release-simarm-try,vm-kernel-nnbd-linux-release-simarm64-try,vm-kernel-precomp-linux-release-simarm-try,vm-kernel-precomp-linux-release-simarm64-try,vm-kernel-precomp-nnbd-linux-release-simarm64-try > Change-Id: Ifb136c64339be76a642ecbb4fda26b6ce8f871f9 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166622 > Commit-Queue: Tess Strickland <[email protected]> > Reviewed-by: Martin Kustermann <[email protected]> > Reviewed-by: Régis Crelier <[email protected]> [email protected],[email protected],[email protected] Change-Id: Iaf79acddcf18fb3699a894950b31515d6f759349 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/172643 Commit-Queue: Tess Strickland <[email protected]> Reviewed-by: Tess Strickland <[email protected]>
1 parent 19b4eae commit 7555f5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+609
-777
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// No type checks are removed here, but we can skip the argument count check.
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
8+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
9+
10+
import "package:expect/expect.dart";
11+
import "common.dart";
12+
13+
class C<T> {
14+
@NeverInline
15+
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
16+
@pragma("vm:entry-point")
17+
void samir1(T x) {
18+
if (x == -1) {
19+
throw "oh no";
20+
}
21+
}
22+
}
23+
24+
void run(void Function(int) test, int i) {
25+
test(i);
26+
}
27+
28+
main(List<String> args) {
29+
var c = new C<int>();
30+
var f = c.samir1;
31+
32+
const int iterations = benchmarkMode ? 100000000 : 100;
33+
for (int i = 0; i < iterations; ++i) {
34+
run(f, i);
35+
}
36+
37+
entryPoint.expectChecked(iterations);
38+
tearoffEntryPoint.expectUnchecked(iterations);
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
8+
9+
// Test that typed calls against tearoffs go into the unchecked entrypoint.
10+
11+
import "package:expect/expect.dart";
12+
import "common.dart";
13+
14+
class C<T> {
15+
@NeverInline
16+
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
17+
@pragma("vm:entry-point")
18+
void target1(T x, String y) {
19+
Expect.notEquals(x, -1);
20+
Expect.equals(y, "foo");
21+
}
22+
}
23+
24+
void run(void Function(int, String) fn, int i) {
25+
fn(i, "foo");
26+
}
27+
28+
main(List<String> args) {
29+
var f = (new C<int>()).target1;
30+
31+
const int iterations = benchmarkMode ? 100000000 : 100;
32+
for (int i = 0; i < iterations; ++i) {
33+
run(f, i);
34+
}
35+
36+
entryPoint.expectChecked(iterations);
37+
tearoffEntryPoint.expectUnchecked(iterations);
38+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// No type checks are removed here, but we can skip the argument count check.
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
8+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
9+
10+
import "package:expect/expect.dart";
11+
import "common.dart";
12+
13+
class C<T> {
14+
@NeverInline
15+
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
16+
@pragma("vm:entry-point")
17+
void samir1(T x) {
18+
if (x == -1) {
19+
throw "oh no";
20+
}
21+
}
22+
}
23+
24+
void run(void Function(int) test, int i) {
25+
test(i);
26+
}
27+
28+
main(List<String> args) {
29+
var c = new C<int>();
30+
var f = c.samir1;
31+
32+
const int iterations = benchmarkMode ? 100000000 : 100;
33+
for (int i = 0; i < iterations; ++i) {
34+
run(f, i);
35+
}
36+
37+
entryPoint.expectChecked(iterations);
38+
tearoffEntryPoint.expectUnchecked(iterations);
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10
6+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=10 -Denable_inlining=true
7+
// VMOptions=--enable-testing-pragmas --no-background-compilation --optimization-counter-threshold=-1
8+
9+
// Test that typed calls against tearoffs go into the unchecked entrypoint.
10+
11+
import "package:expect/expect.dart";
12+
import "common.dart";
13+
14+
class C<T> {
15+
@NeverInline
16+
@pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
17+
@pragma("vm:entry-point")
18+
void target1(T x, String y) {
19+
Expect.notEquals(x, -1);
20+
Expect.equals(y, "foo");
21+
}
22+
}
23+
24+
void run(void Function(int, String) fn, int i) {
25+
fn(i, "foo");
26+
}
27+
28+
main(List<String> args) {
29+
var f = (new C<int>()).target1;
30+
31+
const int iterations = benchmarkMode ? 100000000 : 100;
32+
for (int i = 0; i < iterations; ++i) {
33+
run(f, i);
34+
}
35+
36+
entryPoint.expectChecked(iterations);
37+
tearoffEntryPoint.expectUnchecked(iterations);
38+
}

runtime/vm/compiler/assembler/assembler_arm.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,12 +1023,6 @@ class Assembler : public AssemblerBase {
10231023
JumpDistance distance = kFarJump) {
10241024
b(label, condition);
10251025
}
1026-
void BranchIfZero(Register rn,
1027-
Label* label,
1028-
JumpDistance distance = kFarJump) {
1029-
cmp(rn, Operand(0));
1030-
b(label, ZERO);
1031-
}
10321026

10331027
void MoveRegister(Register rd, Register rm, Condition cond = AL);
10341028

runtime/vm/compiler/assembler/assembler_arm64.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,11 +1109,6 @@ class Assembler : public AssemblerBase {
11091109
JumpDistance distance = kFarJump) {
11101110
b(label, condition);
11111111
}
1112-
void BranchIfZero(Register rn,
1113-
Label* label,
1114-
JumpDistance distance = kFarJump) {
1115-
cbz(label, rn);
1116-
}
11171112

11181113
void cbz(Label* label, Register rt, OperandSize sz = kEightBytes) {
11191114
EmitCompareAndBranch(CBZ, rt, label, sz);

runtime/vm/compiler/assembler/assembler_ia32.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,12 +1784,10 @@ void Assembler::LoadFromOffset(Register reg,
17841784
}
17851785

17861786
void Assembler::LoadFromStack(Register dst, intptr_t depth) {
1787-
ASSERT(depth >= 0);
17881787
movl(dst, Address(ESP, depth * target::kWordSize));
17891788
}
17901789

17911790
void Assembler::StoreToStack(Register src, intptr_t depth) {
1792-
ASSERT(depth >= 0);
17931791
movl(Address(ESP, depth * target::kWordSize), src);
17941792
}
17951793

runtime/vm/compiler/assembler/assembler_ia32.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -577,12 +577,6 @@ class Assembler : public AssemblerBase {
577577
JumpDistance distance = kFarJump) {
578578
j(condition, label, distance);
579579
}
580-
void BranchIfZero(Register src,
581-
Label* label,
582-
JumpDistance distance = kFarJump) {
583-
cmpl(src, Immediate(0));
584-
j(ZERO, label, distance);
585-
}
586580

587581
void LoadFromOffset(Register reg,
588582
Register base,
@@ -722,11 +716,6 @@ class Assembler : public AssemblerBase {
722716
cmpxchgl(address, reg);
723717
}
724718

725-
void CompareTypeNullabilityWith(Register type, int8_t value) {
726-
cmpb(FieldAddress(type, compiler::target::Type::nullability_offset()),
727-
Immediate(value));
728-
}
729-
730719
void EnterFrame(intptr_t frame_space);
731720
void LeaveFrame();
732721
void ReserveAlignedFrameSpace(intptr_t frame_space);

runtime/vm/compiler/assembler/assembler_x64.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -683,12 +683,6 @@ class Assembler : public AssemblerBase {
683683
JumpDistance distance = kFarJump) {
684684
j(condition, label, distance);
685685
}
686-
void BranchIfZero(Register src,
687-
Label* label,
688-
JumpDistance distance = kFarJump) {
689-
cmpq(src, Immediate(0));
690-
j(ZERO, label, distance);
691-
}
692686

693687
// Issues a move instruction if 'to' is not the same as 'from'.
694688
void MoveRegister(Register to, Register from);

runtime/vm/compiler/backend/flow_graph_compiler.cc

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,22 +2286,15 @@ void FlowGraphCompiler::GenerateCidRangesCheck(
22862286

22872287
bool FlowGraphCompiler::CheckAssertAssignableTypeTestingABILocations(
22882288
const LocationSummary& locs) {
2289-
ASSERT(locs.in(AssertAssignableInstr::kInstancePos).IsRegister() &&
2290-
locs.in(AssertAssignableInstr::kInstancePos).reg() ==
2291-
TypeTestABI::kInstanceReg);
2292-
ASSERT((locs.in(AssertAssignableInstr::kDstTypePos).IsConstant() &&
2293-
locs.in(AssertAssignableInstr::kDstTypePos)
2294-
.constant()
2295-
.IsAbstractType()) ||
2296-
(locs.in(AssertAssignableInstr::kDstTypePos).IsRegister() &&
2297-
locs.in(AssertAssignableInstr::kDstTypePos).reg() ==
2298-
TypeTestABI::kDstTypeReg));
2299-
ASSERT(locs.in(AssertAssignableInstr::kInstantiatorTAVPos).IsRegister() &&
2300-
locs.in(AssertAssignableInstr::kInstantiatorTAVPos).reg() ==
2301-
TypeTestABI::kInstantiatorTypeArgumentsReg);
2302-
ASSERT(locs.in(AssertAssignableInstr::kFunctionTAVPos).IsRegister() &&
2303-
locs.in(AssertAssignableInstr::kFunctionTAVPos).reg() ==
2304-
TypeTestABI::kFunctionTypeArgumentsReg);
2289+
ASSERT(locs.in(0).IsRegister() &&
2290+
locs.in(0).reg() == TypeTestABI::kInstanceReg);
2291+
ASSERT((locs.in(1).IsConstant() && locs.in(1).constant().IsAbstractType()) ||
2292+
(locs.in(1).IsRegister() &&
2293+
locs.in(1).reg() == TypeTestABI::kDstTypeReg));
2294+
ASSERT(locs.in(2).IsRegister() &&
2295+
locs.in(2).reg() == TypeTestABI::kInstantiatorTypeArgumentsReg);
2296+
ASSERT(locs.in(3).IsRegister() &&
2297+
locs.in(3).reg() == TypeTestABI::kFunctionTypeArgumentsReg);
23052298
ASSERT(locs.out(0).IsRegister() &&
23062299
locs.out(0).reg() == TypeTestABI::kInstanceReg);
23072300
return true;
@@ -2767,49 +2760,23 @@ void FlowGraphCompiler::GenerateAssertAssignable(CompileType* receiver_type,
27672760
ASSERT(!token_pos.IsClassifying());
27682761
ASSERT(CheckAssertAssignableTypeTestingABILocations(*locs));
27692762

2770-
// Non-null if we have a constant destination type.
2771-
const auto& dst_type =
2772-
locs->in(AssertAssignableInstr::kDstTypePos).IsConstant()
2773-
? AbstractType::Cast(
2774-
locs->in(AssertAssignableInstr::kDstTypePos).constant())
2775-
: Object::null_abstract_type();
2776-
2777-
if (!dst_type.IsNull()) {
2778-
ASSERT(dst_type.IsFinalized());
2779-
if (dst_type.IsTopTypeForSubtyping()) return; // No code needed.
2763+
if (!locs->in(1).IsConstant()) {
2764+
// TODO(dartbug.com/40813): Handle setting up the non-constant case.
2765+
UNREACHABLE();
27802766
}
2767+
const auto& dst_type = AbstractType::Cast(locs->in(1).constant());
2768+
ASSERT(dst_type.IsFinalized());
2769+
2770+
if (dst_type.IsTopTypeForSubtyping()) return; // No code needed.
27812771

27822772
compiler::Label done;
2783-
Register type_reg = TypeTestABI::kDstTypeReg;
2784-
// Generate caller-side checks to perform prior to calling the TTS.
2785-
if (dst_type.IsNull()) {
2786-
__ Comment("AssertAssignable for runtime type");
2787-
// kDstTypeReg should already contain the destination type.
2788-
const bool null_safety = isolate()->null_safety();
2789-
GenerateStubCall(token_pos,
2790-
StubCode::GetTypeIsTopTypeForSubtyping(null_safety),
2791-
PcDescriptorsLayout::kOther, locs, deopt_id);
2792-
// TypeTestABI::kSubtypeTestCacheReg is 0 if the type is a top type.
2793-
__ BranchIfZero(TypeTestABI::kSubtypeTestCacheReg, &done,
2794-
compiler::Assembler::kNearJump);
2795-
2796-
GenerateStubCall(token_pos,
2797-
StubCode::GetNullIsAssignableToType(null_safety),
2798-
PcDescriptorsLayout::kOther, locs, deopt_id);
2799-
// TypeTestABI::kSubtypeTestCacheReg is 0 if the object is null and is
2800-
// assignable.
2801-
__ BranchIfZero(TypeTestABI::kSubtypeTestCacheReg, &done,
2802-
compiler::Assembler::kNearJump);
2803-
} else {
2804-
__ Comment("AssertAssignable for compile-time type");
2805-
GenerateCallerChecksForAssertAssignable(receiver_type, dst_type, &done);
2806-
if (dst_type.IsTypeParameter()) {
2807-
// The resolved type parameter is in the scratch register.
2808-
type_reg = TypeTestABI::kScratchReg;
2809-
}
2810-
}
28112773

2812-
GenerateTTSCall(token_pos, deopt_id, type_reg, dst_type, dst_name, locs);
2774+
GenerateCallerChecksForAssertAssignable(receiver_type, dst_type, &done);
2775+
2776+
GenerateTTSCall(token_pos, deopt_id,
2777+
dst_type.IsTypeParameter() ? TypeTestABI::kScratchReg
2778+
: TypeTestABI::kDstTypeReg,
2779+
dst_type, dst_name, locs);
28132780
__ Bind(&done);
28142781
}
28152782

@@ -2822,7 +2789,8 @@ void FlowGraphCompiler::GenerateTTSCall(TokenPosition token_pos,
28222789
const AbstractType& dst_type,
28232790
const String& dst_name,
28242791
LocationSummary* locs) {
2825-
ASSERT(!dst_name.IsNull());
2792+
// For now, we don't allow dynamic (non-compile-time) dst_type/dst_name.
2793+
ASSERT(!dst_type.IsNull() && !dst_name.IsNull());
28262794
// We use 2 consecutive entries in the pool for the subtype cache and the
28272795
// destination name. The second entry, namely [dst_name] seems to be unused,
28282796
// but it will be used by the code throwing a TypeError if the type test fails
@@ -2836,11 +2804,9 @@ void FlowGraphCompiler::GenerateTTSCall(TokenPosition token_pos,
28362804
ASSERT((sub_type_cache_index + 1) == dst_name_index);
28372805
ASSERT(__ constant_pool_allowed());
28382806

2839-
__ Comment("TTSCall");
28402807
// If the dst_type is known at compile time and instantiated, we know the
28412808
// target TTS stub and so can use a PC-relative call when available.
2842-
if (!dst_type.IsNull() && dst_type.IsInstantiated() &&
2843-
CanPcRelativeCall(dst_type)) {
2809+
if (dst_type.IsInstantiated() && CanPcRelativeCall(dst_type)) {
28442810
__ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
28452811
sub_type_cache_index);
28462812
__ GenerateUnRelocatedPcRelativeCall();

0 commit comments

Comments
 (0)