10
10
11
11
#include < library/cpp/yt/malloc//malloc.h>
12
12
13
+ #include < library/cpp/yt/system/exit.h>
14
+
13
15
namespace NYT {
14
16
15
17
// //////////////////////////////////////////////////////////////////////////////
@@ -177,17 +179,41 @@ Y_FORCE_INLINE TIntrusivePtr<T> SafeConstruct(void* ptr, As&&... args)
177
179
}
178
180
179
181
template <size_t Size, size_t Alignment>
180
- void * AllocateConstSizeAligned ()
182
+ Y_FORCE_INLINE void * AllocateConstSizeAlignedOrCrash ()
183
+ {
184
+ void * ptr;
185
+ #ifdef _win_
186
+ ptr = ::aligned_malloc (Size, Alignment);
187
+ #else
188
+ if (Alignment <= alignof (std::max_align_t )) {
189
+ ptr = ::malloc (Size);
190
+ } else {
191
+ ptr = ::aligned_malloc (Size, Alignment);
192
+ }
193
+ #endif
194
+ if (Y_UNLIKELY (!ptr)) {
195
+ AbortProcess (ToUnderlying (EProcessExitCode::OutOfMemory));
196
+ }
197
+ return ptr;
198
+ }
199
+
200
+ template <size_t Alignment>
201
+ Y_FORCE_INLINE void * AllocateOrCrash (size_t size)
181
202
{
203
+ void * ptr;
182
204
#ifdef _win_
183
- return ::aligned_malloc (Size , Alignment);
205
+ ptr = ::aligned_malloc (size , Alignment);
184
206
#else
185
207
if (Alignment <= alignof (std::max_align_t )) {
186
- return ::malloc (Size );
208
+ ptr = ::malloc (size );
187
209
} else {
188
- return ::aligned_malloc (Size , Alignment);
210
+ ptr = ::aligned_malloc (size , Alignment);
189
211
}
190
212
#endif
213
+ if (Y_UNLIKELY (!ptr)) {
214
+ AbortProcess (ToUnderlying (EProcessExitCode::OutOfMemory));
215
+ }
216
+ return ptr;
191
217
}
192
218
193
219
} // namespace NDetail
@@ -198,25 +224,36 @@ template <class T, class... As, class>
198
224
Y_FORCE_INLINE TIntrusivePtr<T> New (
199
225
As&&... args)
200
226
{
201
- void * ptr = NYT::NDetail::AllocateConstSizeAligned <
227
+ void * ptr = NYT::NDetail::AllocateConstSizeAlignedOrCrash <
202
228
NYT::NDetail::TConstructHelper<T>::Size,
203
229
NYT::NDetail::TConstructHelper<T>::Alignment>();
204
-
205
230
return NYT::NDetail::SafeConstruct<T>(ptr, std::forward<As>(args)...);
206
231
}
207
232
208
233
template <class T , class ... As, class >
209
- Y_FORCE_INLINE TIntrusivePtr<T> New (
234
+ Y_FORCE_INLINE TIntrusivePtr<T> TryNew (
210
235
typename T::TAllocator* allocator,
211
236
As&&... args)
212
237
{
213
238
auto * ptr = allocator->Allocate (NYT::NDetail::TConstructHelper<T>::Size);
214
- if (!ptr) {
239
+ if (Y_UNLIKELY ( !ptr) ) {
215
240
return nullptr ;
216
241
}
217
242
return NYT::NDetail::SafeConstruct<T>(ptr, std::forward<As>(args)...);
218
243
}
219
244
245
+ template <class T , class ... As, class >
246
+ Y_FORCE_INLINE TIntrusivePtr<T> New (
247
+ typename T::TAllocator* allocator,
248
+ As&&... args)
249
+ {
250
+ auto obj = TryNew<T>(allocator, std::forward<As>(args)...);
251
+ if (Y_UNLIKELY (!obj)) {
252
+ AbortProcess (ToUnderlying (EProcessExitCode::OutOfMemory));
253
+ }
254
+ return obj;
255
+ }
256
+
220
257
// //////////////////////////////////////////////////////////////////////////////
221
258
222
259
template <class T , class ... As, class >
@@ -225,48 +262,48 @@ Y_FORCE_INLINE TIntrusivePtr<T> NewWithExtraSpace(
225
262
As&&... args)
226
263
{
227
264
auto totalSize = NYT::NDetail::TConstructHelper<T>::Size + extraSpaceSize;
228
- void * ptr = nullptr ;
229
-
230
- #ifdef _win_
231
- ptr = ::aligned_malloc (totalSize, NYT::NDetail::TConstructHelper<T>::Alignment);
232
- #else
233
- if (NYT::NDetail::TConstructHelper<T>::Alignment <= alignof (std::max_align_t )) {
234
- ptr = ::malloc (totalSize);
235
- } else {
236
- ptr = ::aligned_malloc (totalSize, NYT::NDetail::TConstructHelper<T>::Alignment);
237
- }
238
- #endif
239
-
265
+ void * ptr = NYT::NDetail::AllocateOrCrash<NYT::NDetail::TConstructHelper<T>::Alignment>(totalSize);
240
266
return NYT::NDetail::SafeConstruct<T>(ptr, std::forward<As>(args)...);
241
267
}
242
268
243
269
template <class T , class ... As, class >
244
- Y_FORCE_INLINE TIntrusivePtr<T> NewWithExtraSpace (
270
+ Y_FORCE_INLINE TIntrusivePtr<T> TryNewWithExtraSpace (
245
271
typename T::TAllocator* allocator,
246
272
size_t extraSpaceSize,
247
273
As&&... args)
248
274
{
249
275
auto totalSize = NYT::NDetail::TConstructHelper<T>::Size + extraSpaceSize;
250
276
auto * ptr = allocator->Allocate (totalSize);
251
- if (!ptr) {
277
+ if (Y_UNLIKELY ( !ptr) ) {
252
278
return nullptr ;
253
279
}
254
280
return NYT::NDetail::SafeConstruct<T>(ptr, std::forward<As>(args)...);
255
281
}
256
282
283
+ template <class T , class ... As, class >
284
+ Y_FORCE_INLINE TIntrusivePtr<T> NewWithExtraSpace (
285
+ typename T::TAllocator* allocator,
286
+ size_t extraSpaceSize,
287
+ As&&... args)
288
+ {
289
+ auto obj = TryNewWithExtraSpace<T>(allocator, extraSpaceSize, std::forward<As>(args)...);
290
+ if (Y_UNLIKELY (!obj)) {
291
+ AbortProcess (ToUnderlying (EProcessExitCode::OutOfMemory));
292
+ }
293
+ return obj;
294
+ }
295
+
257
296
// //////////////////////////////////////////////////////////////////////////////
258
297
259
298
template <class T , class TDeleter , class ... As>
260
299
Y_FORCE_INLINE TIntrusivePtr<T> NewWithDeleter (TDeleter deleter, As&&... args)
261
300
{
262
301
using TWrapper = TRefCountedWrapperWithDeleter<T, TDeleter>;
263
- void * ptr = NYT::NDetail::AllocateConstSizeAligned<sizeof (TWrapper), alignof (TWrapper)>();
264
-
302
+ void * ptr = NYT::NDetail::AllocateConstSizeAlignedOrCrash<sizeof (TWrapper), alignof (TWrapper)>();
265
303
auto * instance = NYT::NDetail::NewEpilogue<TWrapper>(
266
304
ptr,
267
305
std::move (deleter),
268
306
std::forward<As>(args)...);
269
-
270
307
return TIntrusivePtr<T>(instance, /* addReference*/ false );
271
308
}
272
309
@@ -278,16 +315,13 @@ Y_FORCE_INLINE TIntrusivePtr<T> NewWithLocation(
278
315
As&&... args)
279
316
{
280
317
using TWrapper = TRefCountedWrapperWithCookie<T>;
281
- void * ptr = NYT::NDetail::AllocateConstSizeAligned<sizeof (TWrapper), alignof (TWrapper)>();
282
-
318
+ void * ptr = NYT::NDetail::AllocateConstSizeAlignedOrCrash<sizeof (TWrapper), alignof (TWrapper)>();
283
319
auto * instance = NYT::NDetail::NewEpilogue<TWrapper>(ptr, std::forward<As>(args)...);
284
-
285
320
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
286
321
instance->InitializeTracking (GetRefCountedTypeCookieWithLocation<T, TTag, Counter>(location));
287
322
#else
288
323
Y_UNUSED (location);
289
324
#endif
290
-
291
325
return TIntrusivePtr<T>(instance, /* addReference*/ false );
292
326
}
293
327
0 commit comments