@@ -69,13 +69,9 @@ struct Location {
69
69
int32_t _data;
70
70
};
71
71
72
- constexpr Location () : type(Uninitialized), _data(-1 ) {}
73
- constexpr Location (const Location& r) : type(r.type), _data(r._data) {}
74
- Location operator =(const Location& r) {
75
- type = r.type ;
76
- _data = r._data ;
77
- return *this ;
78
- }
72
+ constexpr Location () noexcept : type(Uninitialized), _data(-1 ) {}
73
+ constexpr Location (const Location& r) = default;
74
+ Location& operator =(const Location& r) = default ;
79
75
80
76
constexpr Location (LocationType type, int32_t data) : type(type), _data(data) {}
81
77
@@ -283,11 +279,50 @@ class RewriterVar {
283
279
friend class JitFragmentWriter ;
284
280
};
285
281
282
+ // A utility class that is similar to std::function, but stores any closure data inline rather
283
+ // than in a separate allocation. It's similar to SmallVector, but will just fail to compile if
284
+ // you try to put more bytes in than you allocated.
285
+ // Currently, it only works for functions with the signature "void()"
286
+ template <int N = 24 > class SmallFunction {
287
+ private:
288
+ void (*func)(void *);
289
+ char data[N];
290
+
291
+ template <typename Functor> struct Caller {
292
+ static void call (void * data) { (*(Functor*)data)(); }
293
+ };
294
+
295
+ public:
296
+ template <typename Functor> SmallFunction (Functor&& f) noexcept {
297
+ static_assert (std::has_trivial_copy_constructor<typename std::remove_reference<Functor>::type>::value,
298
+ " SmallFunction currently only works with simple types" );
299
+ static_assert (std::is_trivially_destructible<typename std::remove_reference<Functor>::type>::value,
300
+ " SmallFunction currently only works with simple types" );
301
+ static_assert (sizeof (Functor) <= sizeof (data), " Please increase N" );
302
+ new (data) typename std::remove_reference<Functor>::type (std::forward<Functor>(f));
303
+ func = Caller<Functor>::call;
304
+ }
305
+
306
+ SmallFunction () = default ;
307
+ SmallFunction (const SmallFunction<N>& rhs) = default ;
308
+ SmallFunction (SmallFunction<N>&& rhs) = default ;
309
+ SmallFunction& operator =(const SmallFunction<N>& rhs) = default ;
310
+ SmallFunction& operator =(SmallFunction<N>&& rhs) = default ;
311
+
312
+ void operator ()() { func (data); }
313
+ };
314
+
286
315
class RewriterAction {
287
316
public:
288
- std::function<void ()> action;
317
+ SmallFunction<48 > action;
318
+
319
+ template <typename F> RewriterAction (F&& action) : action(std::forward<F>(action)) {}
289
320
290
- RewriterAction (std::function<void ()> f) : action(std::move(f)) {}
321
+ RewriterAction () = default ;
322
+ RewriterAction (const RewriterAction& rhs) = default ;
323
+ RewriterAction (RewriterAction&& rhs) = default ;
324
+ RewriterAction& operator =(const RewriterAction& rhs) = default ;
325
+ RewriterAction& operator =(RewriterAction&& rhs) = default ;
291
326
};
292
327
293
328
enum class ActionType { NORMAL, GUARD, MUTATION };
@@ -449,10 +484,9 @@ class Rewriter : public ICSlotRewrite::CommitHook {
449
484
450
485
void _trap ();
451
486
void _loadConst (RewriterVar* result, int64_t val);
452
- void _setupCall (bool has_side_effects, const RewriterVar::SmallVector& args,
453
- const RewriterVar::SmallVector& args_xmm);
454
- void _call (RewriterVar* result, bool has_side_effects, void * func_addr, const RewriterVar::SmallVector& args,
455
- const RewriterVar::SmallVector& args_xmm);
487
+ void _setupCall (bool has_side_effects, llvm::ArrayRef<RewriterVar*> args, llvm::ArrayRef<RewriterVar*> args_xmm);
488
+ void _call (RewriterVar* result, bool has_side_effects, void * func_addr, llvm::ArrayRef<RewriterVar*> args,
489
+ llvm::ArrayRef<RewriterVar*> args_xmm);
456
490
void _add (RewriterVar* result, RewriterVar* a, int64_t b, Location dest);
457
491
int _allocate (RewriterVar* result, int n);
458
492
void _allocateAndCopy (RewriterVar* result, RewriterVar* array, int n);
0 commit comments