-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge f80214e into dev
- Loading branch information
Showing
11 changed files
with
281 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
// Verifies that compiler can remove bounds checks when told by pragma. | ||
|
||
import 'package:expect/expect.dart'; | ||
import 'package:vm/testing/il_matchers.dart'; | ||
|
||
import 'dart:typed_data'; | ||
|
||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int direct_uint8list_has_bounds_check(Uint8List list) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = list[i]; | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:unsafe:no-bounds-checks') | ||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int direct_uint8list_no_bounds_check(Uint8List list) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = list[i]; | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:prefer-inline') | ||
int helper_uint8list_no_pragma(Uint8List list) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = list[i]; | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int inlined_uint8list_has_bounds_check(Uint8List list) { | ||
if (helper_uint8list_no_pragma(list) == 42) { | ||
return 42; | ||
} | ||
return 0; | ||
} | ||
|
||
@pragma('vm:prefer-inline') | ||
@pragma('vm:unsafe:no-bounds-checks') | ||
int helper_uint8list_pragma(Uint8List list) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = list[i]; | ||
} | ||
return result; | ||
} | ||
|
||
// For whatever reason, this passes even without the fix, despite real-world | ||
// example in CFE (AbstractScanner.select) as well as a test in the VM | ||
// (runtime/vm/compiler/backend/redundancy_elimination_test.cc, | ||
// BoundsCheckElimination_Pragma_Inline) needs the fix. | ||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int inlined_uint8list_no_bounds_check(Uint8List list, bool b) { | ||
if (b) { | ||
return helper_uint8list_pragma(list); | ||
} else { | ||
return helper_uint8list_pragma(list) + 42; | ||
} | ||
} | ||
|
||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int direct_string_has_bounds_check(String s) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = s.codeUnitAt(i); | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:unsafe:no-bounds-checks') | ||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int direct_string_no_bounds_check(String s) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = s.codeUnitAt(i); | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:prefer-inline') | ||
int helper_string_no_pragma(String s) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = s.codeUnitAt(i); | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int inlined_string_has_bounds_check(String s) { | ||
if (helper_string_no_pragma(s) == 42) { | ||
return 42; | ||
} | ||
return 0; | ||
} | ||
|
||
@pragma('vm:prefer-inline') | ||
@pragma('vm:unsafe:no-bounds-checks') | ||
int helper_string_pragma(String s) { | ||
int result = 0; | ||
for (int i = 0; i < 10; i++) { | ||
result = s.codeUnitAt(i); | ||
} | ||
return result; | ||
} | ||
|
||
@pragma('vm:never-inline') | ||
@pragma('vm:testing:print-flow-graph') | ||
int inlined_string_no_bounds_check(String s) { | ||
if (helper_string_pragma(s) == 42) { | ||
return 42; | ||
} | ||
return 0; | ||
} | ||
|
||
void main() { | ||
// Uint8List access directly. | ||
direct_uint8list_has_bounds_check(new Uint8List(20)); | ||
direct_uint8list_no_bounds_check(new Uint8List(20)); | ||
|
||
// Uint8List access via inlined function. | ||
inlined_uint8list_has_bounds_check(new Uint8List(20)); | ||
inlined_uint8list_no_bounds_check( | ||
new Uint8List(20), new Uint8List(20).toString().length.isEven); | ||
|
||
// String access directly. | ||
direct_string_has_bounds_check(new Uint8List(20).toString()); | ||
direct_string_no_bounds_check(new Uint8List(20).toString()); | ||
|
||
// String access via inlined function. | ||
inlined_string_has_bounds_check(new Uint8List(20).toString()); | ||
inlined_string_no_bounds_check(new Uint8List(20).toString()); | ||
} | ||
|
||
void extractAllInstructions(dynamic data, List<String> into) { | ||
if (data is Map) { | ||
for (var entry in data.entries) { | ||
if (entry.key == "o" && entry.value is String) { | ||
into.add(entry.value); | ||
} else { | ||
extractAllInstructions(entry.value, into); | ||
} | ||
} | ||
} else if (data is List) { | ||
for (var entry in data) { | ||
extractAllInstructions(entry, into); | ||
} | ||
} else { | ||
if (data is int || data is String) { | ||
// ok | ||
} else { | ||
print("Notice: Unhandled data: ${data.runtimeType}: $data"); | ||
} | ||
} | ||
} | ||
|
||
bool hasCheckBounds(FlowGraph graph) { | ||
List<String> ils = []; | ||
extractAllInstructions(graph.blocks(), ils); | ||
for (String il in ils) { | ||
if (il == "GenericCheckBound") return true; | ||
} | ||
return false; | ||
} | ||
|
||
void matchIL$direct_uint8list_has_bounds_check(FlowGraph graph) { | ||
Expect.isTrue(hasCheckBounds(graph), "should have bounds checks"); | ||
} | ||
|
||
void matchIL$direct_uint8list_no_bounds_check(FlowGraph graph) { | ||
Expect.isFalse(hasCheckBounds(graph), "should not have bounds checks"); | ||
} | ||
|
||
void matchIL$inlined_uint8list_has_bounds_check(FlowGraph graph) { | ||
Expect.isTrue(hasCheckBounds(graph), "should have bounds checks"); | ||
} | ||
|
||
void matchIL$inlined_uint8list_no_bounds_check(FlowGraph graph) { | ||
Expect.isFalse(hasCheckBounds(graph), "should not have bounds checks"); | ||
} | ||
|
||
void matchIL$direct_string_has_bounds_check(FlowGraph graph) { | ||
Expect.isTrue(hasCheckBounds(graph), "should have bounds checks"); | ||
} | ||
|
||
void matchIL$direct_string_no_bounds_check(FlowGraph graph) { | ||
Expect.isFalse(hasCheckBounds(graph), "should not have bounds checks"); | ||
} | ||
|
||
void matchIL$inlined_string_has_bounds_check(FlowGraph graph) { | ||
Expect.isTrue(hasCheckBounds(graph), "should have bounds checks"); | ||
} | ||
|
||
void matchIL$inlined_string_no_bounds_check(FlowGraph graph) { | ||
Expect.isFalse(hasCheckBounds(graph), "should not have bounds checks"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
void main() { | ||
print(Uri.base.toFilePath()); // should not crash | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,5 +27,5 @@ CHANNEL dev | |
MAJOR 3 | ||
MINOR 6 | ||
PATCH 0 | ||
PRERELEASE 272 | ||
PRERELEASE 273 | ||
PRERELEASE_PATCH 0 |