diff options
Diffstat (limited to 'deps/v8/src/v8memory.h')
-rw-r--r-- | deps/v8/src/v8memory.h | 167 |
1 files changed, 100 insertions, 67 deletions
diff --git a/deps/v8/src/v8memory.h b/deps/v8/src/v8memory.h index 2c38437b9eb..bf62e3b9e68 100644 --- a/deps/v8/src/v8memory.h +++ b/deps/v8/src/v8memory.h @@ -5,78 +5,111 @@ #ifndef V8_V8MEMORY_H_ #define V8_V8MEMORY_H_ +#include "src/globals.h" + namespace v8 { namespace internal { // Memory provides an interface to 'raw' memory. It encapsulates the casts // that typically are needed when incompatible pointer types are used. - -class Memory { - public: - static uint8_t& uint8_at(Address addr) { - return *reinterpret_cast<uint8_t*>(addr); - } - - static uint16_t& uint16_at(Address addr) { - return *reinterpret_cast<uint16_t*>(addr); - } - - static uint32_t& uint32_at(Address addr) { - return *reinterpret_cast<uint32_t*>(addr); - } - - static int32_t& int32_at(Address addr) { - return *reinterpret_cast<int32_t*>(addr); - } - - static uint64_t& uint64_at(Address addr) { - return *reinterpret_cast<uint64_t*>(addr); - } - - static int64_t& int64_at(Address addr) { - return *reinterpret_cast<int64_t*>(addr); - } - - static int& int_at(Address addr) { - return *reinterpret_cast<int*>(addr); - } - - static unsigned& unsigned_at(Address addr) { - return *reinterpret_cast<unsigned*>(addr); - } - - static intptr_t& intptr_at(Address addr) { - return *reinterpret_cast<intptr_t*>(addr); - } - - static uintptr_t& uintptr_at(Address addr) { - return *reinterpret_cast<uintptr_t*>(addr); - } - - static float& float_at(Address addr) { - return *reinterpret_cast<float*>(addr); - } - - static double& double_at(Address addr) { - return *reinterpret_cast<double*>(addr); - } - - static Address& Address_at(Address addr) { - return *reinterpret_cast<Address*>(addr); - } - - static Object*& Object_at(Address addr) { - return *reinterpret_cast<Object**>(addr); - } - - static Handle<Object>& Object_Handle_at(Address addr) { - return *reinterpret_cast<Handle<Object>*>(addr); - } - - static bool IsAddressInRange(Address base, Address address, uint32_t size) { - return base <= address && address < base + size; - } -}; +// Note that this class currently relies on undefined behaviour. There is a +// proposal (http://wg21.link/p0593r2) to make it defined behaviour though. +template <class T> +T& Memory(Address addr) { + return *reinterpret_cast<T*>(addr); +} +template <class T> +T& Memory(byte* addr) { + return Memory<T>(reinterpret_cast<Address>(addr)); +} + +template <typename V> +static inline V ReadUnalignedValue(Address p) { + ASSERT_TRIVIALLY_COPYABLE(V); +#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM) + return *reinterpret_cast<const V*>(p); +#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM + V r; + memmove(&r, reinterpret_cast<void*>(p), sizeof(V)); + return r; +#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM +} + +template <typename V> +static inline void WriteUnalignedValue(Address p, V value) { + ASSERT_TRIVIALLY_COPYABLE(V); +#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM) + *(reinterpret_cast<V*>(p)) = value; +#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM + memmove(reinterpret_cast<void*>(p), &value, sizeof(V)); +#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM +} + +static inline double ReadFloatValue(Address p) { + return ReadUnalignedValue<float>(p); +} + +static inline double ReadDoubleValue(Address p) { + return ReadUnalignedValue<double>(p); +} + +static inline void WriteDoubleValue(Address p, double value) { + WriteUnalignedValue(p, value); +} + +static inline uint16_t ReadUnalignedUInt16(Address p) { + return ReadUnalignedValue<uint16_t>(p); +} + +static inline void WriteUnalignedUInt16(Address p, uint16_t value) { + WriteUnalignedValue(p, value); +} + +static inline uint32_t ReadUnalignedUInt32(Address p) { + return ReadUnalignedValue<uint32_t>(p); +} + +static inline void WriteUnalignedUInt32(Address p, uint32_t value) { + WriteUnalignedValue(p, value); +} + +template <typename V> +static inline V ReadLittleEndianValue(Address p) { +#if defined(V8_TARGET_LITTLE_ENDIAN) + return ReadUnalignedValue<V>(p); +#elif defined(V8_TARGET_BIG_ENDIAN) + V ret{}; + const byte* src = reinterpret_cast<const byte*>(p); + byte* dst = reinterpret_cast<byte*>(&ret); + for (size_t i = 0; i < sizeof(V); i++) { + dst[i] = src[sizeof(V) - i - 1]; + } + return ret; +#endif // V8_TARGET_LITTLE_ENDIAN +} + +template <typename V> +static inline void WriteLittleEndianValue(Address p, V value) { +#if defined(V8_TARGET_LITTLE_ENDIAN) + WriteUnalignedValue<V>(p, value); +#elif defined(V8_TARGET_BIG_ENDIAN) + byte* src = reinterpret_cast<byte*>(&value); + byte* dst = reinterpret_cast<byte*>(p); + for (size_t i = 0; i < sizeof(V); i++) { + dst[i] = src[sizeof(V) - i - 1]; + } +#endif // V8_TARGET_LITTLE_ENDIAN +} + +template <typename V> +static inline V ReadLittleEndianValue(V* p) { + return ReadLittleEndianValue<V>(reinterpret_cast<Address>(p)); +} + +template <typename V> +static inline void WriteLittleEndianValue(V* p, V value) { + WriteLittleEndianValue<V>(reinterpret_cast<Address>(p), value); +} } // namespace internal } // namespace v8 |