[vm] Some pieces for Windows ARM support.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/47824
Change-Id: Iaf401f4d25fc5bf171170728d4a5d3ae6ef17527
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239369
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2022-03-30 19:01:33 +00:00 committed by Commit Bot
parent b55dc762fa
commit f2d3051598
7 changed files with 39 additions and 16 deletions

View file

@ -200,10 +200,10 @@ struct simd128_value_t {
#elif defined(_M_IX86) || defined(__i386__)
#define HOST_ARCH_IA32 1
#define ARCH_IS_32_BIT 1
#elif defined(__ARMEL__)
#elif defined(_M_ARM) || defined(__ARMEL__)
#define HOST_ARCH_ARM 1
#define ARCH_IS_32_BIT 1
#elif defined(__aarch64__)
#elif defined(_M_ARM64) || defined(__aarch64__)
#define HOST_ARCH_ARM64 1
#define ARCH_IS_64_BIT 1
#elif defined(__riscv)

View file

@ -1610,6 +1610,10 @@ void Assembler::SetupCSPFromThread(Register thr) {
// frames before doing an overflow check.)
ldr(TMP, Address(thr, target::Thread::saved_stack_limit_offset()));
AddImmediate(CSP, TMP, -4096);
// TODO(47824): This will probably cause signal handlers on Windows to crash.
// Windows requires the stack to grow in order, one page at a time, but
// pushing CSP to near the stack limit likely skips over many pages.
}
void Assembler::RestoreCSP() {

View file

@ -49,7 +49,7 @@ namespace dart {
// The Linux/Android ABI and the iOS ABI differ in their choice of frame
// pointer, their treatment of R9, and the interprocedural stack alignment.
// EABI (Linux, Android)
// EABI (Linux, Android, Windows)
// See "Procedure Call Standard for the ARM Architecture".
// R0-R1: Argument / result / volatile
// R2-R3: Argument / volatile
@ -61,9 +61,10 @@ namespace dart {
// R15: Program counter
// Stack alignment: 4 bytes always, 8 bytes at public interfaces
// Linux (Debian armhf) and Android also differ in whether floating point
// arguments are passed in floating point registers. Linux uses hardfp and
// Android uses softfp. See TargetCPUFeatures::hardfp_supported().
// Linux (Debian armhf), Windows and Android also differ in whether floating
// point arguments are passed in floating point registers. Linux and Windows
// use hardfp and Android uses softfp. See
// TargetCPUFeatures::hardfp_supported().
// iOS ABI
// See "iOS ABI Function Call Guide"
@ -92,7 +93,7 @@ enum Register {
R8 = 8,
R9 = 9,
R10 = 10, // THR
R11 = 11, // Linux FP
R11 = 11, // Linux/Android/Windows FP
R12 = 12, // IP aka TMP
R13 = 13, // SP
R14 = 14, // LR

View file

@ -49,7 +49,7 @@ enum Register {
R15 = 15, // SP in Dart code.
R16 = 16, // IP0 aka TMP
R17 = 17, // IP1 aka TMP2
R18 = 18, // reserved on iOS, shadow call stack on Fuchsia.
R18 = 18, // reserved on iOS, shadow call stack on Fuchsia, TEB on Windows.
R19 = 19,
R20 = 20,
R21 = 21, // DISPATCH_TABLE_REG

View file

@ -16,6 +16,8 @@
#if defined(DART_HOST_OS_IOS)
#include <libkern/OSCacheControl.h>
#elif defined(DART_HOST_OS_WINDOWS)
#include <processthreadsapi.h>
#endif
#if !defined(TARGET_HOST_MISMATCH)
@ -88,6 +90,10 @@ void CPU::FlushICache(uword start, uword size) {
__builtin___clear_cache(beg, end);
#elif defined(DART_HOST_OS_ANDROID)
cacheflush(start, start + size, 0);
#elif defined(DART_HOST_OS_WINDOWS)
BOOL result = FlushInstructionCache(
GetCurrentProcess(), reinterpret_cast<const void*>(start), size);
ASSERT(result != 0);
#else
#error FlushICache only tested/supported on Linux, Android and iOS
#endif
@ -126,6 +132,16 @@ void HostCPUFeatures::Init() {
initialized_ = true;
#endif
}
#elif DART_HOST_OS_WINDOWS
void HostCPUFeatures::Init() {
hardware_ = "";
integer_division_supported_ = true;
neon_supported_ = true;
hardfp_supported_ = true;
#if defined(DEBUG)
initialized_ = true;
#endif
}
#else // DART_HOST_OS_IOS
void HostCPUFeatures::Init() {
bool is_arm64 = false;

View file

@ -22,6 +22,8 @@
#if defined(DART_HOST_OS_MACOS) || defined(DART_HOST_OS_IOS)
#include <libkern/OSCacheControl.h>
#elif defined(DART_HOST_OS_WINDOWS)
#include <processthreadsapi.h>
#endif
namespace dart {
@ -52,6 +54,10 @@ void CPU::FlushICache(uword start, uword size) {
zx_status_t result = zx_cache_flush(reinterpret_cast<const void*>(start),
size, ZX_CACHE_FLUSH_INSN);
ASSERT(result == ZX_OK);
#elif defined(DART_HOST_OS_WINDOWS)
BOOL result = FlushInstructionCache(
GetCurrentProcess(), reinterpret_cast<const void*>(start), size);
ASSERT(result != 0);
#else
#error FlushICache not implemented for this OS
#endif

View file

@ -172,14 +172,10 @@ bool OSThread::Compare(ThreadId a, ThreadId b) {
}
bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) {
// On Windows stack limits for the current thread are available in
// the thread information block (TIB). Its fields can be accessed through
// FS segment register on x86 and GS segment register on x86_64.
#ifdef _WIN64
*upper = static_cast<uword>(__readgsqword(offsetof(NT_TIB64, StackBase)));
#else
*upper = static_cast<uword>(__readfsdword(offsetof(NT_TIB, StackBase)));
#endif
// On Windows stack limits for the current thread are available in
// the thread information block (TIB).
NT_TIB* tib = reinterpret_cast<NT_TIB*>(NtCurrentTeb());
*upper = reinterpret_cast<uword>(tib->StackBase);
// Notice that we cannot use the TIB's StackLimit for the stack end, as it
// tracks the end of the committed range. We're after the end of the reserved
// stack area (most of which will be uncommitted, most times).