Skip to content

Commit 7bf00de

Browse files
authored
Import changes from the overlay for Data mutation of slices (#1233)
* Import changes from the overlay for Data mutation of slices * Use _CFIsMainThread instead of pthread APIs * Assert on null pointers for linux targets
1 parent 0bf863d commit 7bf00de

File tree

6 files changed

+3247
-243
lines changed

6 files changed

+3247
-243
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include <pthread.h>
3030
#include <execinfo.h>
3131

32+
#if __has_include(<malloc/malloc.h>)
33+
#include <malloc/malloc.h>
34+
#endif
35+
3236
_CF_EXPORT_SCOPE_BEGIN
3337

3438
struct __CFSwiftObject {
@@ -345,6 +349,54 @@ CF_EXPORT CFStringRef _CFXDGCreateCacheDirectoryPath(void);
345349
/// a single base directory relative to which user-specific runtime files and other file objects should be placed. This directory is defined by the environment variable $XDG_RUNTIME_DIR.
346350
CF_EXPORT CFStringRef _CFXDGCreateRuntimeDirectoryPath(void);
347351

352+
353+
typedef struct {
354+
void *_Nonnull memory;
355+
size_t capacity;
356+
_Bool onStack;
357+
} _ConditionalAllocationBuffer;
358+
359+
static inline _Bool _resizeConditionalAllocationBuffer(_ConditionalAllocationBuffer *_Nonnull buffer, size_t amt) {
360+
#if TARGET_OS_MAC
361+
size_t amount = malloc_good_size(amt);
362+
#else
363+
size_t amount = amt;
364+
#endif
365+
if (amount <= buffer->capacity) { return true; }
366+
void *newMemory;
367+
if (buffer->onStack) {
368+
newMemory = malloc(amount);
369+
if (newMemory == NULL) { return false; }
370+
memcpy(newMemory, buffer->memory, buffer->capacity);
371+
buffer->onStack = false;
372+
} else {
373+
newMemory = realloc(buffer->memory, amount);
374+
if (newMemory == NULL) { return false; }
375+
}
376+
if (newMemory == NULL) { return false; }
377+
buffer->memory = newMemory;
378+
buffer->capacity = amount;
379+
return true;
380+
}
381+
382+
static inline _Bool _withStackOrHeapBuffer(size_t amount, void (__attribute__((noescape)) ^ _Nonnull applier)(_ConditionalAllocationBuffer *_Nonnull)) {
383+
_ConditionalAllocationBuffer buffer;
384+
#if TARGET_OS_MAC
385+
buffer.capacity = malloc_good_size(amount);
386+
#else
387+
buffer.capacity = amount;
388+
#endif
389+
buffer.onStack = (_CFIsMainThread() != 0 ? buffer.capacity < 2048 : buffer.capacity < 512);
390+
buffer.memory = buffer.onStack ? alloca(buffer.capacity) : malloc(buffer.capacity);
391+
if (buffer.memory == NULL) { return false; }
392+
applier(&buffer);
393+
if (!buffer.onStack) {
394+
free(buffer.memory);
395+
}
396+
return true;
397+
}
398+
399+
348400
_CF_EXPORT_SCOPE_END
349401

350402
#endif /* __COREFOUNDATION_FORSWIFTFOUNDATIONONLY__ */

0 commit comments

Comments
 (0)