Revert "[vm/ffi] SimDBC64 align stack frame"

This reverts commit f1038ee771.

Reason for revert: breaks function_gc_test on ARM64

Original change's description:
> [vm/ffi] SimDBC64 align stack frame
> 
> And regression test for dartbug.com/37069
> 
> Fixes: https://github.com/dart-lang/sdk/issues/37176
> Follow up of: https://dart-review.googlesource.com/c/sdk/+/103814
> Bug: https://github.com/dart-lang/sdk/issues/37069
> Change-Id: I2c791271f936580d66a48485a60ab6cddb1ba4f8
> Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try, app-kernel-linux-debug-x64-try, vm-kernel-linux-debug-simdbc64-try,vm-kernel-mac-debug-simdbc64-try,vm-kernel-reload-mac-debug-simdbc64-try,vm-kernel-linux-debug-ia32-try,vm-dartkb-linux-debug-simarm64-try,vm-kernel-win-debug-x64-try
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104824
> Commit-Queue: Daco Harkes <dacoharkes@google.com>
> Reviewed-by: Samir Jindel <sjindel@google.com>

TBR=sjindel@google.com,dacoharkes@google.com

Change-Id: Ibefa2e854f4a58b41384aca73a3bbbe86d75bf80
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/37069
Cq-Include-Trybots: luci.dart.try:vm-ffi-android-debug-arm-try, app-kernel-linux-debug-x64-try, vm-kernel-linux-debug-simdbc64-try, vm-kernel-mac-debug-simdbc64-try, vm-kernel-reload-mac-debug-simdbc64-try, vm-kernel-linux-debug-ia32-try, vm-dartkb-linux-debug-simarm64-try, vm-kernel-win-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105840
Reviewed-by: Samir Jindel <sjindel@google.com>
Commit-Queue: Samir Jindel <sjindel@google.com>
This commit is contained in:
Samir Jindel 2019-06-12 22:31:11 +00:00 committed by commit-bot@chromium.org
parent 1e24fe7d69
commit 68b2d53da5
12 changed files with 41 additions and 167 deletions

View file

@ -149,7 +149,7 @@ DART_EXPORT float Times1_337Float(float a) {
}
// Sums many ints.
// Used for testing calling conventions. With so many integers we are using all
// Used for testing calling conventions. With so many doubles we are using all
// normal parameter registers and some stack slots.
DART_EXPORT intptr_t SumManyInts(intptr_t a,
intptr_t b,
@ -169,28 +169,6 @@ DART_EXPORT intptr_t SumManyInts(intptr_t a,
return retval;
}
// Sums an odd number of ints.
// Used for testing calling conventions. With so many arguments, and an odd
// number of arguments, we are testing stack alignment on various architectures.
DART_EXPORT intptr_t SumManyIntsOdd(intptr_t a,
intptr_t b,
intptr_t c,
intptr_t d,
intptr_t e,
intptr_t f,
intptr_t g,
intptr_t h,
intptr_t i,
intptr_t j,
intptr_t k) {
std::cout << "SumManyInts(" << a << ", " << b << ", " << c << ", " << d
<< ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
<< ", " << j << ", " << k << ")\n";
intptr_t retval = a + b + c + d + e + f + g + h + i + j + k;
std::cout << "returning " << retval << "\n";
return retval;
}
// Sums many doubles.
// Used for testing calling conventions. With so many doubles we are using all
// xmm parameter registers and some stack slots.
@ -507,22 +485,6 @@ DART_EXPORT void TriggerGC(uint64_t count) {
Dart_ExecuteInternalCommand("gc-now");
}
// Triggers GC. Has 11 dummy arguments as unboxed odd integers which should be
// ignored by GC.
DART_EXPORT void Regress37069(uint64_t a,
uint64_t b,
uint64_t c,
uint64_t d,
uint64_t e,
uint64_t f,
uint64_t g,
uint64_t h,
uint64_t i,
uint64_t j,
uint64_t k) {
Dart_ExecuteInternalCommand("gc-now");
}
// Calls a Dart function to allocate 'count' objects.
// Used for stress-testing GC when re-entering the API.
DART_EXPORT void AllocateThroughDart() {

View file

@ -5,7 +5,6 @@
#include "lib/ffi.h"
#include "include/dart_api.h"
#include "platform/globals.h"
#include "vm/bootstrap_natives.h"
#include "vm/class_finalizer.h"
#include "vm/compiler/assembler/assembler.h"
@ -678,10 +677,6 @@ void FfiMarshalledArguments::SetNumStackSlots(intptr_t num_args) const {
data_[kOffsetNumStackSlots] = num_args;
}
void FfiMarshalledArguments::SetAlignmentMask(uint64_t alignment_mask) const {
data_[kOffsetAlignmentMask] = alignment_mask;
}
intptr_t FfiMarshalledArguments::GetNumStackSlots() const {
return data_[kOffsetNumStackSlots];
}
@ -696,7 +691,6 @@ uint64_t* FfiMarshalledArguments::New(
const compiler::ffi::FfiSignatureDescriptor& signature,
const uint64_t* arg_values) {
const intptr_t num_stack_slots = signature.num_stack_slots();
const uint64_t alignment_mask = ~(OS::ActivationFrameAlignment() - 1);
const intptr_t size =
FfiMarshalledArguments::kOffsetStackSlotValues + num_stack_slots;
uint64_t* data = Thread::Current()->GetFfiMarshalledArguments(size);
@ -705,7 +699,6 @@ uint64_t* FfiMarshalledArguments::New(
descr.SetFunctionAddress(arg_values[compiler::ffi::kFunctionAddressRegister]);
const intptr_t num_args = signature.length();
descr.SetNumStackSlots(num_stack_slots);
descr.SetAlignmentMask(alignment_mask);
for (int i = 0; i < num_args; i++) {
uint64_t arg_value = arg_values[compiler::ffi::kFirstArgumentRegister + i];
HostLocation loc = signature.LocationAt(i);
@ -744,12 +737,10 @@ void FfiMarshalledArguments::Print() const {
RegisterNames::FpuRegisterName(
host::CallingConventions::FpuArgumentRegisters[i]));
}
const intptr_t alignment_mask = data_[kOffsetAlignmentMask];
OS::PrintErr(" %02" Pd " 0x%" Pp " (stack alignment mask)\n",
kOffsetAlignmentMask, alignment_mask);
const intptr_t num_stack_slots = data_[kOffsetNumStackSlots];
OS::PrintErr(" %02" Pd " 0x%" Pp " (number of stack slots)\n",
kOffsetNumStackSlots, num_stack_slots);
const intptr_t index = kOffsetNumStackSlots;
const intptr_t num_stack_slots = data_[index];
OS::PrintErr(" %02" Pd " 0x%" Pp " (number of stack slots)\n", index,
num_stack_slots);
for (intptr_t i = 0; i < num_stack_slots; i++) {
const intptr_t index = kOffsetStackSlotValues + i;
OS::PrintErr(" %02" Pd " 0x%016" Px64 " (stack slot %" Pd ")\n", index,

View file

@ -47,7 +47,6 @@ class FfiMarshalledArguments : public ValueObject {
void SetFunctionAddress(uint64_t value) const;
void SetRegister(::dart::host::Register reg, uint64_t value) const;
void SetFpuRegister(::dart::host::FpuRegister reg, uint64_t value) const;
void SetAlignmentMask(uint64_t kOffsetAlignmentMask) const;
void SetNumStackSlots(intptr_t num_args) const;
intptr_t GetNumStackSlots() const;
void SetStackSlotValue(intptr_t index, uint64_t value) const;
@ -60,9 +59,8 @@ class FfiMarshalledArguments : public ValueObject {
static const intptr_t kOffsetRegisters = 1;
static const intptr_t kOffsetFpuRegisters =
kOffsetRegisters + ::dart::host::CallingConventions::kNumArgRegs;
static const intptr_t kOffsetAlignmentMask =
static const intptr_t kOffsetNumStackSlots =
kOffsetFpuRegisters + ::dart::host::CallingConventions::kNumFpuArgRegs;
static const intptr_t kOffsetNumStackSlots = kOffsetAlignmentMask + 1;
static const intptr_t kOffsetStackSlotValues = kOffsetNumStackSlots + 1;
static const intptr_t kOffsetIntResult = 0;

View file

@ -12,33 +12,20 @@ FfiTrampolineCall:
_FfiTrampolineCall:
#endif
/* Save argument in scratch register. */
push rbx /* Backup caller saved register. */
push rbx
mov rbx, rdi /* Save argument in scratch register. */
/* Enter frame. */
push rbp
mov rbp, rsp
/* Reserve framespace for arguments. */
mov rax, [rbx+0x80] /* Load number of stack arguments. */
shl rax, 3 /* Multiply by size (8 bytes). */
sub rsp, rax /* Reserve num_stack_args stack slots. */
/* Stack alignment. */
and rsp, [rbx+0x78] /* Align stack with stack alignment mask. */
/* Copy stack arguments. */
mov rax, [rbx+0x78] /* Load number of stack arguments. */
cmp rax, 0x0 /* Check if number of stack arguments is 0. */
jz .done /* Skip loop if no stack arguments. */
add rsp, rax /* Unreserve stack slots so we can push arguments. */
add rbx, 0x80 /* Offset RBX to point to stack arguments */
add rbx, 0x78 /* Offset RBX to point to stack arguments */
.loop: /* Copy stack arguments loop. */
push [rbx+rax] /* Push stack argument. */
sub rax, 0x8 /* Decrement stack argument iterator. */
push [rbx+0x8*rax] /* Push stack argument. */
sub rax, 0x1 /* Decrement stack argument iterator. */
cmp rax, 0x0 /* Compare iterator with 0 */
jnz .loop /* Loop while iterator is not 0 */
sub rbx, 0x80 /* Restore RBX to original value. */
sub rbx, 0x78 /* Restore RBX to original value. */
.done: /* End stack arguments loop. */
/* Copy registers and fpu registers. */
@ -65,13 +52,12 @@ call rax /* Call the function. */
mov [rbx], rax /* Move integer result in kOffsetIntResult */
movsd [rbx+8], xmm0 /* Move double result in kOffsetDoubleResult */
/* leave frame */
mov rsp, rbp
pop rbp
/* Clean up stack arguments. */
mov rax, [rbx+0x78] /* Load number of stack arguments. */
imul rax, 0x8 /* Multiply by stack argument size. */
add rsp, rax /* Clean up the stack. */
/* Restore caller saved register. */
pop rbx
ret
#endif /* HOST_ARCH_X64 */

View file

@ -175,13 +175,9 @@ int64_t OS::GetCurrentThreadCPUMicros() {
// into a architecture specific file e.g: os_ia32_linux.cc
intptr_t OS::ActivationFrameAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || \
defined(TARGET_ARCH_DBC) && \
(defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) || \
defined(HOST_ARCH_ARM64))
defined(TARGET_ARCH_ARM64)
const int kMinimumAlignment = 16;
#elif defined(TARGET_ARCH_ARM) || \
defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_ARM)
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_DBC)
const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.

View file

@ -130,13 +130,9 @@ int64_t OS::GetCurrentThreadCPUMicros() {
// into a architecture specific file e.g: os_ia32_fuchsia.cc
intptr_t OS::ActivationFrameAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || \
defined(TARGET_ARCH_DBC) && \
(defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) || \
defined(HOST_ARCH_ARM64))
defined(TARGET_ARCH_ARM64)
const int kMinimumAlignment = 16;
#elif defined(TARGET_ARCH_ARM) || \
defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_ARM)
#elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_DBC)
const int kMinimumAlignment = 8;
#else
#error Unsupported architecture.

View file

@ -497,7 +497,6 @@ int64_t OS::GetCurrentThreadCPUMicros() {
intptr_t OS::ActivationFrameAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
// DBC alignment should be at least as much as host architecture.
const int kMinimumAlignment = 16;
#elif defined(TARGET_ARCH_ARM)
const int kMinimumAlignment = 8;

View file

@ -16,7 +16,7 @@
#include <sys/time.h> // NOLINT
#include <unistd.h> // NOLINT
#if HOST_OS_IOS
#include <syslog.h> // NOLINT
#include <syslog.h> // NOLINT
#endif
#include "platform/utils.h"
@ -140,7 +140,7 @@ intptr_t OS::ActivationFrameAlignment() {
#elif TARGET_ARCH_X64
return 16; // iOS simulator
#elif TARGET_ARCH_DBC
return 16; // Should be at least as much as any host architecture.
return 16;
#else
#error Unimplemented
#endif
@ -212,6 +212,7 @@ DART_NOINLINE uintptr_t OS::GetProgramCounter() {
__builtin_extract_return_addr(__builtin_return_address(0)));
}
void OS::Print(const char* format, ...) {
#if HOST_OS_IOS
va_list args;

View file

@ -175,11 +175,9 @@ int64_t OS::GetCurrentThreadCPUMicros() {
}
intptr_t OS::ActivationFrameAlignment() {
#if defined(TARGET_ARCH_ARM64) || \
defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_ARM64)
#if defined(TARGET_ARCH_ARM64)
return 16;
#elif defined(TARGET_ARCH_ARM) || \
defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_ARM)
#elif defined(TARGET_ARCH_ARM)
return 8;
#elif defined(_WIN64)
// Windows 64-bit ABI requires the stack to be 16-byte aligned.

View file

@ -18,7 +18,7 @@ typedef NativeQuadOpUnsigned = ffi.Uint64 Function(
typedef NativeFunc4 = ffi.IntPtr Function(ffi.IntPtr);
typedef NativeDoubleUnaryOp = ffi.Double Function(ffi.Double);
typedef NativeFloatUnaryOp = ffi.Float Function(ffi.Float);
typedef NativeDecenaryOp = ffi.IntPtr Function(
typedef NativeOctenaryOp = ffi.IntPtr Function(
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
@ -29,7 +29,7 @@ typedef NativeDecenaryOp = ffi.IntPtr Function(
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr);
typedef NativeDoubleDecenaryOp = ffi.Double Function(
typedef NativeDoubleOctenaryOp = ffi.Double Function(
ffi.Double,
ffi.Double,
ffi.Double,
@ -65,9 +65,9 @@ typedef Int64PointerUnOp = ffi.Pointer<ffi.Int64> Function(
ffi.Pointer<ffi.Int64>);
typedef QuadOp = int Function(int, int, int, int);
typedef DoubleUnaryOp = double Function(double);
typedef DecenaryOp = int Function(
typedef OctenaryOp = int Function(
int, int, int, int, int, int, int, int, int, int);
typedef DoubleDecenaryOp = double Function(double, double, double, double,
typedef DoubleOctenaryOp = double Function(double, double, double, double,
double, double, double, double, double, double);
typedef VigesimalOp = double Function(
int,
@ -162,8 +162,8 @@ main(List<String> arguments) {
{
// function with many arguments: arguments get passed in registers and stack
DecenaryOp sumManyInts = ffiTestFunctions
.lookupFunction<NativeDecenaryOp, DecenaryOp>("SumManyInts");
OctenaryOp sumManyInts = ffiTestFunctions
.lookupFunction<NativeOctenaryOp, OctenaryOp>("SumManyInts");
var result = sumManyInts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
print(result);
print(result.runtimeType);
@ -171,8 +171,8 @@ main(List<String> arguments) {
{
// function with many double arguments
DoubleDecenaryOp sumManyDoubles = ffiTestFunctions.lookupFunction<
NativeDoubleDecenaryOp, DoubleDecenaryOp>("SumManyDoubles");
DoubleOctenaryOp sumManyDoubles = ffiTestFunctions.lookupFunction<
NativeDoubleOctenaryOp, DoubleOctenaryOp>("SumManyDoubles");
var result =
sumManyDoubles(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
print(result);

View file

@ -23,7 +23,6 @@ main() async {
testBoxDouble();
testBoxPointer();
testAllocateInNative();
testRegress37069();
testAllocateInDart();
}
@ -36,25 +35,11 @@ typedef NativeNullaryOpDouble = ffi.Double Function();
typedef NativeNullaryOpPtr = ffi.Pointer<ffi.Void> Function();
typedef NativeNullaryOp = ffi.Void Function();
typedef NativeUnaryOp = ffi.Void Function(ffi.Uint64);
typedef NativeUndenaryOp = ffi.Uint64 Function(
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64,
ffi.Uint64);
typedef NullaryOp = int Function();
typedef NullaryOpDbl = double Function();
typedef NullaryOpPtr = ffi.Pointer<ffi.Void> Function();
typedef UnaryOp = void Function(int);
typedef NullaryOpVoid = void Function();
typedef UndenaryOp = int Function(
int, int, int, int, int, int, int, int, int, int, int);
//// These functions return values that require boxing into different types.
@ -103,21 +88,6 @@ final triggerGc = ffiTestFunctions
// Test GC in the FFI call path by calling a C function which triggers GC
// directly.
void testAllocateInNative() => triggerGc();
// This also works as a regression test for 37176.
final regress37069 = ffiTestFunctions
.lookupFunction<NativeUndenaryOp, UndenaryOp>("Regress37069");
// Test GC in the FFI call path by calling a C function which triggers GC
// directly.
void testRegress37069() {
regress37069(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
}
class C {
final int i;
C(this.i);
}
@pragma("vm:entry-point", "call")
void testAllocationsInDartHelper() => triggerGc();

View file

@ -29,7 +29,6 @@ void main() {
testNativeFunctionManyArguments1();
testNativeFunctionManyArguments2();
testNativeFunctionManyArguments3();
testNativeFunctionManyArguments4();
testNativeFunctionPointer();
testNullInt();
testNullDouble();
@ -226,7 +225,7 @@ void testNativeFunctionFloats() {
Expect.approxEquals(1337.0, times1_337Float(1000.0));
}
typedef NativeDecenaryOp = ffi.IntPtr Function(
typedef NativeOctenaryOp = ffi.IntPtr Function(
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
@ -237,39 +236,17 @@ typedef NativeDecenaryOp = ffi.IntPtr Function(
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr);
typedef DecenaryOp = int Function(
typedef OctenaryOp = int Function(
int, int, int, int, int, int, int, int, int, int);
DecenaryOp sumManyInts = ffiTestFunctions
.lookupFunction<NativeDecenaryOp, DecenaryOp>("SumManyInts");
OctenaryOp sumManyInts = ffiTestFunctions
.lookupFunction<NativeOctenaryOp, OctenaryOp>("SumManyInts");
void testNativeFunctionManyArguments1() {
Expect.equals(55, sumManyInts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
}
typedef NativeUndenaryOp = ffi.IntPtr Function(
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr,
ffi.IntPtr);
typedef UndenaryOp = int Function(
int, int, int, int, int, int, int, int, int, int, int);
UndenaryOp sumManyIntsOdd = ffiTestFunctions
.lookupFunction<NativeUndenaryOp, UndenaryOp>("SumManyIntsOdd");
void testNativeFunctionManyArguments4() {
Expect.equals(66, sumManyIntsOdd(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
}
typedef NativeDoubleDecenaryOp = ffi.Double Function(
typedef NativeDoubleOctenaryOp = ffi.Double Function(
ffi.Double,
ffi.Double,
ffi.Double,
@ -280,11 +257,11 @@ typedef NativeDoubleDecenaryOp = ffi.Double Function(
ffi.Double,
ffi.Double,
ffi.Double);
typedef DoubleDecenaryOp = double Function(double, double, double, double,
typedef DoubleOctenaryOp = double Function(double, double, double, double,
double, double, double, double, double, double);
DoubleDecenaryOp sumManyDoubles = ffiTestFunctions
.lookupFunction<NativeDoubleDecenaryOp, DoubleDecenaryOp>("SumManyDoubles");
DoubleOctenaryOp sumManyDoubles = ffiTestFunctions
.lookupFunction<NativeDoubleOctenaryOp, DoubleOctenaryOp>("SumManyDoubles");
void testNativeFunctionManyArguments2() {
Expect.approxEquals(