Skip to content

Commit 4f6b3c8

Browse files
committed
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 070f125 commit 4f6b3c8

File tree

5 files changed

+3243
-238
lines changed

5 files changed

+3243
-238
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

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

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

3337
struct __CFSwiftObject {
@@ -343,6 +347,54 @@ CF_EXPORT CFStringRef _CFXDGCreateCacheDirectoryPath(void);
343347
/// 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.
344348
CF_EXPORT CFStringRef _CFXDGCreateRuntimeDirectoryPath(void);
345349

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

348400
#endif /* __COREFOUNDATION_FORSWIFTFOUNDATIONONLY__ */

0 commit comments

Comments
 (0)