-
Notifications
You must be signed in to change notification settings - Fork 2
/
redmagic.h
79 lines (53 loc) · 2.27 KB
/
redmagic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* Red Magic by Matthew Francis-Landau <[email protected]>
*/
#ifndef REDMAGIC_H_
#define REDMAGIC_H_
#ifdef __cplusplus
extern "C" {
#endif
// to be call as at the start of main
void redmagic_start(void);
// indicates that we have a backwards branch somewhere, determine if worth tracing
void redmagic_backwards_branch(void *);
// we were at a backwards branch instruction but didn't take it
void redmagic_fellthrough_branch(void *);
// to be call at the start and end of interperter frames
// will be used to identify recursive methods etc
void redmagic_begin_branchable_frame(unsigned long*);
void redmagic_end_branchable_frame(unsigned long*);
// control forcing an the JIT to start a trace of this thread
void redmagic_force_begin_trace(void *);
void redmagic_force_end_trace(void *);
void redmagic_force_jump_to_trace(void *);
// make sure that the program is currently not being traced
// use before error handling/random inline returns
void redmagic_ensure_not_traced(void);
// temporarly disable JIT in a given method
// must have an accompany enable call for every disable otherwise the internal state may go wrong...
void redmagic_temp_disable(void);
void redmagic_temp_enable(void);
// for setup to tell the jit to not trace some function, eg the call into a gc or some custom malloc
void redmagic_do_not_trace_function(void* function_pointer);
// disable traceing on a specific branch, eg if there is some disallowed instruction such as yield contained in the branch
void redmagic_disable_branch(void *);
// return 0 if not traced, non zero otherwise
unsigned long redmagic_is_traced(void);
// A merge block allows you to have some section of code that performs branches but at the end of the block merge back into the same instruction stream
// useful for things like reference counting where hitting zero will not have a significant impact on the following control flow
void redmagic_begin_merge_block(void);
void redmagic_end_merge_block(void);
#ifdef __cplusplus
}
class redmagic_disable {
public:
redmagic_disable () { redmagic_temp_disable(); }
~redmagic_disable() { redmagic_temp_enable(); }
};
class redmagic_merge {
public:
redmagic_merge () { redmagic_begin_merge_block(); }
~redmagic_merge() { redmagic_end_merge_block(); }
};
#endif
#endif // REDMAGIC_H_