FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
jruby/src/org/jruby/ir/Operation.java at parallel_boot · MSNexploder/jruby · GitHub
MSNexploder
/
jruby
Public
forked from
jruby/jruby
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Wiki
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
jruby
/
src
/
org
/
jruby
/
ir
/
Operation.java
Copy path
More file actions
More file actions
Latest commit
History
History
History
242 lines (206 loc) · 9.8 KB
Breadcrumbs
jruby
/
src
/
org
/
jruby
/
ir
/
Operation.java
Copy path
File metadata and controls
242 lines (206 loc) · 9.8 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package
org
.
jruby
.
ir
;
// SSS FIXME: If we can hide these flags from leaking out to the rest of the codebase,
// that would be awesome, but I cannot nest this class in an Enum class.
class
OpFlags
{
final
static
int
f_has_side_effect
=
0x0002
;
final
static
int
f_can_raise_exception
=
0x0004
;
final
static
int
f_is_marker_op
=
0x0008
;
final
static
int
f_is_jump_or_branch
=
0x0010
;
final
static
int
f_is_return
=
0x0020
;
final
static
int
f_is_exception
=
0x0040
;
final
static
int
f_is_debug_op
=
0x0080
;
final
static
int
f_is_load
=
0x0100
;
final
static
int
f_is_store
=
0x0200
;
final
static
int
f_is_call
=
0x0400
;
final
static
int
f_is_arg_receive
=
0x0800
;
final
static
int
f_modifies_code
=
0x1000
;
final
static
int
f_inline_unfriendly
=
0x2000
;
}
public
enum
Operation
{
/* Mark a *non-control-flow* instruction as side-effecting if its compuation is not referentially
* transparent. In other words, mark it side-effecting if the following is true:
*
* If "r = op(args)" is the instruction I and v is the value produced by the instruction at runtime,
* and replacing I with "r = v" will leave the program behavior unchanged. If so, and we determine
* that the value of 'r' is not used anywhere, then it would be safe to get rid of I altogether.
*
* So definitions, calls, returns, stores are all side-effecting by this definition */
// ------ Define the operations below ----
NOP
(
0
),
/** control-flow **/
JUMP
(
OpFlags
.
f_is_jump_or_branch
),
JUMP_INDIRECT
(
OpFlags
.
f_is_jump_or_branch
),
BEQ
(
OpFlags
.
f_is_jump_or_branch
),
BNE
(
OpFlags
.
f_is_jump_or_branch
),
B_UNDEF
(
OpFlags
.
f_is_jump_or_branch
),
B_NIL
(
OpFlags
.
f_is_jump_or_branch
),
B_TRUE
(
OpFlags
.
f_is_jump_or_branch
),
B_FALSE
(
OpFlags
.
f_is_jump_or_branch
),
/** argument receive in methods and blocks **/
RECV_SELF
(
0
),
RECV_PRE_REQD_ARG
(
OpFlags
.
f_is_arg_receive
),
RECV_POST_REQD_ARG
(
OpFlags
.
f_is_arg_receive
),
RECV_REST_ARG
(
OpFlags
.
f_is_arg_receive
),
RECV_OPT_ARG
(
OpFlags
.
f_is_arg_receive
),
RECV_CLOSURE
(
OpFlags
.
f_is_arg_receive
),
RECV_EXCEPTION
(
OpFlags
.
f_is_arg_receive
),
/* By default, call instructions cannot be deleted even if their results
* aren't used by anyone unless we know more about what the call is,
* what it does, etc. Hence all these are marked side effecting */
/** calls **/
CALL
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_call
|
OpFlags
.
f_can_raise_exception
),
SUPER
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_call
|
OpFlags
.
f_can_raise_exception
),
ZSUPER
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_call
|
OpFlags
.
f_can_raise_exception
),
YIELD
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
),
LAMBDA
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_call
|
OpFlags
.
f_can_raise_exception
),
RUNTIME_HELPER
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_call
|
OpFlags
.
f_can_raise_exception
),
/** returns -- returns unwind stack, etc. */
RETURN
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_return
),
NONLOCAL_RETURN
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_return
),
/* BREAK is a return because it can only be used within closures
* and the net result is to return from the closure */
BREAK
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_is_return
),
/** defines **/
ALIAS
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_modifies_code
),
GVAR_ALIAS
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_modifies_code
),
DEF_MODULE
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_modifies_code
|
OpFlags
.
f_inline_unfriendly
),
DEF_CLASS
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_modifies_code
|
OpFlags
.
f_inline_unfriendly
),
DEF_META_CLASS
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_modifies_code
|
OpFlags
.
f_inline_unfriendly
),
DEF_INST_METH
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_modifies_code
|
OpFlags
.
f_inline_unfriendly
),
DEF_CLASS_METH
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_modifies_code
|
OpFlags
.
f_inline_unfriendly
),
PROCESS_MODULE_BODY
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_modifies_code
|
OpFlags
.
f_inline_unfriendly
),
UNDEF_METHOD
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_modifies_code
),
/** marker instructions used to flag/mark places in the code and dont actually get executed **/
LABEL
(
OpFlags
.
f_is_marker_op
),
EXC_REGION_START
(
OpFlags
.
f_is_marker_op
),
EXC_REGION_END
(
OpFlags
.
f_is_marker_op
),
CASE
(
OpFlags
.
f_is_marker_op
),
// unused currently
/** constant operations */
LEXICAL_SEARCH_CONST
(
OpFlags
.
f_can_raise_exception
),
INHERITANCE_SEARCH_CONST
(
OpFlags
.
f_can_raise_exception
),
CONST_MISSING
(
OpFlags
.
f_can_raise_exception
),
SEARCH_CONST
(
OpFlags
.
f_can_raise_exception
),
/** value loads (SSS FIXME: Do any of these have side effects?) **/
GET_GLOBAL_VAR
(
OpFlags
.
f_is_load
),
GET_FIELD
(
OpFlags
.
f_is_load
),
GET_CVAR
(
OpFlags
.
f_is_load
|
OpFlags
.
f_can_raise_exception
),
BINDING_LOAD
(
OpFlags
.
f_is_load
),
MASGN_OPT
(
OpFlags
.
f_is_load
),
MASGN_REQD
(
OpFlags
.
f_is_load
),
MASGN_REST
(
OpFlags
.
f_is_load
),
/** value stores **/
PUT_CONST
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
),
// SSS FIXME: Not all global variable sets can throw exceptions. Should we split this
// operation into two different operations? Those that can throw exceptions and those
// that cannot. But, for now, this should be good enough
PUT_GLOBAL_VAR
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
),
PUT_FIELD
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
),
PUT_ARRAY
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
),
PUT_CVAR
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
),
BINDING_STORE
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
),
ATTR_ASSIGN
(
OpFlags
.
f_is_store
|
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
),
/** debugging ops **/
LINE_NUM
(
OpFlags
.
f_is_debug_op
),
FILE_NAME
(
OpFlags
.
f_is_debug_op
),
/** JRuby-impl instructions **/
COPY
(
0
),
NOT
(
0
),
// ruby NOT operator
BLOCK_GIVEN
(
0
),
GET_OBJECT
(
0
),
GET_BACKREF
(
0
),
RESTORE_ERROR_INFO
(
OpFlags
.
f_has_side_effect
),
RAISE_ARGUMENT_ERROR
(
OpFlags
.
f_can_raise_exception
),
CHECK_ARITY
(
OpFlags
.
f_can_raise_exception
),
CHECK_ARGS_ARRAY_ARITY
(
OpFlags
.
f_can_raise_exception
),
RECORD_END_BLOCK
(
OpFlags
.
f_has_side_effect
),
TO_ARY
(
0
),
ENSURE_RUBY_ARRAY
(
0
),
THROW
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_is_exception
),
MATCH
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_is_call
),
MATCH2
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_is_call
),
MATCH3
(
OpFlags
.
f_has_side_effect
|
OpFlags
.
f_can_raise_exception
|
OpFlags
.
f_is_call
),
SET_RETADDR
(
0
),
CLASS_VAR_MODULE
(
0
),
IS_TRUE
(
0
),
// checks if the operand is non-null and non-false
EQQ
(
0
),
// (FIXME: Exceptions?) a === call used in when
RESCUE_EQQ
(
OpFlags
.
f_can_raise_exception
),
// a === call used in rescue
THREAD_POLL
(
OpFlags
.
f_has_side_effect
),
GET_ENCODING
(
0
),
/* Instructions to support defined? */
SET_WITHIN_DEFINED
(
OpFlags
.
f_has_side_effect
),
DEFINED_CONSTANT_OR_METHOD
(
OpFlags
.
f_can_raise_exception
),
METHOD_DEFINED
(
OpFlags
.
f_can_raise_exception
),
BACKREF_IS_MATCH_DATA
(
0
),
CLASS_VAR_IS_DEFINED
(
0
),
GLOBAL_IS_DEFINED
(
0
),
HAS_INSTANCE_VAR
(
0
),
IS_METHOD_BOUND
(
0
),
METHOD_IS_PUBLIC
(
0
),
SUPER_METHOD_BOUND
(
0
),
GET_ERROR_INFO
(
0
),
INSTANCE_OF
(
0
),
// java instanceof bytecode
/** Other JRuby internal primitives for optimizations */
MODULE_GUARD
(
OpFlags
.
f_is_jump_or_branch
),
/* a guard acts as a branch */
PUSH_FRAME
(
OpFlags
.
f_has_side_effect
),
PUSH_BINDING
(
OpFlags
.
f_has_side_effect
),
POP_FRAME
(
OpFlags
.
f_has_side_effect
),
POP_BINDING
(
OpFlags
.
f_has_side_effect
),
METHOD_LOOKUP
(
0
),
/* for splitting calls into method-lookup and call -- unused **/
BOX_VALUE
(
0
),
/* primitive value boxing/unboxing -- unused */
UNBOX_VALUE
(
0
);
/* unused */
/* ----------- unused ops ------------------
// primitive alu operations -- unboxed primitive ops (not native ruby)
ADD(0), SUB(0), MUL(0), DIV(OpFlags.f_can_raise_exception),
* -----------------------------------------*/
private
int
flags
;
Operation
(
int
flags
) {
this
.
flags
=
flags
;
}
public
boolean
transfersControl
() {
return
(
flags
& (
OpFlags
.
f_is_jump_or_branch
|
OpFlags
.
f_is_return
|
OpFlags
.
f_is_exception
)) >
0
;
}
public
boolean
isLoad
() {
return
(
flags
&
OpFlags
.
f_is_load
) >
0
;
}
public
boolean
isStore
() {
return
(
flags
&
OpFlags
.
f_is_store
) >
0
;
}
public
boolean
isCall
() {
return
(
flags
&
OpFlags
.
f_is_call
) >
0
;
}
public
boolean
isReturn
() {
return
(
flags
&
OpFlags
.
f_is_return
) >
0
;
}
public
boolean
isException
() {
return
(
flags
&
OpFlags
.
f_is_exception
) >
0
;
}
public
boolean
isArgReceive
() {
return
(
flags
&
OpFlags
.
f_is_arg_receive
) >
0
;
}
public
boolean
startsBasicBlock
() {
return
this
==
LABEL
;
}
public
boolean
endsBasicBlock
() {
return
transfersControl
();
}
public
boolean
hasSideEffects
() {
return
(
flags
&
OpFlags
.
f_has_side_effect
) >
0
;
}
public
boolean
isDebugOp
() {
return
(
flags
&
OpFlags
.
f_is_debug_op
) >
0
;
}
// Conservative -- say no only if you know it for sure cannot
public
boolean
canRaiseException
() {
return
(
flags
&
OpFlags
.
f_can_raise_exception
) >
0
;
}
public
boolean
modifiesCode
() {
return
(
flags
&
OpFlags
.
f_modifies_code
) >
0
;
}
public
boolean
inlineUnfriendly
() {
return
(
flags
&
OpFlags
.
f_inline_unfriendly
) >
0
;
}
@
Override
public
String
toString
() {
return
name
().
toLowerCase
();
}
}
Back
|
FazBrowse Home
|
New Git URL