diff --git a/src/asmjit/core/api-config.h b/src/asmjit/core/api-config.h index 2b726ca..dd50475 100644 --- a/src/asmjit/core/api-config.h +++ b/src/asmjit/core/api-config.h @@ -44,7 +44,6 @@ #include #include -#include #include #include diff --git a/src/asmjit/core/builder.cpp b/src/asmjit/core/builder.cpp index 9ec29b9..4b76122 100644 --- a/src/asmjit/core/builder.cpp +++ b/src/asmjit/core/builder.cpp @@ -65,7 +65,7 @@ Error BaseBuilder::newInstNode(InstNode** out, InstId instId, InstOptions instOp if (ASMJIT_UNLIKELY(!node)) return reportError(DebugUtils::errored(kErrorOutOfMemory)); - *out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity); + *out = new(Support::PlacementNew{node}) InstNode(this, instId, instOptions, opCount, opCapacity); return kErrorOk; } @@ -621,7 +621,7 @@ Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1, return reportError(DebugUtils::errored(kErrorOutOfMemory)); } - node = new(node) InstNode(this, instId, options, opCount, opCapacity); + node = new(Support::PlacementNew{node}) InstNode(this, instId, options, opCount, opCapacity); node->setExtraReg(extraReg()); node->setOp(0, o0); node->setOp(1, o1); diff --git a/src/asmjit/core/compiler.cpp b/src/asmjit/core/compiler.cpp index f7cca47..b09ae39 100644 --- a/src/asmjit/core/compiler.cpp +++ b/src/asmjit/core/compiler.cpp @@ -248,7 +248,7 @@ Error BaseCompiler::newVirtReg(VirtReg** out, TypeId typeId, OperandSignature si uint32_t size = TypeUtils::sizeOf(typeId); uint32_t alignment = Support::min(size, 64); - vReg = new(vReg) VirtReg(signature, Operand::indexToVirtId(index), size, alignment, typeId); + vReg = new(Support::PlacementNew{vReg}) VirtReg(signature, Operand::indexToVirtId(index), size, alignment, typeId); #ifndef ASMJIT_NO_LOGGING if (name && name[0] != '\0') @@ -490,7 +490,7 @@ Error BaseCompiler::newJumpNode(JumpNode** out, InstId instId, InstOptions instO if (ASMJIT_UNLIKELY(!node)) return reportError(DebugUtils::errored(kErrorOutOfMemory)); - node = new(node) JumpNode(this, instId, instOptions, opCount, annotation); + node = new(Support::PlacementNew{node}) JumpNode(this, instId, instOptions, opCount, annotation); node->setOp(0, o0); node->resetOpRange(opCount, JumpNode::kBaseOpCapacity); diff --git a/src/asmjit/core/constpool.h b/src/asmjit/core/constpool.h index 036b80f..067c73d 100644 --- a/src/asmjit/core/constpool.h +++ b/src/asmjit/core/constpool.h @@ -167,7 +167,7 @@ public: Node* node = zone->allocT(sizeof(Node) + size); if (ASMJIT_UNLIKELY(!node)) return nullptr; - node = new(node) Node(offset, shared); + node = new(Support::PlacementNew{node}) Node(offset, shared); memcpy(node->data(), data, size); return node; } diff --git a/src/asmjit/core/globals.h b/src/asmjit/core/globals.h index 1dfc7de..dbf8881 100644 --- a/src/asmjit/core/globals.h +++ b/src/asmjit/core/globals.h @@ -25,17 +25,12 @@ namespace Support { ASMJIT_FORCE_INLINE void operatorDelete(void* p) noexcept { if (p) free(p); } } // {Support} -#define ASMJIT_BASE_CLASS(TYPE) \ - ASMJIT_FORCE_INLINE void* operator new(size_t n) noexcept { \ - return Support::operatorNew(n); \ - } \ - \ - ASMJIT_FORCE_INLINE void operator delete(void* p) noexcept { \ - Support::operatorDelete(p); \ - } \ - \ - ASMJIT_FORCE_INLINE void* operator new(size_t, void* p) noexcept { return p; } \ - ASMJIT_FORCE_INLINE void operator delete(void*, void*) noexcept {} +#define ASMJIT_BASE_CLASS(TYPE) \ + ASMJIT_FORCE_INLINE void* operator new(size_t n) noexcept { return Support::operatorNew(n); } \ + ASMJIT_FORCE_INLINE void operator delete(void* ptr) noexcept { Support::operatorDelete(ptr); } \ + \ + ASMJIT_FORCE_INLINE void* operator new(size_t, void* ptr) noexcept { return ptr; } \ + ASMJIT_FORCE_INLINE void operator delete(void*, void*) noexcept {} #else #define ASMJIT_BASE_CLASS(TYPE) #endif diff --git a/src/asmjit/core/jitallocator.cpp b/src/asmjit/core/jitallocator.cpp index 0ce1fa3..3aef8c5 100644 --- a/src/asmjit/core/jitallocator.cpp +++ b/src/asmjit/core/jitallocator.cpp @@ -476,7 +476,7 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator:: } JitAllocatorPool* pools = reinterpret_cast((uint8_t*)p + sizeof(JitAllocatorPrivateImpl)); - JitAllocatorPrivateImpl* impl = new(p) JitAllocatorPrivateImpl(pools, poolCount); + JitAllocatorPrivateImpl* impl = new(Support::PlacementNew{p}) JitAllocatorPrivateImpl(pools, poolCount); impl->options = options; impl->blockSize = blockSize; @@ -485,7 +485,7 @@ static inline JitAllocatorPrivateImpl* JitAllocatorImpl_new(const JitAllocator:: impl->pageSize = vmInfo.pageSize; for (size_t poolId = 0; poolId < poolCount; poolId++) - new(&pools[poolId]) JitAllocatorPool(granularity << poolId); + new(Support::PlacementNew{&pools[poolId]}) JitAllocatorPool(granularity << poolId); return impl; } @@ -632,7 +632,7 @@ static Error JitAllocatorImpl_newBlock(JitAllocatorPrivateImpl* impl, JitAllocat } BitWord* bitWords = reinterpret_cast(blockPtr + sizeof(JitAllocatorBlock)); - *dst = new(blockPtr) JitAllocatorBlock(pool, virtMem, blockSize, blockFlags, bitWords, bitWords + numBitWords, areaSize); + *dst = new(Support::PlacementNew{blockPtr}) JitAllocatorBlock(pool, virtMem, blockSize, blockFlags, bitWords, bitWords + numBitWords, areaSize); return kErrorOk; } diff --git a/src/asmjit/core/rapass.cpp b/src/asmjit/core/rapass.cpp index 0fc1a00..a5b1167 100644 --- a/src/asmjit/core/rapass.cpp +++ b/src/asmjit/core/rapass.cpp @@ -1165,7 +1165,7 @@ ASMJIT_FAVOR_SPEED Error BaseRAPass::initGlobalLiveSpans() noexcept { return DebugUtils::errored(kErrorOutOfMemory); for (size_t physId = 0; physId < physCount; physId++) - new(&liveSpans[physId]) LiveRegSpans(); + new(Support::PlacementNew{&liveSpans[physId]}) LiveRegSpans(); } _globalLiveSpans[group] = liveSpans; diff --git a/src/asmjit/core/rapass_p.h b/src/asmjit/core/rapass_p.h index a96fdef..2e81221 100644 --- a/src/asmjit/core/rapass_p.h +++ b/src/asmjit/core/rapass_p.h @@ -882,7 +882,7 @@ public: void* p = zone()->alloc(RAInst::sizeOf(tiedRegCount)); if (ASMJIT_UNLIKELY(!p)) return nullptr; - return new(p) RAInst(block, instRWFlags, flags, tiedRegCount, clobberedRegs); + return new(Support::PlacementNew{p}) RAInst(block, instRWFlags, flags, tiedRegCount, clobberedRegs); } ASMJIT_FORCE_INLINE Error assignRAInst(BaseNode* node, RABlock* block, RAInstBuilder& ib) noexcept { diff --git a/src/asmjit/core/support.h b/src/asmjit/core/support.h index 5ba726c..096945f 100644 --- a/src/asmjit/core/support.h +++ b/src/asmjit/core/support.h @@ -21,6 +21,12 @@ ASMJIT_BEGIN_NAMESPACE //! here is considered internal and should not be used outside of AsmJit and related projects like AsmTK. namespace Support { +// Support - Placement New +// ======================= + +//! Helper to implement placement new/delete without relying on `` header. +struct PlacementNew { void* ptr; }; + // Support - Basic Traits // ====================== @@ -1759,4 +1765,14 @@ struct Temporary { ASMJIT_END_NAMESPACE +//! Implementation of a placement new so we don't have to depend on ``. +ASMJIT_INLINE_NODEBUG void* operator new(size_t, const asmjit::Support::PlacementNew& p) noexcept { +#if defined(_MSC_VER) && !defined(__clang__) + __assume(p.ptr != nullptr); // Otherwise MSVC would emit a nullptr check. +#endif + return p.ptr; +} + +ASMJIT_INLINE_NODEBUG void operator delete(void*, const asmjit::Support::PlacementNew&) noexcept {} + #endif // ASMJIT_CORE_SUPPORT_H_INCLUDED diff --git a/src/asmjit/core/zone.h b/src/asmjit/core/zone.h index 7edd16b..b61a3d1 100644 --- a/src/asmjit/core/zone.h +++ b/src/asmjit/core/zone.h @@ -322,7 +322,7 @@ public: void* p = alloc(sizeof(T), alignof(T)); if (ASMJIT_UNLIKELY(!p)) return nullptr; - return new(p) T(); + return new(Support::PlacementNew{p}) T(); } //! Like `new(std::nothrow) T(...)`, but allocated by `Zone`. @@ -331,7 +331,7 @@ public: void* p = alloc(sizeof(T), alignof(T)); if (ASMJIT_UNLIKELY(!p)) return nullptr; - return new(p) T(std::forward(args)...); + return new(Support::PlacementNew{p}) T(std::forward(args)...); } //! \cond INTERNAL @@ -573,7 +573,7 @@ public: void* p = allocT(); if (ASMJIT_UNLIKELY(!p)) return nullptr; - return new(p) T(); + return new(Support::PlacementNew{p}) T(); } //! Like `new(std::nothrow) T(...)`, but allocated by `Zone`. template @@ -581,7 +581,7 @@ public: void* p = allocT(); if (ASMJIT_UNLIKELY(!p)) return nullptr; - return new(p) T(std::forward(args)...); + return new(Support::PlacementNew{p}) T(std::forward(args)...); } //! Releases the memory previously allocated by `alloc()`. The `size` argument has to be the same as used to call