Skip to content

Commit

Permalink
Refactor utils.
Browse files Browse the repository at this point in the history
  • Loading branch information
rmacnak committed Nov 2, 2024
1 parent 2e39917 commit c485767
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 160 deletions.
51 changes: 27 additions & 24 deletions vm/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#if !defined(WIN32_LEAN_AND_MEAN)
#define WIN32_LEAN_AND_MEAN
#endif
#if !defined(NOMINMAX)
#define NOMINMAX
#endif

#include <windows.h>
#endif // defined(_WIN32)
Expand Down Expand Up @@ -111,41 +114,41 @@ typedef uintptr_t uword;
typedef decltype(nullptr) nullptr_t;

// Byte sizes.
constexpr int kWordSize = sizeof(word);
constexpr int kDoubleSize = sizeof(double);
constexpr int kFloatSize = sizeof(float);
constexpr int kInt32Size = sizeof(int32_t);
constexpr int kInt16Size = sizeof(int16_t);
constexpr size_t kWordSize = sizeof(word);
constexpr size_t kDoubleSize = sizeof(double);
constexpr size_t kFloatSize = sizeof(float);
constexpr size_t kInt32Size = sizeof(int32_t);
constexpr size_t kInt16Size = sizeof(int16_t);
#if defined(ARCH_IS_32_BIT)
constexpr int kWordSizeLog2 = 2;
constexpr size_t kWordSizeLog2 = 2;
constexpr uword kUwordMax = kMaxUint32;
#elif defined(ARCH_IS_64_BIT)
constexpr int kWordSizeLog2 = 3;
constexpr size_t kWordSizeLog2 = 3;
constexpr uword kUwordMax = kMaxUint64;
#endif

// Bit sizes.
constexpr int kBitsPerByte = 8;
constexpr int kBitsPerWord = kWordSize * kBitsPerByte;
constexpr size_t kBitsPerByte = 8;
constexpr size_t kBitsPerWord = kWordSize * kBitsPerByte;

// System-wide named constants.
constexpr intptr_t KB = 1024;
constexpr intptr_t KBLog2 = 10;
constexpr intptr_t MB = KB * KB;
constexpr intptr_t MBLog2 = KBLog2 + KBLog2;
constexpr intptr_t GB = MB * KB;
constexpr intptr_t GBLog2 = MBLog2 + KBLog2;
constexpr size_t KB = 1024;
constexpr size_t KBLog2 = 10;
constexpr size_t MB = KB * KB;
constexpr size_t MBLog2 = KBLog2 + KBLog2;
constexpr size_t GB = MB * KB;
constexpr size_t GBLog2 = MBLog2 + KBLog2;

// Time constants.
constexpr int kMillisecondsPerSecond = 1000;
constexpr int kMicrosecondsPerMillisecond = 1000;
constexpr int kMicrosecondsPerSecond = (kMicrosecondsPerMillisecond *
kMillisecondsPerSecond);
constexpr int kNanosecondsPerMicrosecond = 1000;
constexpr int kNanosecondsPerMillisecond = (kNanosecondsPerMicrosecond *
kMicrosecondsPerMillisecond);
constexpr int kNanosecondsPerSecond = (kNanosecondsPerMicrosecond *
kMicrosecondsPerSecond);
constexpr int64_t kMillisecondsPerSecond = 1000;
constexpr int64_t kMicrosecondsPerMillisecond = 1000;
constexpr int64_t kMicrosecondsPerSecond = (kMicrosecondsPerMillisecond *
kMillisecondsPerSecond);
constexpr int64_t kNanosecondsPerMicrosecond = 1000;
constexpr int64_t kNanosecondsPerMillisecond = (kNanosecondsPerMicrosecond *
kMicrosecondsPerMillisecond);
constexpr int64_t kNanosecondsPerSecond = (kNanosecondsPerMicrosecond *
kMicrosecondsPerSecond);

// A macro to disallow the copy constructor and operator= functions.
// This should be used in the private: declarations for a class.
Expand Down
2 changes: 1 addition & 1 deletion vm/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class FreeList {
// Languages, Programming, Systems, and Applications. 1997.
class Heap {
private:
static constexpr intptr_t kLargeAllocationSize = 32 * KB;
static constexpr size_t kLargeAllocationSize = 32 * KB;
static constexpr intptr_t kRememberedSetOverflowSize = 8 * KB;
static constexpr size_t kInitialSemispaceCapacity = sizeof(uword) * MB / 8;
static constexpr size_t kMaxSemispaceCapacity = 2 * sizeof(uword) * MB;
Expand Down
159 changes: 44 additions & 115 deletions vm/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,121 +5,87 @@
#ifndef VM_MATH_H_
#define VM_MATH_H_

#include <limits>
#include <type_traits>

#include "vm/assert.h"
#include "vm/globals.h"

namespace psoup {

class Math {
public:
static inline bool AddHasOverflow64(int64_t left,
int64_t right,
int64_t* result) {
template <typename T>
static inline bool AddHasOverflow(T left, T right, T* result) {
if (TEST_SLOW_PATH) return true;

#if defined(__GNUC__)
#if __GNUC__ >= 5
#define HAS_BUILTIN_ADD_OVERFLOW
#endif
#endif

#if defined(__has_builtin)
#if __has_builtin(__builtin_add_overflow)
#define HAS_BUILTIN_ADD_OVERFLOW
#endif
#elif defined(__GNUC__)
#if __GNUC__ >= 5
#define HAS_BUILTIN_ADD_OVERFLOW
#endif
#endif

#if defined(HAS_BUILTIN_ADD_OVERFLOW)
return __builtin_add_overflow(left, right, result);
#else
if (((right > 0) && (left > (INT64_MAX - right))) ||
((right < 0) && (left < (INT64_MIN - right)))) {
if (((right > 0) && (left > (std::numeric_limits<T>::max() - right))) ||
((right < 0) && (left < (std::numeric_limits<T>::min() - right)))) {
return true;
}
*result = left + right;
return false;
#endif
}

static inline bool SubtractHasOverflow64(int64_t left,
int64_t right,
int64_t* result) {
template <typename T>
static inline bool SubtractHasOverflow(T left, T right, T* result) {
if (TEST_SLOW_PATH) return true;

#if defined(__GNUC__)
#if __GNUC__ >= 5
#define HAS_BUILTIN_SUB_OVERFLOW
#endif
#endif

#if defined(__has_builtin)
#if __has_builtin(__builtin_sub_overflow)
#define HAS_BUILTIN_SUB_OVERFLOW
#endif
#elif defined(__GNUC__)
#if __GNUC__ >= 5
#define HAS_BUILTIN_SUB_OVERFLOW
#endif
#endif

#if defined(HAS_BUILTIN_SUB_OVERFLOW)
return __builtin_sub_overflow(left, right, result);
#else
if (((right > 0) && (left < (INT64_MIN + right))) ||
((right < 0) && (left > (INT64_MAX + right)))) {
if (((right > 0) && (left < (std::numeric_limits<T>::min() + right))) ||
((right < 0) && (left > (std::numeric_limits<T>::max() + right)))) {
return true;
}
*result = left - right;
return false;
#endif
}

static inline bool MultiplyHasOverflow(intptr_t left,
intptr_t right,
intptr_t* result) {
template <typename T>
static inline bool MultiplyHasOverflow(T left, T right, T* result) {
if (TEST_SLOW_PATH) return true;

#if defined(__GNUC__)
#if __GNUC__ >= 5
#define HAS_BUILTIN_MUL_OVERFLOW
#endif
#endif

#if defined(__has_builtin)
#if __has_builtin(__builtin_mul_overflow)
#define HAS_BUILTIN_MUL_OVERFLOW
#endif
#endif

#if defined(HAS_BUILTIN_MUL_OVERFLOW)
return __builtin_mul_overflow(left, right, result);
#else
const intptr_t kMaxBits = (sizeof(intptr_t) * 8) - 2;
if ((Utils::HighestBit(left) + Utils::HighestBit(right)) < kMaxBits) {
*result = left * right;
return false;
}
return true;
#endif
}

static inline bool MultiplyHasOverflow64(int64_t left,
int64_t right,
int64_t* result) {
if (TEST_SLOW_PATH) return true;

#if defined(__GNUC__)
#elif defined(__GNUC__)
#if __GNUC__ >= 5
#define HAS_BUILTIN_MUL_OVERFLOW
#endif
#endif

#if defined(__has_builtin)
#if __has_builtin(__builtin_mul_overflow)
#define HAS_BUILTIN_MUL_OVERFLOW
#endif
#endif

#if defined(HAS_BUILTIN_MUL_OVERFLOW)
return __builtin_mul_overflow(left, right, result);
#else
if ((Utils::HighestBit(left) + Utils::HighestBit(right)) < 62) {
constexpr intptr_t kMaxBits = (sizeof(T) * kBitsPerByte) - 2;
if ((Utils::HighestBit(left) + Utils::HighestBit(right)) < kMaxBits) {
*result = left * right;
return false;
}
Expand All @@ -129,48 +95,26 @@ class Math {

// See DAAN LEIJEN. "Division and Modulus for Computer Scientists". 2001.

static inline intptr_t TruncDiv(intptr_t dividend, intptr_t divisor) {
ASSERT(divisor != 0);
ASSERT((divisor != -1) || (dividend != INTPTR_MIN));
return dividend / divisor; // Undefined before C99.
}

static inline int64_t TruncDiv64(int64_t dividend, int64_t divisor) {
template <typename T>
static constexpr inline T TruncDiv(T dividend, T divisor) {
ASSERT(divisor != 0);
ASSERT((divisor != -1) || (dividend != INT64_MIN));
ASSERT((divisor != -1) || (dividend != std::numeric_limits<T>::min()));
return dividend / divisor; // Undefined before C99.
}

static inline intptr_t TruncMod(intptr_t dividend, intptr_t divisor) {
template <typename T>
static constexpr inline T TruncMod(T dividend, T divisor) {
ASSERT(divisor != 0);
ASSERT((divisor != -1) || (dividend != INTPTR_MIN));
ASSERT((divisor != -1) || (dividend != std::numeric_limits<T>::min()));
return dividend % divisor; // Undefined before C99.
}

static inline int64_t TruncMod64(int64_t dividend, int64_t divisor) {
ASSERT(divisor != 0);
ASSERT((divisor != -1) || (dividend != INT64_MIN));
return dividend % divisor; // Undefined before C99.
}

static inline intptr_t FloorDiv(intptr_t dividend, intptr_t divisor) {
ASSERT(divisor != 0);
ASSERT(divisor != -1 || dividend != INTPTR_MIN);
intptr_t truncating_quoitent = dividend / divisor; // Undefined before C99.
intptr_t truncating_remainder = dividend % divisor;
if ((truncating_remainder != 0) &&
((dividend < 0) != (divisor < 0))) {
return truncating_quoitent - 1;
} else {
return truncating_quoitent;
}
}

static inline int64_t FloorDiv64(int64_t dividend, int64_t divisor) {
template <typename T>
static constexpr inline T FloorDiv(T dividend, T divisor) {
ASSERT(divisor != 0);
ASSERT(divisor != -1 || dividend != INT64_MIN);
int64_t truncating_quoitent = dividend / divisor; // Undefined before C99.
int64_t truncating_remainder = dividend % divisor;
ASSERT((divisor != -1) || (dividend != std::numeric_limits<T>::min()));
T truncating_quoitent = dividend / divisor; // Undefined before C99.
T truncating_remainder = dividend % divisor;
if ((truncating_remainder != 0) &&
((dividend < 0) != (divisor < 0))) {
return truncating_quoitent - 1;
Expand All @@ -179,24 +123,11 @@ class Math {
}
}

static inline intptr_t FloorMod(intptr_t dividend, intptr_t divisor) {
ASSERT(divisor != 0);
ASSERT(divisor != -1 || dividend != INTPTR_MIN);
intptr_t truncating_remainder = dividend % divisor;
if ((truncating_remainder != 0) &&
((truncating_remainder < 0) != (divisor < 0))) {
return truncating_remainder + divisor;
} else {
return truncating_remainder;
}
}

static inline int64_t FloorMod64(int64_t dividend, int64_t divisor) {
template <typename T>
static constexpr inline T FloorMod(T dividend, T divisor) {
ASSERT(divisor != 0);
if ((divisor == -1) && (dividend == INT64_MIN)) {
return 0;
}
int64_t truncating_remainder = dividend % divisor;
ASSERT((divisor != -1) || (dividend != std::numeric_limits<T>::min()));
T truncating_remainder = dividend % divisor;
if ((truncating_remainder != 0) &&
((truncating_remainder < 0) != (divisor < 0))) {
return truncating_remainder + divisor;
Expand All @@ -205,16 +136,14 @@ class Math {
}
}

static inline intptr_t ShiftLeft(intptr_t left, intptr_t right) {
return static_cast<intptr_t>(static_cast<uintptr_t>(left) << right);
}

static inline int64_t ShiftLeft64(int64_t left, int64_t right) {
return static_cast<int64_t>(static_cast<uint64_t>(left) << right);
template <typename T>
static constexpr inline T ShiftLeft(T left, T right) {
typedef typename std::make_unsigned<T>::type Unsigned;
return static_cast<T>(static_cast<Unsigned>(left) << right);
}

NO_SANITIZE_UNDEFINED("float-divide-by-zero")
static inline double DivideF64(double dividend, double divisor) {
static constexpr inline double DivideF64(double dividend, double divisor) {
return dividend / divisor;
}
};
Expand Down
Loading

0 comments on commit c485767

Please sign in to comment.