[vm/compiler] Limit exposure of untagged pointers to managed memory. After https://dart-review.googlesource.com/c/sdk/+/330600, there were more chances for the optimizing compiler to introduce or move GC-triggering instructions like allocations or boxings between the retrieval of an untagged pointer to GC-moveable memory and its use. To limit the chance of this happening, this CL removes the explicit loading of the untagged payload address when building the initial flow graph in most cases when the array is not known to be an external array (an external string, an external typed data object, or an FFI Pointer). The remaining case is during view allocation, which extracts the payload address of the base typed data object underlying the view (which may be GC-movable) to calculate the payload address that should be stored in the data field of the view object. See https://github.com/dart-lang/sdk/issues/54884. During canonicalization of LoadIndexed, StoreIndexed, and MemoryCopy instructions, if the cid of an array input is an external array (external string, external typed data object, or Pointer), then a LoadField instruction that extracts the untagged payload address is inserted before the instruction and the corresponding input is rebound to that LoadField instruction. Once all compiler passes that involve code motion have been performed, a new pass looks for LoadIndexed, StoreIndexed, or MemoryCopy where the cid stored in the instruction for the array is a typed data cid. In these cases, if the array is not an internal typed data object, then the payload address is extracted. Waiting until this point ensures that no GC-triggering instructions are inserted between the extraction of the payload address and the use. (Internal typed data objects are left as-is because the payload address is inside the object itself and doesn't require indirection through the data field of the object). This CL also replaces code conditional on the array cid with code that is instead conditional on the array element representation in cases where it makes sense to do so, since this is a less brittle check than checking the array cid (e.g., checking for kUnboxedInt8 to load, store, or copy an signed byte from an array instead of listing all possible array cids that store signed bytes). This CL also fixes an issue with the ARM64 assembler where calling LoadFromOffset with an Address that has a non-Offset type would silently generate bad code instead of triggering the ASSERT in PrepareLargeOffset. TEST=vm/dart/typed_list_index_checkbound_il_test Issue: https://github.com/dart-lang/sdk/issues/54710 Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-aot-win-debug-arm64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try,vm-win-debug-arm64-try,vm-win-debug-x64-try,vm-win-release-ia32-try Change-Id: I25b5f314943e9254d3d28986d720a5d47f12feeb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352363 Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
Dart is:
Approachable: Develop with a strongly typed programming language that is consistent, concise, and offers modern language features like null safety and patterns.
Portable: Compile to ARM, x64, or RISC-V machine code for mobile, desktop, and backend. Compile to JavaScript or WebAssembly for the web.
Productive: Make changes iteratively: use hot reload to see the result instantly in your running app. Diagnose app issues using DevTools.
Dart's flexible compiler technology lets you run Dart code in different ways, depending on your target platform and goals:
Dart Native: For programs targeting devices (mobile, desktop, server, and more), Dart Native includes both a Dart VM with JIT (just-in-time) compilation and an AOT (ahead-of-time) compiler for producing machine code.
Dart Web: For programs targeting the web, Dart Web includes both a development time compiler (dartdevc) and a production time compiler (dart2js).
Dart is free and open source.
See LICENSE and PATENT_GRANT.
Visit dart.dev to learn more about the language, tools, and to find codelabs.
Browse pub.dev for more packages and libraries contributed by the community and the Dart team.
Our API reference documentation is published at api.dart.dev, based on the stable release. (We also publish docs from our beta and dev channels, as well as from the primary development branch).
If you want to build Dart yourself, here is a guide to getting the source, preparing your machine to build the SDK, and building.
There are more documents on our wiki.
The easiest way to contribute to Dart is to file issues.
You can also contribute patches, as described in Contributing.