Loading...
--- dyld/dyld-960/common/Array.h
+++ dyld/dyld-1122.1/common/Array.h
@@ -26,12 +26,15 @@
#include <algorithm>
#include <stdint.h>
+#include <stdio.h>
#include <assert.h>
#include <stddef.h>
+#include <TargetConditionals.h>
+#include "Defines.h"
+#if !TARGET_OS_EXCLAVEKIT
#include <mach/mach.h>
-#include <TargetConditionals.h>
-
-#include "Defines.h"
+#endif
+#include "Allocator.h"
namespace dyld3 {
@@ -71,7 +74,7 @@
void remove(size_t idx) { assert(idx < _usedCount); ::memmove(&_elements[idx], &_elements[idx+1], sizeof(T)*(_usedCount-idx-1)); }
void resize(size_t count) { assert(count <= _allocCount); _usedCount = count; }
void clear() { _usedCount = 0; }
-
+
protected:
T* _elements;
uintptr_t _allocCount;
@@ -109,14 +112,17 @@
OverflowSafeArray(T* stackStorage, uintptr_t stackAllocCount) : Array<T>(stackStorage, stackAllocCount) {}
~OverflowSafeArray();
- OverflowSafeArray(OverflowSafeArray&) = default;
+ OverflowSafeArray(const OverflowSafeArray&) = delete;
+ OverflowSafeArray& operator=(const OverflowSafeArray& other) = delete;
+ OverflowSafeArray(OverflowSafeArray&&);
OverflowSafeArray& operator=(OverflowSafeArray&& other);
void push_back(const T& t) { verifySpace(1); this->_elements[this->_usedCount++] = t; }
+ void push_back(T&& t) { verifySpace(1); this->_elements[this->_usedCount++] = std::move(t); }
template <class... Args>
void emplace_back(Args&&... args) { verifySpace(1); new (&this->_elements[this->_usedCount++])T(args...); }
void default_constuct_back() { verifySpace(1); new (&this->_elements[this->_usedCount++])T(); }
- void clear() { this->_usedCount = 0; }
+ void clear();
void reserve(uintptr_t n) { if (this->_allocCount < n) growTo(n); }
void resize(uintptr_t n) {
if (n == this->_usedCount)
@@ -134,49 +140,86 @@
void verifySpace(uintptr_t n) { if (this->_usedCount+n > this->_allocCount) growTo(this->_usedCount + n); }
private:
- vm_address_t _overflowBuffer = 0;
- vm_size_t _overflowBufferSize = 0;
+ void * _overflowBuffer = 0;
+ size_t _overflowBufferSize = 0;
};
template <typename T, uintptr_t MAXCOUNT>
inline void OverflowSafeArray<T,MAXCOUNT>::growTo(uintptr_t n)
{
- vm_address_t oldBuffer = _overflowBuffer;
- vm_size_t oldBufferSize = _overflowBufferSize;
+ void * oldBuffer = _overflowBuffer;
+ size_t oldBufferSize = _overflowBufferSize;
if ( MAXCOUNT != 0xFFFFFFFF ) {
assert(oldBufferSize == 0); // only re-alloc once
// MAXCOUNT is specified, so immediately jump to that size
- _overflowBufferSize = round_page(std::max(MAXCOUNT, n) * sizeof(T));
+ //_overflowBufferSize = round_page(std::max(MAXCOUNT, n) * sizeof(T));
}
else {
// MAXCOUNT is not specified, keep doubling size
_overflowBufferSize = round_page(std::max(this->_allocCount * 2, n) * sizeof(T));
}
- kern_return_t kr = ::vm_allocate(mach_task_self(), &_overflowBuffer, _overflowBufferSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_DYLD));
- if (kr != KERN_SUCCESS) {
-#if BUILDING_LIBDYLD
+#if !TARGET_OS_EXCLAVEKIT
+ int kr = ::vm_allocate(mach_task_self(), (vm_address_t*)&_overflowBuffer, _overflowBufferSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_DYLD));
+#else
+ _overflowBuffer = lsl::MemoryManager::allocate_pages(_overflowBufferSize);
+ int kr = 0;
+#endif
+ if (kr != 0) {
+#if BUILDING_LIBDYLD && !TARGET_OS_EXCLAVEKIT
//FIXME We should figure out a way to do this in dyld
char crashString[256];
- snprintf(crashString, 256, "OverflowSafeArray failed to allocate %llu bytes, vm_allocate returned: %d\n",
- (uint64_t)_overflowBufferSize, kr);
+ snprintf(crashString, sizeof(crashString), "OverflowSafeArray failed to allocate %llu bytes, vm_allocate returned: %d\n",
+ (uint64_t)_overflowBufferSize, kr);
CRSetCrashLogMessage(crashString);
#endif
assert(0);
}
- ::memcpy((void*)_overflowBuffer, (void*)this->_elements, this->_usedCount*sizeof(T));
+
+ if constexpr (std::is_trivially_copyable<T>::value) {
+ ::memcpy((void*)_overflowBuffer, (void*)this->_elements, this->_usedCount*sizeof(T));
+ } else if constexpr (std::is_move_constructible<T>::value) {
+ //static_assert(std::is_trivially_copyable<T>::value, "Type isn't POD, but our destructor doesn't destroy elements");
+ T* newBuffer = (T*)_overflowBuffer;
+ for (uintptr_t i = 0; i != this->_usedCount; ++i)
+ new (&newBuffer[i]) T(std::move(this->_elements[i]));
+ } else {
+ static_assert(std::is_trivially_copyable<T>::value || std::is_move_constructible<T>::value,
+ "Type must be trivially copyable/move_constructible");
+ }
this->_elements = (T*)_overflowBuffer;
this->_allocCount = _overflowBufferSize / sizeof(T);
if ( oldBuffer != 0 )
- ::vm_deallocate(mach_task_self(), oldBuffer, oldBufferSize);
+#if !TARGET_OS_EXCLAVEKIT
+ ::vm_deallocate(mach_task_self(), (vm_address_t)oldBuffer, oldBufferSize);
+#else
+ lsl::MemoryManager::deallocate_pages(oldBuffer, oldBufferSize);
+#endif
+}
+
+template <typename T, uintptr_t MAXCOUNT>
+inline void OverflowSafeArray<T,MAXCOUNT>::clear()
+{
+ if constexpr (!std::is_trivially_destructible<T>::value) {
+ for (uintptr_t i = 0; i != this->_usedCount; ++i)
+ this->_elements[i].~T();
+ }
+ this->_usedCount = 0;
}
template <typename T, uintptr_t MAXCOUNT>
inline OverflowSafeArray<T,MAXCOUNT>::~OverflowSafeArray()
{
+ // Call clear in case there are element destructors to call
+ clear();
+
if ( _overflowBuffer != 0 )
- ::vm_deallocate(mach_task_self(), _overflowBuffer, _overflowBufferSize);
+#if !TARGET_OS_EXCLAVEKIT
+ ::vm_deallocate(mach_task_self(), (vm_address_t)_overflowBuffer, _overflowBufferSize);
+#else
+ lsl::MemoryManager::deallocate_pages(_overflowBuffer, _overflowBufferSize);
+#endif
}
template <typename T, uintptr_t MAXCOUNT>
@@ -187,7 +230,19 @@
// Free our buffer if we have one
if ( _overflowBuffer != 0 )
- ::vm_deallocate(mach_task_self(), _overflowBuffer, _overflowBufferSize);
+#if !TARGET_OS_EXCLAVEKIT
+ vm_deallocate(mach_task_self(), (vm_address_t)_overflowBuffer, _overflowBufferSize);
+#else
+ lsl::MemoryManager::deallocate_pages(_overflowBuffer, _overflowBufferSize);
+#endif
+
+ new (this) OverflowSafeArray<T,MAXCOUNT>(std::move(other));
+ return *this;
+}
+
+template <typename T, uintptr_t MAXCOUNT>
+inline OverflowSafeArray<T,MAXCOUNT>::OverflowSafeArray(OverflowSafeArray<T,MAXCOUNT>&& other)
+{
// Now take the buffer from the other array
this->_elements = other._elements;
@@ -202,7 +257,6 @@
other._usedCount = 0;
other._overflowBuffer = 0;
other._overflowBufferSize = 0;
- return *this;
}