-
Notifications
You must be signed in to change notification settings - Fork 608
/
unwind_info.hpp
113 lines (90 loc) · 2.33 KB
/
unwind_info.hpp
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef RBX_UNWIND_INFO_HPP
#define RBX_UNWIND_INFO_HPP
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "prelude.hpp"
namespace rubinius {
const int kMaxUnwindInfos = 4;
enum UnwindType {
cRescue = 0,
cEnsure = 1
};
struct UnwindInfo {
uint32_t target_ip;
int stack_depth;
UnwindType type;
bool for_ensure() const {
return type == cEnsure;
}
bool for_rescue() const {
return type == cRescue;
}
};
typedef std::vector<UnwindInfo> UnwindOverflow;
class UnwindInfoSet {
private:
UnwindInfo unwinds_[kMaxUnwindInfos];
UnwindOverflow* overflow_;
int current_;
void overflow_set_unwind_info(int i, uint32_t target_ip, int stack_depth, UnwindType type);
void overflow_push(uint32_t target_ip, int stack_depth, UnwindType type);
UnwindInfo overflow_pop();
void overflow_drop();
public:
UnwindInfoSet()
: unwinds_()
, overflow_(NULL)
, current_(0)
{}
~UnwindInfoSet() {
if(overflow_) {
delete overflow_;
}
}
UnwindInfoSet(const UnwindInfoSet& other);
int has_unwinds() const {
return current_ > 0;
}
void set_current(int current) {
current_ = current;
}
void set_unwind_info(int i, uint32_t target_ip, int stack_depth, UnwindType type) {
if(unlikely(i >= kMaxUnwindInfos)) {
overflow_set_unwind_info(i, target_ip, stack_depth, type);
} else {
UnwindInfo& info = unwinds_[i];
info.target_ip = target_ip;
info.stack_depth = stack_depth;
info.type = type;
}
}
void push(uint32_t target_ip, int stack_depth, UnwindType type) {
if(unlikely(current_ >= kMaxUnwindInfos - 1)) {
overflow_push(target_ip, stack_depth, type);
} else {
UnwindInfo& info = unwinds_[current_++];
info.target_ip = target_ip;
info.stack_depth = stack_depth;
info.type = type;
}
}
UnwindInfo pop() {
UnwindInfo info;
if(unlikely(current_ >= kMaxUnwindInfos)) {
info = overflow_pop();
} else {
info = unwinds_[--current_];
}
return info;
}
void drop() {
if(unlikely(current_ >= kMaxUnwindInfos)) {
overflow_drop();
} else {
--current_;
}
}
};
}
#endif