This CL adds passing structs by value in FFI trampolines.
Nested structs and inline arrays are future work.
C defines passing empty structs as undefined behavior, so that is not
supported in this CL.
Suggested review order:
1) commit message
2) ffi/marshaller (decisions for what is done in IL and what in MC)
3) frontend/kernel_to_il (IL construction)
4) backend/il (MC generation from IL)
5) rest in VM
Overall architecture is that structs are split up into word-size chunks
in IL when this is possible: 1 definition in IL per chunk, 1 Location in
IL per chunk, and 1 NativeLocation for the backend per chunk.
In some cases it is not possible or less convenient to split into
chunks. In these cases TypedDataBase objects are stored into and loaded
from directly in machine code.
The various cases:
- FFI call arguments which are not passed as pointers: pass individual
chunks to FFI call which already have the right location.
- FFI call arguments which are passed as pointers: Pass in TypedDataBase
to FFI call, allocate space on the stack, and make a copy on the stack
and pass the copies' address to the callee.
- FFI call return value: pass in TypedData to FFI call, and copy result
in machine code.
- FFI callback arguments which are not passed as pointers: IL definition
for each chunk, and populate a new TypedData with those chunks.
- FFI callback arguments which are passed as pointer: IL definition for
the pointer, and copying of contents in IL.
- FFI return value when location is pointer: Copy data to callee result
location in IL.
- FFI return value when location is not a pointer: Copy data in machine
code to the right registers.
Some other notes about the implementation:
- Due to Store/LoadIndexed loading doubles from float arrays, we use
a int32 instead and use the BitCastInstr.
- Linux ia32 uses `ret 4` when returning structs by value. This requires
special casing in the FFI callback trampolines to either use `ret` or
`ret 4` when returning.
- The 1 IL definition, 1 Location, and 1 NativeLocation approach does
not remove the need for special casing PairLocations in the machine
code generation because they are 1 Location belonging to 1 definition.
Because of the amount of corner cases in the calling conventions that
need to be covered, the tests are generated, rather than hand-written.
ABIs tested on CQ: x64 (Linux, MacOS, Windows), ia32 (Linux, Windows),
arm (Android softFP, Linux hardFP), arm64 Android.
ABIs tested locally through Flutter: ia32 Android (emulator), x64 iOS
(simulator), arm64 iOS.
ABIs not tested: arm iOS.
TEST=runtime/bin/ffi_test/ffi_test_functions_generated.cc
TEST=runtime/bin/ffi_test/ffi_test_functions.cc
TEST=tests/{ffi,ffi_2}/function_structs_by_value_generated_test.dart
TEST=tests/{ffi,ffi_2}/function_callbacks_structs_by_value_generated_tes
TEST=tests/{ffi,ffi_2}/function_callbacks_structs_by_value_test.dart
TEST=tests/{ffi,ffi_2}/vmspecific_static_checks_test.dart
Closes https://github.com/dart-lang/sdk/issues/36730.
Change-Id: I474d3a4ee1faadbe767ddadd1b696e24d8dc364c
Cq-Include-Trybots: luci.dart.try:dart-sdk-linux-try,dart-sdk-mac-try,dart-sdk-win-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64-try,vm-kernel-asan-linux-release-x64-try,vm-kernel-mac-debug-x64-try,vm-kernel-linux-debug-ia32-try,vm-kernel-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-x64-try,vm-kernel-nnbd-linux-debug-ia32-try,vm-kernel-nnbd-mac-release-x64-try,vm-kernel-nnbd-win-debug-x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-reload-linux-debug-x64-try,vm-kernel-reload-rollback-linux-debug-x64-try,vm-kernel-win-debug-x64-try,vm-kernel-win-debug-ia32-try,vm-precomp-ffi-qemu-linux-release-arm-try,vm-kernel-precomp-obfuscate-linux-release-x64-try,vm-kernel-msan-linux-release-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-android-release-arm_x64-try,analyzer-analysis-server-linux-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140290
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Previously, all boxed native field slots were marked not nullable.
However, several boxed native fields are in fact nullable, which means
that even generated IL that appropriately checks these fields for null
can break in optimized code when the null checks are removed.
Also add some helper utilities for working with representations.
Change-Id: I22703d14cfbadbabeae74179476dea47ace12161
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/159280
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Clement Skau <cskau@google.com>
Originally, the assert here required the location be a machine register,
invalid, or a pair location if always_calls() was true, which meant
that SameAsFirstInput() could not be used.
Extend the assert to allow SameAsFirstInput(), but only if the location
of the first input is a machine register, invalid, or a pair location.
Also make sure any further changes to the first input remain consistent
with this expectation.
Fixes: https://github.com/dart-lang/sdk/issues/32787
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-simarm_x64-try
Change-Id: If43eb5399283d23f62a502edb0a9ce9c82813b3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147101
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif // defined(DART_PRECOMPILED_RUNTIME)
Remove #if defined(DART_PRECOMPILED_RUNTIME) from most compiler sources.
Change-Id: Id175c83fdbea38d9d5e1371ff433e3888f2afe8a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143523
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Static methods and constructors may receive unboxed parameters.
This change adds a bitmap to the RawFunction object indicating
which parameters are unboxed and their types. Also, the stack frame
bitmap was updated to include new bits for those parameters.
The ArgumentsDescriptor object was updated to store not only the number
of arguments, but also their size, since 32-bit platforms would use two
words for each int64 and double value.
In addition, static methods that return non-nullable integers
and doubles may return these values unboxed.
Dart AOT x64:
TypedData.Uint8ClampedListViewVarBench +11.73%
DeltaBlue +9.32%
Meteor (Intel Xeon) +4.64%
Flutter release android-armv8:
velocity_tracker_bench -2.32% (less is better)
flutter_gallery_readonlydata_size +0.18%
flutter_gallery_total_size +0.13%
flutter_gallery_instructions_size +0.12%
Issue https://github.com/dart-lang/sdk/issues/33549
Change-Id: I97e310f8f30213920af2333fbdedf193d03db5c3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135313
Commit-Queue: Victor Agnez Lima <victoragnez@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
While emitting code for a ParallelMove on ARM32, the TMP register was
being used as a dest/src. When the stack slot offset is large,
StoreToOffset creates a new base in TMP in order to use a smaller
offset. Since the ParallelMove implementation was hardcoding TMP as the
dest/src register, the assert that the register != TMP failed with large
offsets. Now we instead perform a check to see if the offset will fit to
determine whether or not we can use TMP or if we need to fall back and
use LR as our temporary (we can do this since we're in the middle of a
ParallelMove).
Fixes https://github.com/dart-lang/sdk/issues/38654
Change-Id: I4d8cc8b54f6090d86992aabb8ff44d088bc02d3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119584
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
Refactoring motivation: go/dart-simulated-ffi
* template Location and PairLocation with <dart::Register, dart::FpuRegister> or <dart::host::Register, dart::host::FpuRegister>
* move RegisterName and FpuRegisterName from assembler to constants
* move methods that are only implemented by Location and not HostLocation out of Location
Change-Id: Ie9aa2dae63380da0cbfb15eacc440537fbed48f8
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-bare-linux-release-simarm-try, vm-kernel-precomp-bare-linux-release-simarm64-try, vm-kernel-precomp-linux-debug-x64-try, vm-kernel-linux-debug-simdbc64-try, vm-kernel-precomp-win-release-simarm64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/98845
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Auto-Submit: Daco Harkes <dacoharkes@google.com>
This is the next step towards preventing compiler from directly peeking
into runtime and instead interact with runtime through a well defined
surface.
This CL decouples the hand-written stub codes from the runtime. The
target architecture dependent stubs are moved to
dart::compiler::StubCodeCompiler which use dart::compiler::target:*
for accessing any runtime related code.
The generation of type testing stubs is moved to separate files for the
time being.
Issue https://github.com/dart-lang/sdk/issues/31709
Change-Id: Icd0995b18a7bac496b1e12231cf437943f5c94f1
Reviewed-on: https://dart-review.googlesource.com/c/92720
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Auto-Submit: Martin Kustermann <kustermann@google.com>
This is the next step towards preventing compiler from directly peeking
into runtime and instead interact with runtime through a well defined
surface.
This CL decouples the hand-written stub codes from the runtime. The
target architecture dependent stubs are moved to
dart::compiler::StubCodeCompiler which use dart::compiler::target:*
for accessing any runtime related code.
The generation of type testing stubs is moved to separate files for the
time being.
Issue https://github.com/dart-lang/sdk/issues/31709
Change-Id: I1b4f1cca0acb704b30b80eca7f634734772389b5
Reviewed-on: https://dart-review.googlesource.com/c/92138
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Aart Bik <ajcbik@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This is the next step towards preventing compiler from directly peeking
into runtime and instead interact with runtime through a well defined
surface. The goal of the refactoring to locate all places where compiler
accesses some runtime information and partion those accesses into two
categories:
- creating objects in the host runtime (e.g. allocating strings, numbers, etc)
during compilation;
- accessing properties of the target runtime (e.g. offsets of fields) to
embed those into the generated code;
This change introduces dart::compiler and dart::compiler::target namespaces.
All code in the compiler will gradually be moved into dart::compiler namespace.
One of the motivations for this change is to be able to prevent access to
globally defined host constants like kWordSize by shadowing them in the
dart::compiler namespace.
The nested namespace dart::compiler::target hosts all information about
target runtime that compiler could access, e.g. compiler::target::kWordSize
defines word size of the target which will eventually be made different
from the host kWordSize (defined by dart::kWordSize).
The API for compiler to runtime interaction is placed into compiler_api.h.
Note that we still permit runtime to access compiler internals directly -
this is not going to be decoupled as part of this work.
Issue https://github.com/dart-lang/sdk/issues/31709
Change-Id: If4396d295879391becfa6c38d4802bbff81f5b20
Reviewed-on: https://dart-review.googlesource.com/c/90242
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
So far the frontend (parser, flow graph builder, ssa construction) were
aware of the actual frame layout.
This CL makes the indices we assign to [LocalVariable]s logical
indices, assigning:
* M parameters the indices 1 ... M
* N local variables the indices 0 -1 ... -(N-1)
The scope building, flow graph builder and ssa construction operate on
those logical indices.
When emitting actual code, the backend will translate those indices into
actual FP relative indices. This allows us to be more flexible in the
backend which frame layout we choose.
Issue https://github.com/dart-lang/sdk/issues/33274
Change-Id: I9a504bf97821c257aafd2b3430df9f4c9da4b442
Reviewed-on: https://dart-review.googlesource.com/57321
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This fixes an issue when a program got loaded via dill, a function
with a try-catch got optimized and the exception/stacktrace variables
got captured.
Change-Id: Icb8ea5f3557080f8274f7db2af09e33154820e5b
Reviewed-on: https://dart-review.googlesource.com/55721
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
This reverts commit 23b4a505ec.
Reason for revert: The language_2/custom_await_stack_trace_test started failing.
Original change's description:
> Reland "[VM] Use IR for code in [CatchEntryInstr]s to populate captured exception/stacktrace variables"
>
> This fixes an issue when a program got loaded via dill, a function
> with a try-catch got optimized and the exception/stacktrace variables
> got captured.
>
> Change-Id: Icb626965019b248afe3b72a6679c5049ea7b7b00
> Reviewed-on: https://dart-review.googlesource.com/55681
> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
> Commit-Queue: Martin Kustermann <kustermann@google.com>
TBR=vegorov@google.com,kustermann@google.com
Change-Id: Ic825c1e3ed14c731da1d43aa6f27d37ed5d36b4c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/55720
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This fixes an issue when a program got loaded via dill, a function
with a try-catch got optimized and the exception/stacktrace variables
got captured.
Change-Id: Icb626965019b248afe3b72a6679c5049ea7b7b00
Reviewed-on: https://dart-review.googlesource.com/55681
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This reverts commit 12759870a4.
Reason for revert: Broke many bots.
Original change's description:
> [VM] Use IR for code in [CatchEntryInstr]s to populate captured exception/stacktrace variables
>
> This fixes an issue when a program got loaded via dill, a function
> with a try-catch got optimized and the exception/stacktrace variables
> got captured.
>
> Change-Id: Ia6b62f2a0986c78b90afe7fae25025ca4e5b09db
> Reviewed-on: https://dart-review.googlesource.com/35182
> Commit-Queue: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
TBR=vegorov@google.com,kustermann@google.com
Change-Id: I2ec7b4bea401e6d5665f6e789eb8e241b99db7b3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/36200
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This fixes an issue when a program got loaded via dill, a function
with a try-catch got optimized and the exception/stacktrace variables
got captured.
Change-Id: Ia6b62f2a0986c78b90afe7fae25025ca4e5b09db
Reviewed-on: https://dart-review.googlesource.com/35182
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
New folder structure (nested under vm/):
- compiler/
- jit/ - JIT specific code
- aot/ - AOT specific code
- backend/ - all middle-end and back-end code (IL, flow graph)
- assembler/ - assemblers and disassemblers
- frontend/ - front ends (AST -> IL, Kernel -> IL)
compiler/README.md would be the documentation root for the compiler
pipeline
Bug: https://github.com/dart-lang/sdk/issues/30575
Change-Id: I2dfd9688793bff737f7632ddc77fca766875ce36
Reviewed-on: https://dart-review.googlesource.com/2940
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>