1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_V8MEMORY_H_ 6 #define V8_V8MEMORY_H_ 7 8 #include "src/globals.h" 9 10 namespace v8 { 11 namespace internal { 12 13 // Memory provides an interface to 'raw' memory. It encapsulates the casts 14 // that typically are needed when incompatible pointer types are used. 15 // Note that this class currently relies on undefined behaviour. There is a 16 // proposal (http://wg21.link/p0593r2) to make it defined behaviour though. 17 template <class T> 18 T& Memory(Address addr) { 19 return *reinterpret_cast<T*>(addr); 20 } 21 template <class T> 22 T& Memory(byte* addr) { 23 return Memory<T>(reinterpret_cast<Address>(addr)); 24 } 25 26 template <typename V> 27 static inline V ReadUnalignedValue(Address p) { 28 ASSERT_TRIVIALLY_COPYABLE(V); 29 #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM) 30 return *reinterpret_cast<const V*>(p); 31 #else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM 32 V r; 33 memmove(&r, reinterpret_cast<void*>(p), sizeof(V)); 34 return r; 35 #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM 36 } 37 38 template <typename V> 39 static inline void WriteUnalignedValue(Address p, V value) { 40 ASSERT_TRIVIALLY_COPYABLE(V); 41 #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM) 42 *(reinterpret_cast<V*>(p)) = value; 43 #else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM 44 memmove(reinterpret_cast<void*>(p), &value, sizeof(V)); 45 #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM 46 } 47 48 static inline double ReadFloatValue(Address p) { 49 return ReadUnalignedValue<float>(p); 50 } 51 52 static inline double ReadDoubleValue(Address p) { 53 return ReadUnalignedValue<double>(p); 54 } 55 56 static inline void WriteDoubleValue(Address p, double value) { 57 WriteUnalignedValue(p, value); 58 } 59 60 static inline uint16_t ReadUnalignedUInt16(Address p) { 61 return ReadUnalignedValue<uint16_t>(p); 62 } 63 64 static inline void WriteUnalignedUInt16(Address p, uint16_t value) { 65 WriteUnalignedValue(p, value); 66 } 67 68 static inline uint32_t ReadUnalignedUInt32(Address p) { 69 return ReadUnalignedValue<uint32_t>(p); 70 } 71 72 static inline void WriteUnalignedUInt32(Address p, uint32_t value) { 73 WriteUnalignedValue(p, value); 74 } 75 76 template <typename V> 77 static inline V ReadLittleEndianValue(Address p) { 78 #if defined(V8_TARGET_LITTLE_ENDIAN) 79 return ReadUnalignedValue<V>(p); 80 #elif defined(V8_TARGET_BIG_ENDIAN) 81 V ret{}; 82 const byte* src = reinterpret_cast<const byte*>(p); 83 byte* dst = reinterpret_cast<byte*>(&ret); 84 for (size_t i = 0; i < sizeof(V); i++) { 85 dst[i] = src[sizeof(V) - i - 1]; 86 } 87 return ret; 88 #endif // V8_TARGET_LITTLE_ENDIAN 89 } 90 91 template <typename V> 92 static inline void WriteLittleEndianValue(Address p, V value) { 93 #if defined(V8_TARGET_LITTLE_ENDIAN) 94 WriteUnalignedValue<V>(p, value); 95 #elif defined(V8_TARGET_BIG_ENDIAN) 96 byte* src = reinterpret_cast<byte*>(&value); 97 byte* dst = reinterpret_cast<byte*>(p); 98 for (size_t i = 0; i < sizeof(V); i++) { 99 dst[i] = src[sizeof(V) - i - 1]; 100 } 101 #endif // V8_TARGET_LITTLE_ENDIAN 102 } 103 104 template <typename V> 105 static inline V ReadLittleEndianValue(V* p) { 106 return ReadLittleEndianValue<V>(reinterpret_cast<Address>(p)); 107 } 108 109 template <typename V> 110 static inline void WriteLittleEndianValue(V* p, V value) { 111 WriteLittleEndianValue<V>(reinterpret_cast<Address>(p), value); 112 } 113 114 } // namespace internal 115 } // namespace v8 116 117 #endif // V8_V8MEMORY_H_ 118