-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[vm/ffi] Non-aligned reads and writes #45009
Comments
What are the failure modes? If you read What are the alternatives?
It's an issue that intel CPUs won't complain about unaligned pointers being read. That means that many users won't ever need to use I'd consider the I think that's potentially a more consistent API than adding extra methods to all more-than-one-byte types. It matches the typed-array story of having aligned |
Only ARMv7 with the testing I've done locally (that does not include all OS/hardware combinations yet).
I'll make a CL for this to see what is the impact on arm. |
To be honest I think we should just do what C/C++ would do a segfault. |
@mraleph Some instructions still require alignment, that's true (also for |
For packed structs we need support for unaligned reads/writes or our Struct API will segfault. #pragma pack(push, 1)
struct Struct9BytesPackedMixed {
uint8_t a0;
double a1;
};
#pragma pack(pop) Dart API @Packed(1)
class Struct9BytesPackedMixed extends Struct {
@Uint8()
external int a0;
@Double()
external double a1; // This getter/setter needs to do an unaligned read/write.
} |
Yeah I agree that we should support reading unaligned data from packed structs - basically follow how C does it: normally it assumes aligned access, except for certain cases like packed structs. For convenience we can also have either unaligned getters or other APIs, but I would suggest against making Pointers themselves defensive against misalignment. |
Out of curiosity, here's the code our C compiler generates for packed (and therefore possibly unaligned) float/double members. typedef struct __attribute__((packed)) {
char _;
double d;
float f;
char __;
} Foo ;
int getSize() {
return sizeof(Foo);
}
double getDouble(Foo* f) {
return f->d;
}
float getFloat(Foo* f) {
return f->f;
} In normal arm abi:
And hard-fp abi:
The ARM ISA mentions:
|
We will not expose unaligned reads/writes in a public API, only implement it for packed structs. |
This CL validates the hypothesis that the only misaligned reads/writes which are not supported are double and float, and only on arm32. Running these on the CI and Golem will validate this hypothesis. Bug: #45009 Change-Id: I0a77fd1f47a388d1f454c1ded50cd7ecaeadb0f0 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/+/190523 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Aske Simon Christensen <askesc@google.com>
Closes: #38158 This CL implements unaligned access for float/double on arm32, but does not expose it in an API. Rather it only uses these loads/stores inside the getters and setters of packed structs. Bug: #45009 Besides unaligned access for float/double, this CL is mostly a CFE change. The only VM change is reading the packing in the `_FfiStructLayout` annotation. The implementation of using the packing in the VM, and analyzer changes have landed separately in earlier CLs. tools/test.py ffi ffi_2 TEST=tests/ffi(_2)/(.*)by_value_(*.)_test.dart Change-Id: Ic3106ecc626d2e30674a49bf03f65ae12d2b3502 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/+/186143 Reviewed-by: Aske Simon Christensen <askesc@google.com>
Skip float and double access tests on ARM because they will always trigger alignment traps. These traps might or might not be hidden from the user depending on the specific OS configuration, e.g. many Linux distrubutions choose to perform fixup in the kernel, but Android disables that. Similarly there is a difference in QEMU behavior depending on QEMU version. Change-Id: Idca9553486e0f479ec1a32c25131d3d1bd4ef74d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/338140 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Slava Egorov <vegorov@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com> Auto-Submit: Slava Egorov <vegorov@google.com>
The getters and setters on
Pointer<Double>
etc, require memory to be aligned.sdk/sdk/lib/ffi/ffi.dart
Lines 475 to 480 in 4216dc8
Attempting to read/write with a non-aligned pointer causes a segmentation fault on arm32-Android. (On many other hardware/OS combinations it seems to be fine or just slower.)
We currently do not provide a way to do non-aligned reads and writes.
(The workaround is to manually turn the double into 8 uint8's, and write those.)
We should add unaligned reads/writes.
@lrhn
unalignedValue
getter and setter as naming? wdyt?Should we add unaligned access for index operators as well? That might not be that useful.
sdk/sdk/lib/ffi/ffi.dart
Lines 482 to 490 in 4216dc8
We need this feature for interacting with packed structs #38158.
The text was updated successfully, but these errors were encountered: