seafoam 0.2 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/workflows.yml +39 -0
  3. data/.rubocop.yml +4 -1
  4. data/README.md +107 -27
  5. data/bin/bgv2isabelle +16 -45
  6. data/bin/bgv2json +18 -36
  7. data/bin/cfg2asm +24 -0
  8. data/bin/seafoam +2 -2
  9. data/demos/box-unbox-stats +65 -0
  10. data/docs/bgv.md +16 -7
  11. data/docs/getting-graphs.md +12 -0
  12. data/docs/json.md +35 -0
  13. data/examples/fib-java.bgv.gz +0 -0
  14. data/examples/fib.js +1 -1
  15. data/examples/java/JavaExamples.java +1 -1
  16. data/examples/ruby/clamps.rb +20 -0
  17. data/examples/ruby/graal.patch +15 -0
  18. data/examples/ruby/ruby_examples.rb +278 -0
  19. data/lib/seafoam.rb +5 -1
  20. data/lib/seafoam/annotators/graal.rb +1 -1
  21. data/lib/seafoam/bgv/bgv_parser.rb +12 -2
  22. data/lib/seafoam/cfg/cfg_parser.rb +93 -0
  23. data/lib/seafoam/cfg/disassembler.rb +70 -0
  24. data/lib/seafoam/commands.rb +196 -36
  25. data/lib/seafoam/graal/source.rb +23 -0
  26. data/lib/seafoam/isabelle_writer.rb +46 -0
  27. data/lib/seafoam/json_writer.rb +58 -0
  28. data/lib/seafoam/version.rb +1 -1
  29. data/seafoam.gemspec +4 -2
  30. data/spec/seafoam/annotators/graal_spec.rb +7 -7
  31. data/spec/seafoam/bgv/bgv_parser_spec.rb +27 -14
  32. data/spec/seafoam/cfg/cfg_parser_spec.rb +21 -0
  33. data/spec/seafoam/cfg/disassembler_spec.rb +32 -0
  34. data/spec/seafoam/command_spec.rb +94 -30
  35. data/spec/seafoam/graphviz_writer_spec.rb +2 -2
  36. data/spec/seafoam/json_writer_spec.rb +14 -0
  37. data/spec/seafoam/spec_helpers.rb +5 -1
  38. data/spec/seafoam/spotlight_spec.rb +1 -1
  39. data/tools/render-all +2 -2
  40. metadata +34 -98
  41. data/.github/workflows/rubocop.yml +0 -10
  42. data/.github/workflows/specs.yml +0 -19
  43. data/examples/fib-java.bgv +0 -0
  44. data/examples/fib-js.bgv +0 -0
  45. data/examples/fib-ruby.bgv +0 -0
  46. data/examples/identity.bgv +0 -0
  47. data/examples/java/exampleArithOperator.bgv +0 -0
  48. data/examples/java/exampleArithOperator.cfg +0 -925
  49. data/examples/java/exampleArrayAllocation.bgv +0 -0
  50. data/examples/java/exampleArrayAllocation.cfg +0 -5268
  51. data/examples/java/exampleArrayRead.bgv +0 -0
  52. data/examples/java/exampleArrayRead.cfg +0 -2263
  53. data/examples/java/exampleArrayWrite.bgv +0 -0
  54. data/examples/java/exampleArrayWrite.cfg +0 -2315
  55. data/examples/java/exampleCatch.bgv +0 -0
  56. data/examples/java/exampleCatch.cfg +0 -4150
  57. data/examples/java/exampleCompareOperator.bgv +0 -0
  58. data/examples/java/exampleCompareOperator.cfg +0 -1109
  59. data/examples/java/exampleDoubleSynchronized.bgv +0 -0
  60. data/examples/java/exampleDoubleSynchronized.cfg +0 -26497
  61. data/examples/java/exampleExactArith.bgv +0 -0
  62. data/examples/java/exampleExactArith.cfg +0 -1888
  63. data/examples/java/exampleFieldRead.bgv +0 -0
  64. data/examples/java/exampleFieldRead.cfg +0 -1228
  65. data/examples/java/exampleFieldWrite.bgv +0 -0
  66. data/examples/java/exampleFieldWrite.cfg +0 -1102
  67. data/examples/java/exampleFor.bgv +0 -0
  68. data/examples/java/exampleFor.cfg +0 -3936
  69. data/examples/java/exampleFullEscape.bgv +0 -0
  70. data/examples/java/exampleFullEscape.cfg +0 -5893
  71. data/examples/java/exampleIf.bgv +0 -0
  72. data/examples/java/exampleIf.cfg +0 -2462
  73. data/examples/java/exampleIfNeverTaken.bgv +0 -0
  74. data/examples/java/exampleIfNeverTaken.cfg +0 -2476
  75. data/examples/java/exampleInstanceOfManyImpls.bgv +0 -0
  76. data/examples/java/exampleInstanceOfManyImpls.cfg +0 -6391
  77. data/examples/java/exampleInstanceOfOneImpl.bgv +0 -0
  78. data/examples/java/exampleInstanceOfOneImpl.cfg +0 -2604
  79. data/examples/java/exampleIntSwitch.bgv +0 -0
  80. data/examples/java/exampleIntSwitch.cfg +0 -3121
  81. data/examples/java/exampleInterfaceCallManyImpls.bgv +0 -0
  82. data/examples/java/exampleInterfaceCallManyImpls.cfg +0 -1358
  83. data/examples/java/exampleInterfaceCallOneImpl.bgv +0 -0
  84. data/examples/java/exampleInterfaceCallOneImpl.cfg +0 -3859
  85. data/examples/java/exampleLocalInstanceOf.bgv +0 -0
  86. data/examples/java/exampleLocalInstanceOf.cfg +0 -5276
  87. data/examples/java/exampleLocalSynchronized.bgv +0 -0
  88. data/examples/java/exampleLocalSynchronized.cfg +0 -1364
  89. data/examples/java/exampleLocalVariables.bgv +0 -0
  90. data/examples/java/exampleLocalVariables.cfg +0 -1195
  91. data/examples/java/exampleLocalVariablesState.bgv +0 -0
  92. data/examples/java/exampleLocalVariablesState.cfg +0 -1673
  93. data/examples/java/exampleNestedWhile.bgv +0 -0
  94. data/examples/java/exampleNestedWhile.cfg +0 -15499
  95. data/examples/java/exampleNestedWhileBreak.bgv +0 -0
  96. data/examples/java/exampleNestedWhileBreak.cfg +0 -11162
  97. data/examples/java/exampleNoEscape.bgv +0 -0
  98. data/examples/java/exampleNoEscape.cfg +0 -974
  99. data/examples/java/exampleObjectAllocation.bgv +0 -0
  100. data/examples/java/exampleObjectAllocation.cfg +0 -5287
  101. data/examples/java/examplePartialEscape.bgv +0 -0
  102. data/examples/java/examplePartialEscape.cfg +0 -7042
  103. data/examples/java/examplePhi.bgv +0 -0
  104. data/examples/java/examplePhi.cfg +0 -3227
  105. data/examples/java/exampleReducible.bgv +0 -0
  106. data/examples/java/exampleReducible.cfg +0 -5578
  107. data/examples/java/exampleSimpleCall.bgv +0 -0
  108. data/examples/java/exampleSimpleCall.cfg +0 -1435
  109. data/examples/java/exampleStamp.bgv +0 -0
  110. data/examples/java/exampleStamp.cfg +0 -913
  111. data/examples/java/exampleStaticCall.bgv +0 -0
  112. data/examples/java/exampleStaticCall.cfg +0 -1154
  113. data/examples/java/exampleStringSwitch.bgv +0 -0
  114. data/examples/java/exampleStringSwitch.cfg +0 -15377
  115. data/examples/java/exampleSynchronized.bgv +0 -0
  116. data/examples/java/exampleSynchronized.cfg +0 -26027
  117. data/examples/java/exampleThrow.bgv +0 -0
  118. data/examples/java/exampleThrow.cfg +0 -780
  119. data/examples/java/exampleThrowCatch.bgv +0 -0
  120. data/examples/java/exampleThrowCatch.cfg +0 -744
  121. data/examples/java/exampleUnsafeRead.bgv +0 -0
  122. data/examples/java/exampleUnsafeRead.cfg +0 -912
  123. data/examples/java/exampleUnsafeWrite.bgv +0 -0
  124. data/examples/java/exampleUnsafeWrite.cfg +0 -962
  125. data/examples/java/exampleWhile.bgv +0 -0
  126. data/examples/java/exampleWhile.cfg +0 -3936
  127. data/examples/java/exampleWhileBreak.bgv +0 -0
  128. data/examples/java/exampleWhileBreak.cfg +0 -5963
  129. data/examples/matmult-java.bgv +0 -0
  130. data/examples/matmult-ruby.bgv +0 -0
  131. data/examples/overflow.bgv +0 -0
  132. data/lib/seafoam/binary/binary_reader.rb +0 -21
  133. data/spec/seafoam/bgv/fixtures/not.bgv +0 -1
  134. data/spec/seafoam/bgv/fixtures/unsupported.bgv +0 -1
data/bin/cfg2asm ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'seafoam'
4
+
5
+ # This is the 'cfg2asm' command line entry point.
6
+
7
+ begin
8
+ # Load configuraiton.
9
+ config = Seafoam::Config.new
10
+ config.load_config
11
+
12
+ # Run the command line.
13
+ commands = Seafoam::Commands.new($stdout, config)
14
+ commands.cfg2asm(*ARGV)
15
+ rescue StandardError => e
16
+ if $DEBUG
17
+ # Re-raise the exception so the user sees it, if debugging is
18
+ # enabled (ruby -d).
19
+ raise e
20
+ else
21
+ # Otherwise, just print the message.
22
+ warn "seafoam: #{e.message}"
23
+ end
24
+ end
data/bin/seafoam CHANGED
@@ -11,10 +11,10 @@ begin
11
11
 
12
12
  # Run the command line.
13
13
  commands = Seafoam::Commands.new($stdout, config)
14
- commands.run(*ARGV)
14
+ commands.seafoam(*ARGV)
15
15
  rescue StandardError => e
16
16
  if $DEBUG
17
- # Re-raise the exception so the user sees it, it debugging is
17
+ # Re-raise the exception so the user sees it, if debugging is
18
18
  # enabled (ruby -d).
19
19
  raise e
20
20
  else
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This demo analyses a directory full of graphs and looks for how many box nodes
4
+ # take their value directly from an unbox node.
5
+
6
+ require 'seafoam'
7
+
8
+ box_nodes_count = 0
9
+ box_nodes_from_unbox_count = 0
10
+
11
+ graph_count = 0
12
+ graph_match_count = 0
13
+
14
+ ARGV.each do |dir|
15
+ Dir.glob(['*.bgv', '*.bgv.gz'], base: dir) do |file|
16
+ parser = Seafoam::BGV::BGVParser.new(File.join(dir, file))
17
+ parser.read_file_header
18
+ parser.skip_document_props
19
+
20
+ loop do
21
+ index, = parser.read_graph_preheader
22
+ break unless index
23
+
24
+ parser.skip_graph_header
25
+ graph = parser.read_graph
26
+
27
+ contains_box_unbox = false
28
+
29
+ graph.nodes.each_value do |node|
30
+ next unless node.props.dig(:node_class, :node_class).start_with?('org.graalvm.compiler.nodes.extended.BoxNode')
31
+
32
+ box_node = node
33
+ box_nodes_count += 1
34
+ value_edge = node.edges.find { |e| e.props[:name] == 'value' }
35
+ raise unless value_edge
36
+
37
+ value_node = value_edge.from
38
+ next unless value_node.props.dig(:node_class, :node_class).start_with?('org.graalvm.compiler.nodes.extended.UnboxNode')
39
+
40
+ unbox_node = value_node
41
+ box_nodes_from_unbox_count += 1
42
+ contains_box_unbox = true
43
+ puts "seafoam '#{File.join(dir, file)}:#{index}' render --spotlight #{box_node.id},#{unbox_node.id}"
44
+ end
45
+
46
+ graph_count += 1
47
+ graph_match_count += 1 if contains_box_unbox
48
+ end
49
+ end
50
+ end
51
+
52
+ if box_nodes_count.positive?
53
+ box_nodes_percent = (box_nodes_from_unbox_count / box_nodes_count.to_f) * 100
54
+ else
55
+ box_nodes_percent = 0.0
56
+ end
57
+
58
+ if graph_count.positive?
59
+ graph_percent = (graph_match_count / graph_count.to_f) * 100
60
+ else
61
+ graph_percent = 0.0
62
+ end
63
+
64
+ puts " How many boxes take a value from an unbox? #{box_nodes_percent.round(1)}%"
65
+ puts "How many graphs contain at least one box-unbox? #{graph_percent.round(1)}%"
data/docs/bgv.md CHANGED
@@ -22,11 +22,11 @@ BGV {
22
22
  char[4] = 'BIGV'
23
23
  sint8 major
24
24
  sint8 minor
25
- GroupOrGraph*
25
+ GroupDocumentGraph*
26
26
  }
27
27
 
28
- GroupOrGraph {
29
- BeginGroup GroupOrGraph* CloseGroup | Graph
28
+ GroupDocumentGraph {
29
+ BeginGroup GroupDocumentGraph* CloseGroup | Document | Graph
30
30
  }
31
31
 
32
32
  BeginGroup {
@@ -37,6 +37,15 @@ BeginGroup {
37
37
  Props props
38
38
  }
39
39
 
40
+ CloseGroup {
41
+ sint8 token = CLOSE_GROUP
42
+ }
43
+
44
+ Document {
45
+ sint8 token = BEGIN_DOCUMENT
46
+ Pops props
47
+ }
48
+
40
49
  Graph {
41
50
  sint8 token = BEGIN_GRAPH
42
51
  String format
@@ -72,10 +81,6 @@ Blocks {
72
81
  sint32[followers_count] followers
73
82
  }
74
83
 
75
- CloseGroup {
76
- sint8 token = CLOSE_GROUP
77
- }
78
-
79
84
  Props {
80
85
  sint16 props_count
81
86
  Prop[props_count] props
@@ -278,6 +283,10 @@ In order to 'seek' BGV files we have two code paths for reading the file, one
278
283
  with loads the data and one which loads as little as possible to know just how
279
284
  much further to advance in the file.
280
285
 
286
+ ## Compression
287
+
288
+ Seafoam supports compressed BGV files in the gzip file format.
289
+
281
290
  ## Other information
282
291
 
283
292
  `seafoam file.bgv debug` checks that a file can be parsed and prints information
@@ -29,6 +29,14 @@ graph without significantly effecting too much how the logic in it is compiled.
29
29
  -Dgraal.VectorizeLoops=false
30
30
  ```
31
31
 
32
+ ## GraalVM's Native Image compiler
33
+
34
+ When using `native-image` you will want to use the `-H:` format.
35
+
36
+ ```
37
+ % native-image -H:Dump=:2 -H:MethodFilter=fib Fib
38
+ ```
39
+
32
40
  ## TruffleRuby and other Truffle languages
33
41
 
34
42
  Use the same options as for GraalVM for Java, except they're prefixed with
@@ -45,3 +53,7 @@ You may want to disable on-stack-replacement and inlining with
45
53
  easier to understand.
46
54
 
47
55
  You may need to use `--experimental-options`.
56
+
57
+ ## Getting CFG files
58
+
59
+ To also get CFG files, add `-Dgraal.PrintBackendCFG=true`, or `--vm.Dgraal.PrintBackendCFG=true` for Truffle.
data/docs/json.md ADDED
@@ -0,0 +1,35 @@
1
+ # JSON Output Format
2
+
3
+ The `bgv2json` command outputs files in [JSON Lines](https://jsonlines.org/) format - one JSON object for each graph, one per line.
4
+
5
+ Each graph is of the format:
6
+
7
+ ```js
8
+ {
9
+ "name": ...,
10
+ "props": {...},
11
+ "nodes": [...],
12
+ "edges": [...]
13
+ }
14
+ ```
15
+
16
+ Each node is of the format:
17
+
18
+ ```js
19
+ {
20
+ "id": ...,
21
+ "props": {...}
22
+ }
23
+ ```
24
+
25
+ Each edge is of the format:
26
+
27
+ ```js
28
+ {
29
+ "from": ..., // node id
30
+ "to": ..., // node id
31
+ "props": {...}
32
+ }
33
+ ```
34
+
35
+ Note that `bgv2json` runs annotations, so for example all nodes have a `"label"` property with an easy-to-use name.
Binary file
data/examples/fib.js CHANGED
@@ -1,4 +1,4 @@
1
- // % node --experimental-options --engine.CompileOnly=fib --engine.Inlining=false --vm.Dgraal.Dump=Truffle:2 -f fib.js 14
1
+ // % node --experimental-options --engine.CompileOnly=fib --engine.Inlining=false --vm.Dgraal.Dump=Truffle:2 fib.js 14
2
2
 
3
3
  function fib(n) {
4
4
  if (n <= 1) {
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * % javac JavaExamples.java
3
- * % java -XX:-UseOnStackReplacement '-XX:CompileCommand=dontinline,*::*' -XX:+PrintCompilation -Dgraal.Dump=:3 JavaExamples
3
+ * % java -XX:-UseOnStackReplacement '-XX:CompileCommand=dontinline,*::*' -XX:+PrintCompilation -Dgraal.PrintBackendCFG=true -Dgraal.Dump=:3 JavaExamples
4
4
  */
5
5
 
6
6
  import java.lang.reflect.Field;
@@ -0,0 +1,20 @@
1
+ # ruby --experimental-options --engine.CompileOnly=clamp_low,clamp_high --vm.Dgraal.Dump=Truffle:2 --vm.Dgraal.PrintBackendCFG=true clamps.rb
2
+
3
+ def clamp_high(min, max, value)
4
+ [min, max, value].sort[1]
5
+ end
6
+
7
+ def clamp_low(min, max, value)
8
+ if value > max
9
+ max
10
+ elsif value < min
11
+ min
12
+ else
13
+ value
14
+ end
15
+ end
16
+
17
+ loop do
18
+ clamp_high(10, 90, rand(100))
19
+ clamp_low(10, 90, rand(100))
20
+ end
@@ -0,0 +1,15 @@
1
+ diff --git a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/DefaultInliningPolicy.java b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/DefaultInliningPolicy.java
2
+ index ffe01c1688f..d662a7096c4 100644
3
+ --- a/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/DefaultInliningPolicy.java
4
+ +++ b/compiler/src/org.graalvm.compiler.truffle.compiler/src/org/graalvm/compiler/truffle/compiler/phases/inlining/DefaultInliningPolicy.java
5
+ @@ -114,6 +114,10 @@ final class DefaultInliningPolicy implements InliningPolicy {
6
+ final PriorityQueue<CallNode> inlineQueue = getQueue(tree, CallNode.State.Expanded);
7
+ CallNode candidate;
8
+ while ((candidate = inlineQueue.poll()) != null) {
9
+ + if (candidate.getName().startsWith("Object#opaque_") || candidate.getName().equals("Object#static_call") || candidate.getName().equals("ExampleObject#instance_call")) {
10
+ + continue;
11
+ + }
12
+ +
13
+ if (candidate.isTrivial()) {
14
+ candidate.inline();
15
+ continue;
@@ -0,0 +1,278 @@
1
+ # truffleruby_primitives: true
2
+
3
+ # We're using Graal with graal.patch, to disable some inlining.
4
+
5
+ # % ruby --jvm --experimental-options --engine.OSR=false --engine.MultiTier=false --engine.TraceCompilation --vm.Dgraal.Dump=Truffle:1 ruby_examples.rb
6
+
7
+ RANDOM = Random.new
8
+ EXCEPTION = Exception.new
9
+
10
+ def example_local_variables(x, y)
11
+ a = x + y
12
+ a * 2 + a
13
+ end
14
+
15
+ def example_local_variables_state(x, y)
16
+ a = x + y
17
+ opaque_call
18
+ a * 2 + a
19
+ end
20
+
21
+ def example_arith_operator(x, y)
22
+ x + y
23
+ end
24
+
25
+ def example_compare_operator(x, y)
26
+ x <= y
27
+ end
28
+
29
+ def example_phi(condition, x)
30
+ if condition
31
+ a = opaque_call_a
32
+ else
33
+ a = opaque_call_b
34
+ end
35
+ a + x
36
+ end
37
+
38
+ def example_simple_call(object, x)
39
+ object.instance_call(x)
40
+ end
41
+
42
+ def example_stamp(x)
43
+ x & 0x1234
44
+ end
45
+
46
+ def example_full_escape(x)
47
+ a = [x]
48
+ Primitive.blackhole a
49
+ a[0]
50
+ end
51
+
52
+ def example_no_escape(x)
53
+ a = [x]
54
+ a[0]
55
+ end
56
+
57
+ def example_partial_escape(condition, x)
58
+ a = [x]
59
+ if condition
60
+ Primitive.blackhole a
61
+ a[0]
62
+ else
63
+ a[0]
64
+ end
65
+ end
66
+
67
+ def example_if(condition, x, y)
68
+ if condition
69
+ Primitive.blackhole x
70
+ a = x
71
+ else
72
+ Primitive.blackhole y
73
+ a = y
74
+ end
75
+ a
76
+ end
77
+
78
+ def example_if_never_taken(condition, x, y)
79
+ if condition
80
+ Primitive.blackhole x
81
+ a = x
82
+ else
83
+ Primitive.blackhole y
84
+ a = y
85
+ end
86
+ a
87
+ end
88
+
89
+ def example_int_switch(value, x, y, z)
90
+ case value
91
+ when 0
92
+ Primitive.blackhole x
93
+ a = x
94
+ when 1
95
+ Primitive.blackhole y
96
+ a = y
97
+ else
98
+ Primitive.blackhole z
99
+ a = z
100
+ end
101
+ a
102
+ end
103
+
104
+ def example_string_switch(value, x, y, z)
105
+ case value
106
+ when 'foo'
107
+ Primitive.blackhole x
108
+ a = x
109
+ when 'bar'
110
+ Primitive.blackhole y
111
+ a = y
112
+ else
113
+ Primitive.blackhole z
114
+ a = z
115
+ end
116
+ a
117
+ end
118
+
119
+ def example_while(count)
120
+ a = count
121
+ while a > 0
122
+ Primitive.blackhole a
123
+ a -= 1
124
+ end
125
+ count
126
+ end
127
+
128
+ def example_for(count)
129
+ count.times do |a|
130
+ Primitive.blackhole a
131
+ end
132
+ end
133
+
134
+ def example_nested_while(count)
135
+ a = count
136
+ while (a > 0)
137
+ y = count
138
+ while (y > 0)
139
+ Primitive.blackhole a
140
+ y -= 1
141
+ end
142
+ a -= 1
143
+ end
144
+ count
145
+ end
146
+
147
+ def example_while_break(count)
148
+ a = count
149
+ while a > 0
150
+ if a == 4
151
+ break
152
+ end
153
+ Primitive.blackhole a
154
+ a -= 1
155
+ end
156
+ count
157
+ end
158
+
159
+ def example_raise
160
+ raise EXCEPTION
161
+ end
162
+
163
+ def example_rescue
164
+ begin
165
+ opaque_raise
166
+ rescue Exception => e
167
+ Primitive.blackhole e
168
+ end
169
+ end
170
+
171
+ def example_raise_rescue
172
+ begin
173
+ raise EXCEPTION
174
+ rescue Exception => e
175
+ Primitive.blackhole e
176
+ end
177
+ end
178
+
179
+ def example_object_allocation(x)
180
+ ExampleObject.new(x)
181
+ end
182
+
183
+ def example_array_allocation(x, y)
184
+ [x, y]
185
+ end
186
+
187
+ def example_field_write(object, x)
188
+ object.x = x
189
+ end
190
+
191
+ def example_field_read(object)
192
+ object.x
193
+ end
194
+
195
+ def example_array_write(array, n, x)
196
+ array[n] = x
197
+ end
198
+
199
+ def example_array_read(array, n)
200
+ array[n]
201
+ end
202
+
203
+ def example_instance_of(x)
204
+ x.is_a?(ExampleObject)
205
+ end
206
+
207
+ # no inline
208
+ def opaque_call
209
+ RANDOM.rand(1000)
210
+ end
211
+
212
+ # no inline
213
+ def opaque_call_a
214
+ opaque_call
215
+ end
216
+
217
+ # no inline
218
+ def opaque_call_b
219
+ opaque_call
220
+ end
221
+
222
+ # no inline
223
+ def opaque_raise
224
+ raise EXCEPTION
225
+ end
226
+
227
+ # no inline
228
+ def static_call(x)
229
+ x
230
+ end
231
+
232
+ class ExampleObject
233
+ attr_accessor :x
234
+
235
+ def initialize(x)
236
+ @x = x
237
+ end
238
+
239
+ # no inline
240
+ def instance_call(y)
241
+ @x + y
242
+ end
243
+ end
244
+
245
+ loop do
246
+ example_local_variables RANDOM.rand(1000), RANDOM.rand(1000)
247
+ example_local_variables_state RANDOM.rand(1000), RANDOM.rand(1000)
248
+ example_arith_operator RANDOM.rand(1000), RANDOM.rand(1000)
249
+ example_compare_operator RANDOM.rand(1000), RANDOM.rand(1000)
250
+ example_phi [true, false].sample, RANDOM.rand(1000)
251
+ example_simple_call ExampleObject.new(RANDOM.rand(1000)), RANDOM.rand(1000)
252
+ example_stamp RANDOM.rand(1000)
253
+ example_full_escape RANDOM.rand(1000)
254
+ example_no_escape RANDOM.rand(1000)
255
+ example_partial_escape [true, false].sample, RANDOM.rand(1000)
256
+ example_if [true, false].sample, RANDOM.rand(1000), RANDOM.rand(1000)
257
+ example_if_never_taken false, RANDOM.rand(1000), RANDOM.rand(1000)
258
+ example_int_switch RANDOM.rand(3), RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)
259
+ example_string_switch ['foo', 'bar', 'baz'].sample, RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)
260
+ example_while RANDOM.rand(10)
261
+ example_for RANDOM.rand(10)
262
+ example_nested_while RANDOM.rand(10)
263
+ example_while_break RANDOM.rand(10)
264
+ begin
265
+ example_raise
266
+ rescue Exception => e
267
+ #
268
+ end
269
+ example_rescue
270
+ example_raise_rescue
271
+ example_object_allocation RANDOM.rand(1000)
272
+ example_array_allocation RANDOM.rand(1000), RANDOM.rand(1000)
273
+ example_field_write ExampleObject.new(RANDOM.rand(1000)), RANDOM.rand(1000)
274
+ example_field_read ExampleObject.new(RANDOM.rand(1000))
275
+ example_array_write [RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)], RANDOM.rand(3), RANDOM.rand(1000)
276
+ example_array_read [RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)], RANDOM.rand(3)
277
+ example_instance_of [Object.new, ExampleObject.new(0)].sample
278
+ end