@@ -171,7 +171,7 @@ class unique {
171
171
if (_p) {
172
172
static_cast <void >(sizeof (T));
173
173
_p->~T ();
174
- co::free (_s , _s-> n );
174
+ co::free (( char *)_p - _s[- 2 ] , _s[- 1 ] );
175
175
_p = 0 ;
176
176
}
177
177
}
@@ -187,20 +187,23 @@ class unique {
187
187
}
188
188
189
189
private:
190
- struct S { T o; size_t n; };
191
- union { S* _s; T* _p; };
190
+ union { T* _p; uint32* _s; };
192
191
};
193
192
194
193
template <typename T, typename ... Args>
195
194
inline unique<T> make_unique (Args&&... args) {
196
- struct S { T o; size_t n; };
197
- S* const s = (S*) co::alloc (sizeof (S));
195
+ struct S { uint32 o; uint32 n; T t; };
196
+ static_assert (alignof (S) <= 1024 , " " );
197
+ const size_t off = (size_t ) &((S*)0 )->t ;
198
+ S* const s = (S*) co::alloc (sizeof (S), alignof (S));
199
+ T* const t = &s->t ;
198
200
if (s) {
199
- new (s) T (std::forward<Args>(args)...);
200
- s->n = sizeof (S);
201
+ new (t) T (std::forward<Args>(args)...);
202
+ ((uint32*)t)[-1 ] = sizeof (S);
203
+ ((uint32*)t)[-2 ] = (uint32)off;
201
204
}
202
205
unique<T> x;
203
- *(void **)&x = s ;
206
+ *(void **)&x = t ;
204
207
return x;
205
208
}
206
209
@@ -217,7 +220,7 @@ class shared {
217
220
218
221
shared (const shared& x) noexcept {
219
222
_s = x._s ;
220
- if (_s) atomic_inc (&_s-> refn , mo_relaxed );
223
+ if (_s) this -> _ref ( );
221
224
}
222
225
223
226
shared (shared&& x) noexcept {
@@ -242,7 +245,7 @@ class shared {
242
245
> = 0 >
243
246
shared (const shared<X>& x) noexcept {
244
247
_p = x.get ();
245
- if (_s) atomic_inc (&_s-> refn , mo_relaxed );
248
+ if (_s) this -> _ref ( );
246
249
}
247
250
248
251
template <typename X, god::if_t <
@@ -279,17 +282,17 @@ class shared {
279
282
280
283
void reset () {
281
284
if (_s) {
282
- if (atomic_dec (&_s-> refn , mo_acq_rel ) == 0 ) {
285
+ if (this -> _unref ( ) == 0 ) {
283
286
static_cast <void >(sizeof (T));
284
287
_p->~T ();
285
- co::free (_s , _s-> size );
288
+ co::free (( char *)_p - _s[- 2 ] , _s[- 1 ] );
286
289
}
287
290
_p = 0 ;
288
291
}
289
292
}
290
293
291
294
size_t ref_count () const noexcept {
292
- return _s ? atomic_load (&_s-> refn , mo_relaxed) : 0 ;
295
+ return _s ? atomic_load (&_s[- 3 ] , mo_relaxed) : 0 ;
293
296
}
294
297
295
298
size_t use_count () const noexcept {
@@ -307,21 +310,32 @@ class shared {
307
310
}
308
311
309
312
private:
310
- struct S { T o; uint32 refn; uint32 size; };
311
- union { S* _s; T* _p; };
313
+ union { T* _p; uint32* _s; };
314
+
315
+ void _ref () {
316
+ atomic_inc (&_s[-3 ], mo_relaxed);
317
+ }
318
+
319
+ uint32 _unref () {
320
+ return atomic_dec (&_s[-3 ], mo_acq_rel);
321
+ }
312
322
};
313
323
314
324
template <typename T, typename ... Args>
315
325
inline shared<T> make_shared (Args&&... args) {
316
- struct S { T o; uint32 refn; uint32 size; };
317
- S* const s = (S*) co::alloc (sizeof (S));
326
+ struct S { uint32 r; uint32 o; uint32 n; T t; };
327
+ static_assert (alignof (S) <= 1024 , " " );
328
+ const size_t off = (size_t ) &((S*)0 )->t ;
329
+ S* const s = (S*) co::alloc (sizeof (S), alignof (S));
330
+ T* const t = &s->t ;
318
331
if (s) {
319
- new (s) T (std::forward<Args>(args)...);
320
- s->refn = 1 ;
321
- s->size = sizeof (S);
332
+ new (t) T (std::forward<Args>(args)...);
333
+ ((uint32*)t)[-1 ] = sizeof (S);
334
+ ((uint32*)t)[-2 ] = (uint32)off;
335
+ ((uint32*)t)[-3 ] = 1 ;
322
336
}
323
337
shared<T> x;
324
- *(void **)&x = s ;
338
+ *(void **)&x = t ;
325
339
return x;
326
340
}
327
341
0 commit comments