mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
[vm] Fix kNumberOfReservedCpuRegisters on ARM64
Instead of using an integer literal use constexpr popcount function instead. The misalignment causes an incorrect generation of a call to a shared write barrier stub for the last allocatable register on ARM64. Reported by Lin Zuojian <zuojian.lzj@alibaba-inc.com> TEST=ci Change-Id: I69ce32da958573be0ec8967e462f8a378a778a28 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254401 Commit-Queue: Slava Egorov <vegorov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
d23c1b9d88
commit
afb34fb9e3
7 changed files with 281 additions and 278 deletions
|
@ -29,34 +29,6 @@ uintptr_t Utils::RoundUpToPowerOfTwo(uintptr_t x) {
|
|||
return x + 1;
|
||||
}
|
||||
|
||||
int Utils::CountOneBits64(uint64_t x) {
|
||||
// Apparently there are x64 chips without popcount.
|
||||
#if __GNUC__ && !defined(HOST_ARCH_IA32) && !defined(HOST_ARCH_X64)
|
||||
return __builtin_popcountll(x);
|
||||
#else
|
||||
x = x - ((x >> 1) & 0x5555555555555555);
|
||||
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
|
||||
x = (((x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f) * 0x0101010101010101) >> 56;
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Utils::CountOneBits32(uint32_t x) {
|
||||
// Apparently there are x64 chips without popcount.
|
||||
#if __GNUC__ && !defined(HOST_ARCH_IA32) && !defined(HOST_ARCH_X64)
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
|
||||
// figure 5-2, page 66, where the function is called pop.
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
x = (x + (x >> 4)) & 0x0F0F0F0F;
|
||||
x = x + (x >> 8);
|
||||
x = x + (x >> 16);
|
||||
return static_cast<int>(x & 0x0000003F);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Utils::CountLeadingZeros64(uint64_t x) {
|
||||
#if defined(ARCH_IS_32_BIT)
|
||||
const uint32_t x_hi = static_cast<uint32_t>(x >> 32);
|
||||
|
@ -110,21 +82,21 @@ int Utils::CountTrailingZeros32(uint32_t x) {
|
|||
}
|
||||
|
||||
uint64_t Utils::ReverseBits64(uint64_t x) {
|
||||
x = ( (x >> 32) & 0x00000000ffffffff ) | ( x << 32 );
|
||||
x = ( (x >> 16) & 0x0000ffff0000ffff ) | ( (x & 0x0000ffff0000ffff) << 16 );
|
||||
x = ( (x >> 8) & 0x00ff00ff00ff00ff ) | ( (x & 0x00ff00ff00ff00ff) << 8 );
|
||||
x = ( (x >> 4) & 0x0f0f0f0f0f0f0f0f ) | ( (x & 0x0f0f0f0f0f0f0f0f) << 4 );
|
||||
x = ( (x >> 2) & 0x3333333333333333 ) | ( (x & 0x3333333333333333) << 2 );
|
||||
x = ( (x >> 1) & 0x5555555555555555 ) | ( (x & 0x5555555555555555) << 1 );
|
||||
x = ((x >> 32) & 0x00000000ffffffff) | (x << 32);
|
||||
x = ((x >> 16) & 0x0000ffff0000ffff) | ((x & 0x0000ffff0000ffff) << 16);
|
||||
x = ((x >> 8) & 0x00ff00ff00ff00ff) | ((x & 0x00ff00ff00ff00ff) << 8);
|
||||
x = ((x >> 4) & 0x0f0f0f0f0f0f0f0f) | ((x & 0x0f0f0f0f0f0f0f0f) << 4);
|
||||
x = ((x >> 2) & 0x3333333333333333) | ((x & 0x3333333333333333) << 2);
|
||||
x = ((x >> 1) & 0x5555555555555555) | ((x & 0x5555555555555555) << 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t Utils::ReverseBits32(uint32_t x) {
|
||||
x = ( (x >> 16) & 0x0000ffff ) | ( (x & 0x0000ffff) << 16 );
|
||||
x = ( (x >> 8) & 0x00ff00ff ) | ( (x & 0x00ff00ff) << 8 );
|
||||
x = ( (x >> 4) & 0x0f0f0f0f ) | ( (x & 0x0f0f0f0f) << 4 );
|
||||
x = ( (x >> 2) & 0x33333333 ) | ( (x & 0x33333333) << 2 );
|
||||
x = ( (x >> 1) & 0x55555555 ) | ( (x & 0x55555555) << 1 );
|
||||
x = ((x >> 16) & 0x0000ffff) | ((x & 0x0000ffff) << 16);
|
||||
x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
|
||||
x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
|
||||
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
|
||||
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,10 +106,35 @@ class Utils {
|
|||
|
||||
static uintptr_t RoundUpToPowerOfTwo(uintptr_t x);
|
||||
|
||||
static int CountOneBits64(uint64_t x);
|
||||
static int CountOneBits32(uint32_t x);
|
||||
static constexpr int CountOneBits64(uint64_t x) {
|
||||
// Apparently there are x64 chips without popcount.
|
||||
#if __GNUC__ && !defined(HOST_ARCH_IA32) && !defined(HOST_ARCH_X64)
|
||||
return __builtin_popcountll(x);
|
||||
#else
|
||||
x = x - ((x >> 1) & 0x5555555555555555);
|
||||
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
|
||||
x = (((x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f) * 0x0101010101010101) >> 56;
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int CountOneBitsWord(uword x) {
|
||||
static constexpr int CountOneBits32(uint32_t x) {
|
||||
// Apparently there are x64 chips without popcount.
|
||||
#if __GNUC__ && !defined(HOST_ARCH_IA32) && !defined(HOST_ARCH_X64)
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
|
||||
// figure 5-2, page 66, where the function is called pop.
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
x = (x + (x >> 4)) & 0x0F0F0F0F;
|
||||
x = x + (x >> 8);
|
||||
x = x + (x >> 16);
|
||||
return static_cast<int>(x & 0x0000003F);
|
||||
#endif
|
||||
}
|
||||
|
||||
static constexpr int CountOneBitsWord(uword x) {
|
||||
#ifdef ARCH_IS_64_BIT
|
||||
return CountOneBits64(x);
|
||||
#else
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "platform/assert.h"
|
||||
#include "platform/globals.h"
|
||||
#include "platform/utils.h"
|
||||
|
||||
#include "vm/constants_base.h"
|
||||
|
||||
|
@ -625,7 +626,8 @@ const int kAbiPreservedFpuRegCount = 4;
|
|||
const RegList kReservedCpuRegisters = (1 << SPREG) | (1 << FPREG) | (1 << TMP) |
|
||||
(1 << PP) | (1 << THR) | (1 << LR) |
|
||||
(1 << PC) | (1 << NOTFP);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 8;
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters =
|
||||
Utils::CountOneBits32(kReservedCpuRegisters);
|
||||
// CPU registers available to Dart allocator.
|
||||
constexpr RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "platform/assert.h"
|
||||
#include "platform/globals.h"
|
||||
#include "platform/utils.h"
|
||||
|
||||
#include "vm/constants_base.h"
|
||||
|
||||
|
@ -476,12 +477,13 @@ const VRegister kAbiFirstPreservedFpuReg = V8;
|
|||
const VRegister kAbiLastPreservedFpuReg = V15;
|
||||
const int kAbiPreservedFpuRegCount = 8;
|
||||
|
||||
const intptr_t kReservedCpuRegisters = R(SPREG) | // Dart SP
|
||||
R(FPREG) | R(TMP) | R(TMP2) | R(PP) |
|
||||
R(THR) | R(LR) | R(HEAP_BITS) |
|
||||
R(NULL_REG) | R(R31) | // C++ SP
|
||||
R(R18) | R(DISPATCH_TABLE_REG);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 13;
|
||||
const RegList kReservedCpuRegisters = R(SPREG) | // Dart SP
|
||||
R(FPREG) | R(TMP) | R(TMP2) | R(PP) |
|
||||
R(THR) | R(LR) | R(HEAP_BITS) |
|
||||
R(NULL_REG) | R(R31) | // C++ SP
|
||||
R(R18) | R(DISPATCH_TABLE_REG);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters =
|
||||
Utils::CountOneBits32(kReservedCpuRegisters);
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
|
|
|
@ -461,18 +461,18 @@ constexpr int kAbiPreservedCpuRegCount = 11;
|
|||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
// We rely on X18 not being touched by Dart generated assembly or stubs at all.
|
||||
// We rely on that any calls into C++ also preserve X18.
|
||||
constexpr intptr_t kReservedCpuRegisters =
|
||||
constexpr RegList kReservedCpuRegisters =
|
||||
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
|
||||
R(RA) | R(WRITE_BARRIER_STATE) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
|
||||
R(FAR_TMP) | R(18);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 15;
|
||||
#else
|
||||
constexpr intptr_t kReservedCpuRegisters =
|
||||
constexpr RegList kReservedCpuRegisters =
|
||||
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
|
||||
R(RA) | R(WRITE_BARRIER_STATE) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
|
||||
R(FAR_TMP);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 14;
|
||||
#endif
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters =
|
||||
Utils::CountOneBits32(kReservedCpuRegisters);
|
||||
// CPU registers available to Dart allocator.
|
||||
constexpr RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "platform/assert.h"
|
||||
#include "platform/globals.h"
|
||||
#include "platform/utils.h"
|
||||
|
||||
#include "vm/constants_base.h"
|
||||
|
||||
|
@ -412,7 +413,8 @@ const RegList kAllFpuRegistersList = 0xFFFF;
|
|||
|
||||
const RegList kReservedCpuRegisters =
|
||||
R(SPREG) | R(FPREG) | R(TMP) | R(PP) | R(THR);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 5;
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters =
|
||||
Utils::CountOneBits32(kReservedCpuRegisters);
|
||||
// CPU registers available to Dart allocator.
|
||||
const RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
|
|
Loading…
Reference in a new issue