Skip to content

Commit 073f733

Browse files
authored
Merge pull request #42580 from compnerd/5.7-aligned
2 parents 6fff1c4 + ff69aae commit 073f733

22 files changed

+97
-44
lines changed

include/swift/Runtime/Atomic.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,6 @@ struct aligned_alloc<Alignment_, true> {
9595
free(ptr);
9696
#endif
9797
}
98-
99-
#if defined(_WIN32)
100-
// FIXME: why is this even needed? This is not permitted as per the C++
101-
// standrd new.delete.placement (§17.6.3.4).
102-
[[nodiscard]] void *operator new(std::size_t size, void *where) noexcept {
103-
return ::operator new(size, where);
104-
}
105-
#endif
10698
};
10799

108100
/// The default implementation for swift::atomic<T>, which just wraps

include/swift/Runtime/AtomicWaitQueue.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define SWIFT_RUNTIME_ATOMICWAITQUEUE_H
2121

2222
#include "swift/Runtime/Heap.h"
23+
#include "swift/Runtime/HeapObject.h"
2324
#include "swift/Runtime/Mutex.h"
2425
#include <assert.h>
2526

@@ -84,7 +85,7 @@ class AtomicWaitQueue {
8485
/// global lock and while *not* holding the wait queue lock.
8586
void release_locked() {
8687
if (referenceCount == 1) {
87-
delete &asImpl();
88+
swift_cxx_deleteObject(&asImpl());
8889
} else {
8990
referenceCount--;
9091
}
@@ -211,7 +212,7 @@ class AtomicWaitQueue {
211212
// If we created the queue but never published it, destroy it.
212213
if (CurrentQueue) {
213214
CurrentQueue->WaitQueueLock.unlock();
214-
delete CurrentQueue;
215+
swift_cxx_deleteObject(CurrentQueue);
215216
}
216217
}
217218

@@ -425,12 +426,7 @@ class AtomicWaitQueue {
425426
private:
426427
template <class... Args>
427428
static Impl *createNewQueue(Args &&...args) {
428-
#if !defined(__cpp_aligned_new)
429-
static_assert(!swift::requires_aligned_alloc<std::alignment_of<Impl>::value>::value ||
430-
is_aligned_alloc_aware<Impl>::value,
431-
"type is over-aligned for non-alignment aware operator new");
432-
#endif
433-
auto queue = new Impl(std::forward<Args>(args)...);
429+
auto queue = swift_cxx_newObject<Impl>(std::forward<Args>(args)...);
434430
queue->WaitQueueLock.lock();
435431
return queue;
436432
}

include/swift/Runtime/HeapObject.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <cstddef>
2121
#include <cstdint>
22+
#include <new>
23+
#include <utility>
2224
#include "swift/Runtime/Config.h"
2325

2426
#if SWIFT_OBJC_INTEROP
@@ -131,6 +133,49 @@ void *swift_slowAlloc(size_t bytes, size_t alignMask);
131133
SWIFT_RUNTIME_EXPORT
132134
void swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask);
133135

136+
/// Allocate and construct an instance of type \c T.
137+
///
138+
/// \param args The arguments to pass to the constructor for \c T.
139+
///
140+
/// \returns A pointer to a new, fully constructed instance of \c T. This
141+
/// function never returns \c nullptr. The caller is responsible for
142+
/// eventually destroying the resulting object by passing it to
143+
/// \c swift_cxx_deleteObject().
144+
///
145+
/// This function avoids the use of the global \c operator \c new (which may be
146+
/// overridden by other code in a process) in favor of calling
147+
/// \c swift_slowAlloc() and constructing the new object with placement new.
148+
///
149+
/// This function is capable of returning well-aligned memory even on platforms
150+
/// that do not implement the C++17 "over-aligned new" feature.
151+
template <typename T, typename... Args>
152+
static inline T *swift_cxx_newObject(Args &&... args) {
153+
auto result = reinterpret_cast<T *>(swift_slowAlloc(sizeof(T),
154+
alignof(T) - 1));
155+
::new (result) T(std::forward<Args>(args)...);
156+
return result;
157+
}
158+
159+
/// Destruct and deallocate an instance of type \c T.
160+
///
161+
/// \param ptr A pointer to an instance of type \c T previously created with a
162+
/// call to \c swift_cxx_newObject().
163+
///
164+
/// This function avoids the use of the global \c operator \c delete (which may
165+
/// be overridden by other code in a process) in favor of directly calling the
166+
/// destructor for \a *ptr and then freeing its memory by calling
167+
/// \c swift_slowDealloc().
168+
///
169+
/// The effect of passing a pointer to this function that was \em not returned
170+
/// from \c swift_cxx_newObject() is undefined.
171+
template <typename T>
172+
static inline void swift_cxx_deleteObject(T *ptr) {
173+
if (ptr) {
174+
ptr->~T();
175+
swift_slowDealloc(ptr, sizeof(T), alignof(T) - 1);
176+
}
177+
}
178+
134179
/// Atomically increments the retain count of an object.
135180
///
136181
/// \param object - may be null, in which case this is a no-op

stdlib/public/Concurrency/Actor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "swift/Runtime/Concurrency.h"
1919
#include <atomic>
20+
#include <new>
2021

2122
#ifdef _WIN32
2223
// On Windows, an include below triggers an indirect include of minwindef.h

stdlib/public/Concurrency/AsyncLet.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <dlfcn.h>
3232
#endif
3333

34+
#include <new>
35+
3436
using namespace swift;
3537

3638
namespace {
@@ -139,7 +141,7 @@ static AsyncLetImpl *asImpl(const AsyncLet *alet) {
139141

140142
void swift::asyncLet_addImpl(AsyncTask *task, AsyncLet *asyncLet,
141143
bool didAllocateInParentTask) {
142-
AsyncLetImpl *impl = new (asyncLet) AsyncLetImpl(task);
144+
AsyncLetImpl *impl = ::new (asyncLet) AsyncLetImpl(task);
143145
impl->setDidAllocateFromParentTask(didAllocateInParentTask);
144146

145147
auto record = impl->getTaskRecord();

stdlib/public/Concurrency/Task.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "Debug.h"
2929
#include "Error.h"
3030
#include <atomic>
31+
#include <new>
3132

3233
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
3334
#include <dispatch/dispatch.h>
@@ -770,20 +771,20 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
770771
// Initialize the child fragment if applicable.
771772
if (parent) {
772773
auto childFragment = task->childFragment();
773-
new (childFragment) AsyncTask::ChildFragment(parent);
774+
::new (childFragment) AsyncTask::ChildFragment(parent);
774775
}
775776

776777
// Initialize the group child fragment if applicable.
777778
if (group) {
778779
auto groupChildFragment = task->groupChildFragment();
779-
new (groupChildFragment) AsyncTask::GroupChildFragment(group);
780+
::new (groupChildFragment) AsyncTask::GroupChildFragment(group);
780781
}
781782

782783
// Initialize the future fragment if applicable.
783784
if (futureResultType) {
784785
assert(task->isFuture());
785786
auto futureFragment = task->futureFragment();
786-
new (futureFragment) FutureFragment(futureResultType);
787+
::new (futureFragment) FutureFragment(futureResultType);
787788

788789
// Set up the context for the future so there is no error, and a successful
789790
// result will be written into the future fragment's storage.
@@ -1202,7 +1203,7 @@ swift_task_addCancellationHandlerImpl(
12021203
void *allocation =
12031204
swift_task_alloc(sizeof(CancellationNotificationStatusRecord));
12041205
auto unsigned_handler = swift_auth_code(handler, 3848);
1205-
auto *record = new (allocation)
1206+
auto *record = ::new (allocation)
12061207
CancellationNotificationStatusRecord(unsigned_handler, context);
12071208

12081209
bool fireHandlerNow = false;
@@ -1237,7 +1238,7 @@ swift_task_createNullaryContinuationJobImpl(
12371238
void *allocation =
12381239
swift_task_alloc(sizeof(NullaryContinuationJob));
12391240
auto *job =
1240-
new (allocation) NullaryContinuationJob(
1241+
::new (allocation) NullaryContinuationJob(
12411242
swift_task_getCurrent(), static_cast<JobPriority>(priority),
12421243
continuation);
12431244

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "string"
3434
#include "queue" // TODO: remove and replace with usage of our mpsc queue
3535
#include <atomic>
36+
#include <new>
3637
#include <assert.h>
3738
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
3839
#include <dispatch/dispatch.h>
@@ -469,7 +470,7 @@ SWIFT_CC(swift)
469470
static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
470471
SWIFT_TASK_DEBUG_LOG("creating task group = %p", group);
471472

472-
TaskGroupImpl *impl = new (group) TaskGroupImpl(T);
473+
TaskGroupImpl *impl = ::new (group) TaskGroupImpl(T);
473474
auto record = impl->getTaskRecord();
474475
assert(impl == record && "the group IS the task record");
475476

stdlib/public/Concurrency/TaskLocal.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/ABI/Metadata.h"
2525
#include "llvm/ADT/PointerIntPair.h"
2626
#include "TaskPrivate.h"
27+
#include <new>
2728
#include <set>
2829

2930
#if SWIFT_STDLIB_HAS_ASL
@@ -207,7 +208,7 @@ TaskLocal::Item::createLink(AsyncTask *task,
207208
size_t amountToAllocate = Item::itemSize(valueType);
208209
void *allocation = task ? _swift_task_alloc_specific(task, amountToAllocate)
209210
: malloc(amountToAllocate);
210-
Item *item = new (allocation) Item(key, valueType);
211+
Item *item = ::new (allocation) Item(key, valueType);
211212

212213
auto next = task ? task->_private().Local.head
213214
: FallbackTaskLocalStorage::get()->head;

stdlib/public/Concurrency/TaskPrivate.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/Runtime/Heap.h"
3030
#include "swift/Runtime/HeapObject.h"
3131
#include <atomic>
32+
#include <new>
3233

3334
#define SWIFT_FATAL_ERROR swift_Concurrency_fatalError
3435
#include "../runtime/StackAllocator.h"
@@ -655,11 +656,11 @@ AsyncTask::OpaquePrivateStorage::get() const {
655656
return reinterpret_cast<const PrivateStorage &>(*this);
656657
}
657658
inline void AsyncTask::OpaquePrivateStorage::initialize(JobPriority basePri) {
658-
new (this) PrivateStorage(basePri);
659+
::new (this) PrivateStorage(basePri);
659660
}
660661
inline void AsyncTask::OpaquePrivateStorage::initializeWithSlab(
661662
JobPriority basePri, void *slab, size_t slabCapacity) {
662-
new (this) PrivateStorage(basePri, slab, slabCapacity);
663+
::new (this) PrivateStorage(basePri, slab, slabCapacity);
663664
}
664665
inline void AsyncTask::OpaquePrivateStorage::complete(AsyncTask *task) {
665666
get().complete(task);

stdlib/public/runtime/AccessibleFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/Runtime/Metadata.h"
2424

2525
#include <cstdint>
26+
#include <new>
2627

2728
using namespace swift;
2829

@@ -153,7 +154,7 @@ swift::runtime::swift_findAccessibleFunction(const char *targetNameStart,
153154
S.Cache.getOrInsert(
154155
name, [&](AccessibleFunctionCacheEntry *entry, bool created) {
155156
if (created)
156-
new (entry) AccessibleFunctionCacheEntry{name, record};
157+
::new (entry) AccessibleFunctionCacheEntry{name, record};
157158
return true;
158159
});
159160
}

stdlib/public/runtime/AnyHashableSupport.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "swift/Runtime/Debug.h"
2222
#include "swift/Runtime/HeapObject.h"
2323

24+
#include <new>
25+
2426
using namespace swift;
2527
using namespace swift::hashable_support;
2628

@@ -103,7 +105,7 @@ findHashableBaseTypeImpl(const Metadata *type) {
103105
HashableConformances.getOrInsert(key, [&](HashableConformanceEntry *entry,
104106
bool created) {
105107
if (created)
106-
new (entry) HashableConformanceEntry(key, baseTypeThatConformsToHashable);
108+
::new (entry) HashableConformanceEntry(key, baseTypeThatConformsToHashable);
107109
return true; // Keep the new entry.
108110
});
109111
return baseTypeThatConformsToHashable;

stdlib/public/runtime/AutoDiffSupport.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "swift/ABI/Metadata.h"
1515
#include "swift/Runtime/HeapObject.h"
1616

17+
#include <new>
18+
1719
using namespace swift;
1820
using namespace llvm;
1921

@@ -59,7 +61,7 @@ AutoDiffLinearMapContext *swift::swift_autoDiffCreateLinearMapContext(
5961
sizeof(AutoDiffLinearMapContext), alignof(AutoDiffLinearMapContext))
6062
+ topLevelLinearMapStructSize;
6163
auto *buffer = (AutoDiffLinearMapContext *)malloc(allocationSize);
62-
return new (buffer) AutoDiffLinearMapContext;
64+
return ::new (buffer) AutoDiffLinearMapContext;
6365
}
6466

6567
void *swift::swift_autoDiffProjectTopLevelSubcontext(

stdlib/public/runtime/HeapObject.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <cstring>
3232
#include <cstdio>
3333
#include <cstdlib>
34+
#include <new>
3435
#include <thread>
3536
#include "../SwiftShims/GlobalObjects.h"
3637
#include "../SwiftShims/RuntimeShims.h"
@@ -124,7 +125,7 @@ static HeapObject *_swift_allocObject_(HeapMetadata const *metadata,
124125
// NOTE: this relies on the C++17 guaranteed semantics of no null-pointer
125126
// check on the placement new allocator which we have observed on Windows,
126127
// Linux, and macOS.
127-
new (object) HeapObject(metadata);
128+
::new (object) HeapObject(metadata);
128129

129130
// If leak tracking is enabled, start tracking this object.
130131
SWIFT_LEAKS_START_TRACKING_OBJECT(object);

stdlib/public/runtime/KeyPaths.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "swift/Runtime/Metadata.h"
1515
#include <cstdint>
1616
#include <cstring>
17+
#include <new>
1718

1819
using namespace swift;
1920

@@ -98,7 +99,7 @@ namespace {
9899
static OpaqueValue *allocateIn(const Metadata *type,
99100
YieldOnceBuffer *buffer) {
100101
auto *temp =
101-
new (reinterpret_cast<void*>(buffer)) YieldOnceTemporary(type);
102+
::new (reinterpret_cast<void*>(buffer)) YieldOnceTemporary(type);
102103
return type->allocateBufferIn(&temp->Buffer);
103104
}
104105

stdlib/public/runtime/Metadata.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,7 @@ static ValueWitnessTable *getMutableVWTableForInit(StructMetadata *self,
23852385
// Otherwise, allocate permanent memory for it and copy the existing table.
23862386
void *memory = allocateMetadata(sizeof(ValueWitnessTable),
23872387
alignof(ValueWitnessTable));
2388-
auto newTable = new (memory) ValueWitnessTable(*oldTable);
2388+
auto newTable = ::new (memory) ValueWitnessTable(*oldTable);
23892389

23902390
// If we ever need to check layout-completeness asynchronously from
23912391
// initialization, we'll need this to be a store-release (and rely on
@@ -4653,7 +4653,7 @@ static const WitnessTable *_getForeignWitnessTable(
46534653
ForeignWitnessTables.getOrInsert(
46544654
key, [&](ForeignWitnessTableCacheEntry *entryPtr, bool created) {
46554655
if (created)
4656-
new (entryPtr)
4656+
::new (entryPtr)
46574657
ForeignWitnessTableCacheEntry(key, witnessTableCandidate);
46584658
result = entryPtr->data;
46594659
return true;

stdlib/public/runtime/MetadataImpl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "EnumImpl.h"
5252

5353
#include <cstring>
54+
#include <new>
5455
#include <type_traits>
5556

5657
namespace swift {
@@ -99,11 +100,11 @@ struct NativeBox {
99100
}
100101

101102
static T *initializeWithCopy(T *dest, T *src) {
102-
return new (dest) T(*src);
103+
return ::new (dest) T(*src);
103104
}
104105

105106
static T *initializeWithTake(T *dest, T *src) {
106-
T *result = new (dest) T(std::move(*src));
107+
T *result = ::new (dest) T(std::move(*src));
107108
src->T::~T();
108109
return result;
109110
}

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <functional>
3939
#include <vector>
4040
#include <list>
41+
#include <new>
4142

4243
using namespace swift;
4344
using namespace Demangle;
@@ -774,7 +775,7 @@ _findContextDescriptor(Demangle::NodePointer node,
774775
*entry,
775776
bool created) {
776777
if (created)
777-
new (entry) NominalTypeDescriptorCacheEntry{mangledName, foundContext};
778+
::new (entry) NominalTypeDescriptorCacheEntry{mangledName, foundContext};
778779
return true;
779780
});
780781

@@ -931,7 +932,7 @@ _findProtocolDescriptor(NodePointer node,
931932
*entry,
932933
bool created) {
933934
if (created)
934-
new (entry) ProtocolDescriptorCacheEntry{mangledName, foundProtocol};
935+
::new (entry) ProtocolDescriptorCacheEntry{mangledName, foundProtocol};
935936
return true;
936937
});
937938
}

0 commit comments

Comments
 (0)