seafoam 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/workflows.yml +39 -0
- data/.rubocop.yml +1 -1
- data/README.md +75 -2
- data/bin/bgv2isabelle +16 -45
- data/bin/bgv2json +18 -36
- data/bin/cfg2asm +24 -0
- data/bin/seafoam +1 -1
- data/demos/box-unbox-stats +65 -0
- data/docs/getting-graphs.md +4 -0
- data/examples/fib-java.bgv.gz +0 -0
- data/examples/fib.js +1 -1
- data/examples/java/JavaExamples.java +1 -1
- data/examples/ruby/clamps.rb +20 -0
- data/examples/ruby/graal.patch +15 -0
- data/examples/ruby/ruby_examples.rb +278 -0
- data/lib/seafoam.rb +5 -0
- data/lib/seafoam/annotators/graal.rb +1 -1
- data/lib/seafoam/cfg/cfg_parser.rb +93 -0
- data/lib/seafoam/cfg/disassembler.rb +70 -0
- data/lib/seafoam/commands.rb +185 -29
- data/lib/seafoam/graal/source.rb +23 -0
- data/lib/seafoam/isabelle_writer.rb +46 -0
- data/lib/seafoam/json_writer.rb +58 -0
- data/lib/seafoam/version.rb +1 -1
- data/seafoam.gemspec +2 -1
- data/spec/seafoam/annotators/graal_spec.rb +7 -7
- data/spec/seafoam/bgv/bgv_parser_spec.rb +2 -2
- data/spec/seafoam/cfg/cfg_parser_spec.rb +21 -0
- data/spec/seafoam/cfg/disassembler_spec.rb +32 -0
- data/spec/seafoam/command_spec.rb +78 -30
- data/spec/seafoam/json_writer_spec.rb +14 -0
- data/spec/seafoam/spec_helpers.rb +4 -0
- data/tools/render-all +2 -2
- metadata +36 -102
- data/.github/workflows/rubocop.yml +0 -10
- data/.github/workflows/specs.yml +0 -19
- data/examples/fib-java.bgv +0 -0
- data/examples/fib-js.bgv +0 -0
- data/examples/fib-ruby.bgv +0 -0
- data/examples/identity.bgv +0 -0
- data/examples/java/exampleArithOperator.bgv +0 -0
- data/examples/java/exampleArithOperator.cfg +0 -925
- data/examples/java/exampleArrayAllocation.bgv +0 -0
- data/examples/java/exampleArrayAllocation.cfg +0 -5268
- data/examples/java/exampleArrayRead.bgv +0 -0
- data/examples/java/exampleArrayRead.cfg +0 -2263
- data/examples/java/exampleArrayWrite.bgv +0 -0
- data/examples/java/exampleArrayWrite.cfg +0 -2315
- data/examples/java/exampleCatch.bgv +0 -0
- data/examples/java/exampleCatch.cfg +0 -4150
- data/examples/java/exampleCompareOperator.bgv +0 -0
- data/examples/java/exampleCompareOperator.cfg +0 -1109
- data/examples/java/exampleDoubleSynchronized.bgv +0 -0
- data/examples/java/exampleDoubleSynchronized.cfg +0 -26497
- data/examples/java/exampleExactArith.bgv +0 -0
- data/examples/java/exampleExactArith.cfg +0 -1888
- data/examples/java/exampleFieldRead.bgv +0 -0
- data/examples/java/exampleFieldRead.cfg +0 -1228
- data/examples/java/exampleFieldWrite.bgv +0 -0
- data/examples/java/exampleFieldWrite.cfg +0 -1102
- data/examples/java/exampleFor.bgv +0 -0
- data/examples/java/exampleFor.cfg +0 -3936
- data/examples/java/exampleFullEscape.bgv +0 -0
- data/examples/java/exampleFullEscape.cfg +0 -5893
- data/examples/java/exampleIf.bgv +0 -0
- data/examples/java/exampleIf.cfg +0 -2462
- data/examples/java/exampleIfNeverTaken.bgv +0 -0
- data/examples/java/exampleIfNeverTaken.cfg +0 -2476
- data/examples/java/exampleInstanceOfManyImpls.bgv +0 -0
- data/examples/java/exampleInstanceOfManyImpls.cfg +0 -6391
- data/examples/java/exampleInstanceOfOneImpl.bgv +0 -0
- data/examples/java/exampleInstanceOfOneImpl.cfg +0 -2604
- data/examples/java/exampleIntSwitch.bgv +0 -0
- data/examples/java/exampleIntSwitch.cfg +0 -3121
- data/examples/java/exampleInterfaceCallManyImpls.bgv +0 -0
- data/examples/java/exampleInterfaceCallManyImpls.cfg +0 -1358
- data/examples/java/exampleInterfaceCallOneImpl.bgv +0 -0
- data/examples/java/exampleInterfaceCallOneImpl.cfg +0 -3859
- data/examples/java/exampleLocalInstanceOf.bgv +0 -0
- data/examples/java/exampleLocalInstanceOf.cfg +0 -5276
- data/examples/java/exampleLocalSynchronized.bgv +0 -0
- data/examples/java/exampleLocalSynchronized.cfg +0 -1364
- data/examples/java/exampleLocalVariables.bgv +0 -0
- data/examples/java/exampleLocalVariables.cfg +0 -1195
- data/examples/java/exampleLocalVariablesState.bgv +0 -0
- data/examples/java/exampleLocalVariablesState.cfg +0 -1673
- data/examples/java/exampleNestedWhile.bgv +0 -0
- data/examples/java/exampleNestedWhile.cfg +0 -15499
- data/examples/java/exampleNestedWhileBreak.bgv +0 -0
- data/examples/java/exampleNestedWhileBreak.cfg +0 -11162
- data/examples/java/exampleNoEscape.bgv +0 -0
- data/examples/java/exampleNoEscape.cfg +0 -974
- data/examples/java/exampleObjectAllocation.bgv +0 -0
- data/examples/java/exampleObjectAllocation.cfg +0 -5287
- data/examples/java/examplePartialEscape.bgv +0 -0
- data/examples/java/examplePartialEscape.cfg +0 -7042
- data/examples/java/examplePhi.bgv +0 -0
- data/examples/java/examplePhi.cfg +0 -3227
- data/examples/java/exampleReducible.bgv +0 -0
- data/examples/java/exampleReducible.cfg +0 -5578
- data/examples/java/exampleSimpleCall.bgv +0 -0
- data/examples/java/exampleSimpleCall.cfg +0 -1435
- data/examples/java/exampleStamp.bgv +0 -0
- data/examples/java/exampleStamp.cfg +0 -913
- data/examples/java/exampleStaticCall.bgv +0 -0
- data/examples/java/exampleStaticCall.cfg +0 -1154
- data/examples/java/exampleStringSwitch.bgv +0 -0
- data/examples/java/exampleStringSwitch.cfg +0 -15377
- data/examples/java/exampleSynchronized.bgv +0 -0
- data/examples/java/exampleSynchronized.cfg +0 -26027
- data/examples/java/exampleThrow.bgv +0 -0
- data/examples/java/exampleThrow.cfg +0 -780
- data/examples/java/exampleThrowCatch.bgv +0 -0
- data/examples/java/exampleThrowCatch.cfg +0 -744
- data/examples/java/exampleUnsafeRead.bgv +0 -0
- data/examples/java/exampleUnsafeRead.cfg +0 -912
- data/examples/java/exampleUnsafeWrite.bgv +0 -0
- data/examples/java/exampleUnsafeWrite.cfg +0 -962
- data/examples/java/exampleWhile.bgv +0 -0
- data/examples/java/exampleWhile.cfg +0 -3936
- data/examples/java/exampleWhileBreak.bgv +0 -0
- data/examples/java/exampleWhileBreak.cfg +0 -5963
- data/examples/matmult-java.bgv +0 -0
- data/examples/matmult-ruby.bgv +0 -0
- data/examples/overflow.bgv +0 -0
- data/spec/seafoam/bgv/fixtures/not.bgv +0 -1
- data/spec/seafoam/bgv/fixtures/unsupported.bgv +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08ef3412a15721b9bfd6184645579568626e2079ff1aaaeb9d9181270c25209f'
|
4
|
+
data.tar.gz: a139c2adb73d4912131b886a61482d2c67ee2090f1117a51669cfe334202ea37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1939c6d23e19bb930475a33c7b1fd690c2e3c57b6fcfaed3eafd3c01d4c2e2775398f796f6a22c62012e6133a27dc4575df0f3afc96785efd1fdfbd3a8203203
|
7
|
+
data.tar.gz: 9fb0c9552c3df825ab9dde3b76480d08a4ef5587ccb85f1e9024e0fff85fd71b8707bd0d7cecccde69d35a6662e736ee1fbeb332f95745ca8e34a40d260da702
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: Workflows
|
2
|
+
on: [push]
|
3
|
+
jobs:
|
4
|
+
rubocop:
|
5
|
+
runs-on: ubuntu-latest
|
6
|
+
steps:
|
7
|
+
- uses: actions/checkout@v2
|
8
|
+
- uses: ruby/setup-ruby@v1
|
9
|
+
- run: bundle install
|
10
|
+
- run: bundle exec rubocop
|
11
|
+
specs:
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
os: [ubuntu, macos]
|
15
|
+
ruby: [2.5, 2.6, 2.7]
|
16
|
+
runs-on: ${{ matrix.os }}-latest
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
bundler-cache: true
|
23
|
+
- run: bundle install
|
24
|
+
- run: if [[ $(uname) == "Darwin" ]]; then brew install graphviz capstone; else sudo apt-get install graphviz libcapstone3; fi
|
25
|
+
- run: bundle exec rspec
|
26
|
+
specs-no-dependencies:
|
27
|
+
strategy:
|
28
|
+
matrix:
|
29
|
+
os: [ubuntu, macos]
|
30
|
+
ruby: [2.5, 2.6, 2.7]
|
31
|
+
runs-on: ${{ matrix.os }}-latest
|
32
|
+
steps:
|
33
|
+
- uses: actions/checkout@v2
|
34
|
+
- uses: ruby/setup-ruby@v1
|
35
|
+
with:
|
36
|
+
ruby-version: ${{ matrix.ruby }}
|
37
|
+
bundler-cache: true
|
38
|
+
- run: bundle install
|
39
|
+
- run: NO_DEPENDENCIES_INSTALLED=true bundle exec rspec
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -14,10 +14,14 @@ IGV, Seafoam:
|
|
14
14
|
* is able to some extent seek BGV files to load specific graphs without loading the rest of the file
|
15
15
|
* has a command-line interface
|
16
16
|
* can be used as a library
|
17
|
-
* has easy PDF, SVG and
|
17
|
+
* has easy PDF, SVG, PNG and JSON output
|
18
18
|
* is designed for accessibility
|
19
19
|
* looks prettier, in our opinion
|
20
20
|
|
21
|
+
Additionally, Seafoam adds:
|
22
|
+
|
23
|
+
* support for disassembling CFG files
|
24
|
+
|
21
25
|
Admittedly, Seafoam does not yet have:
|
22
26
|
|
23
27
|
* an interactive user interface
|
@@ -53,7 +57,7 @@ seafoam 0.1
|
|
53
57
|
seafoam 0.1
|
54
58
|
```
|
55
59
|
|
56
|
-
|
60
|
+
### RedHat
|
57
61
|
|
58
62
|
```
|
59
63
|
% sudo yum install ruby graphviz
|
@@ -62,6 +66,15 @@ seafoam 0.1
|
|
62
66
|
seafoam 0.1
|
63
67
|
```
|
64
68
|
|
69
|
+
### Capstone
|
70
|
+
|
71
|
+
To use the `cfg2asm` disassembler, you'll then need to install Capstone.
|
72
|
+
|
73
|
+
```
|
74
|
+
% brew install capstone # macOS
|
75
|
+
% sudo apt-get install libcapstone3 # Ubuntu
|
76
|
+
```
|
77
|
+
|
65
78
|
## Quick-start demo
|
66
79
|
|
67
80
|
```
|
@@ -183,6 +196,26 @@ Output:
|
|
183
196
|
}
|
184
197
|
```
|
185
198
|
|
199
|
+
#### Print node source information
|
200
|
+
|
201
|
+
```
|
202
|
+
% seafoam examples/fib-ruby.bgv:8:2443 source
|
203
|
+
java.lang.Math#addExact
|
204
|
+
org.truffleruby.core.numeric.IntegerNodes$AddNode#add
|
205
|
+
org.truffleruby.core.numeric.IntegerNodesFactory$AddNodeFactory$AddNodeGen#executeAdd
|
206
|
+
org.truffleruby.core.inlined.InlinedAddNode#intAdd
|
207
|
+
org.truffleruby.core.inlined.InlinedAddNodeGen#execute
|
208
|
+
org.truffleruby.language.control.IfElseNode#execute
|
209
|
+
org.truffleruby.language.control.SequenceNode#execute
|
210
|
+
org.truffleruby.language.arguments.CheckArityNode#execute
|
211
|
+
org.truffleruby.language.control.SequenceNode#execute
|
212
|
+
org.truffleruby.language.methods.CatchForMethodNode#execute
|
213
|
+
org.truffleruby.language.methods.ExceptionTranslatingNode#execute
|
214
|
+
org.truffleruby.language.RubyRootNode#execute
|
215
|
+
org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#executeRootNode
|
216
|
+
org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#profiledPERoot
|
217
|
+
```
|
218
|
+
|
186
219
|
#### Render a graph
|
187
220
|
|
188
221
|
Render a graph as a PDF image and have it opened automatically.
|
@@ -227,6 +260,46 @@ graph0 = # 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhas
|
|
227
260
|
...
|
228
261
|
```
|
229
262
|
|
263
|
+
Convert a BGV file to JSON.
|
264
|
+
|
265
|
+
```
|
266
|
+
% bgv2json examples/fib-java.bgv
|
267
|
+
graph0 = # 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase
|
268
|
+
(add_node 0 StartNode [2] [8]
|
269
|
+
(add_node 1 (ParameterNode 0) [] [2, 5, 9, 11, 14, 16]
|
270
|
+
(add_node 2 FrameState [1] [0]
|
271
|
+
(add_node 3 (ConstantNode 1) [] []
|
272
|
+
(add_node 4 (ConstantNode 2) [] [5]
|
273
|
+
(add_node 5 IntegerLessThanNode [1, 4] [8]
|
274
|
+
(add_node 6 BeginNode [8] [13]
|
275
|
+
(add_node 7 BeginNode [8] [9]
|
276
|
+
(add_node 8 IfNode [0, 5] [7, 6]
|
277
|
+
...
|
278
|
+
```
|
279
|
+
|
280
|
+
#### Disassembling
|
281
|
+
|
282
|
+
```
|
283
|
+
% cfg2asm examples/java/exampleArithOperator.cfg
|
284
|
+
[examples/java/exampleArithOperator.cfg]
|
285
|
+
;Comment 0: 3
|
286
|
+
;Comment 0: 1
|
287
|
+
0x112e2f660: nop dword ptr [rax + rax]
|
288
|
+
;Comment 5: block B0 null
|
289
|
+
;Comment 5: 0 [rsi|DWORD, rdx|DWORD, rbp|QWORD] = LABEL numbPhis: 0 align: false label: ?
|
290
|
+
;Comment 5: 4 [] = HOTSPOTLOCKSTACK frameMapBuilder: org.graalvm.compiler.lir.amd64.AMD64FrameMapBuilder@143082de0 slotKind: QWORD
|
291
|
+
;Comment 5: 10 rsi|DWORD = ADD (x: rsi|DWORD, y: rdx|DWORD) size: DWORD
|
292
|
+
0x112e2f665: add esi, edx
|
293
|
+
;Comment 7: 12 rax|DWORD = MOVE rsi|DWORD moveKind: DWORD
|
294
|
+
0x112e2f667: mov eax, esi
|
295
|
+
;Comment 9: 14 RETURN (savedRbp: rbp|QWORD, value: rax|DWORD) isStub: false requiresReservedStackAccessCheck: false thread: r15 scratchForSafepointOnReturn: rcx config: org.graalvm.compiler.hotspot.GraalHotSpotVMConfig@137f187d8
|
296
|
+
;Comment 9: 12
|
297
|
+
0x112e2f669: test dword ptr [rip - 0x46c4669], eax
|
298
|
+
0x112e2f66f: vzeroupper
|
299
|
+
0x112e2f672: ret
|
300
|
+
...
|
301
|
+
```
|
302
|
+
|
230
303
|
## Options for GraalVM graphs
|
231
304
|
|
232
305
|
* `--show-frame-state` shows frame state nodes, which are hidden by default
|
data/bin/bgv2isabelle
CHANGED
@@ -2,52 +2,23 @@
|
|
2
2
|
|
3
3
|
require 'seafoam'
|
4
4
|
|
5
|
-
#
|
6
|
-
# "eg_short_cut_or1 =
|
7
|
-
# (add_node 14 ReturnNode [13] []
|
8
|
-
# (add_node 13 PhiNode [10, 11, 12] []
|
9
|
-
# (add_node 12 (ConstantNode 0) [] []
|
10
|
-
# (add_node 11 (ConstantNode 42) [] []
|
11
|
-
# (add_node 10 MergeNode [7, 9] [14]
|
12
|
-
# (add_node 9 EndNode [] []
|
13
|
-
# (add_node 8 BeginNode [] [9]
|
14
|
-
# (add_node 7 EndNode [] []
|
15
|
-
# (add_node 6 BeginNode [] [7]
|
16
|
-
# (add_node 5 IfNode [3] [6, 8]
|
17
|
-
# (add_node 3 (ShortCircuitOrNode False False) [1, 2] []
|
18
|
-
# (add_node 2 (ParameterNode 1) [] []
|
19
|
-
# (add_node 1 (ParameterNode 0) [] []
|
20
|
-
# (add_node 0 StartNode [] [5]
|
21
|
-
# empty_graph))))))))))))))"
|
5
|
+
# This is the 'bgv2isabelle' command line entry point.
|
22
6
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
7
|
+
begin
|
8
|
+
# Load configuraiton.
|
9
|
+
config = Seafoam::Config.new
|
10
|
+
config.load_config
|
27
11
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
case node_class
|
40
|
-
when 'org.graalvm.compiler.nodes.ConstantNode'
|
41
|
-
desc = "(ConstantNode #{node.props['rawvalue']})"
|
42
|
-
when 'org.graalvm.compiler.nodes.ParameterNode'
|
43
|
-
desc = "(ParameterNode #{node.props['index']})"
|
44
|
-
else
|
45
|
-
desc = node_class.split('.').last
|
46
|
-
end
|
47
|
-
inputs = node.inputs.map(&:from).map(&:id)
|
48
|
-
outputs = node.outputs.map(&:to).map(&:id)
|
49
|
-
puts " (add_node #{node.id} #{desc} #{inputs.inspect} #{outputs.inspect}"
|
50
|
-
end
|
51
|
-
puts ' empty_graph' + (')' * graph.nodes.size)
|
12
|
+
# Run the command line.
|
13
|
+
commands = Seafoam::Commands.new($stdout, config)
|
14
|
+
commands.bgv2isabelle(*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}"
|
52
23
|
end
|
53
24
|
end
|
data/bin/bgv2json
CHANGED
@@ -1,42 +1,24 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'seafoam'
|
4
|
-
require 'json'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
graph.nodes.each_value do |node|
|
26
|
-
nodes.push(
|
27
|
-
id: node.id,
|
28
|
-
props: node.props
|
29
|
-
)
|
30
|
-
|
31
|
-
node.outputs.each do |edge|
|
32
|
-
edges.push(
|
33
|
-
from: edge.from.id,
|
34
|
-
to: edge.to.id,
|
35
|
-
props: edge.props
|
36
|
-
)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
puts JSON.generate(name: name, props: graph.props, nodes: nodes, edges: edges)
|
5
|
+
# This is the 'bgv2json' 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.bgv2json(*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}"
|
41
23
|
end
|
42
24
|
end
|
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
@@ -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/getting-graphs.md
CHANGED
@@ -53,3 +53,7 @@ You may want to disable on-stack-replacement and inlining with
|
|
53
53
|
easier to understand.
|
54
54
|
|
55
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/examples/fib-java.bgv.gz
CHANGED
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
|
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
|