seafoam 0.3 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/workflows.yml +40 -0
  3. data/.gitignore +0 -1
  4. data/.rubocop.yml +1 -1
  5. data/.ruby-version +1 -1
  6. data/Gemfile.lock +59 -0
  7. data/README.md +76 -3
  8. data/bin/bgv2isabelle +16 -45
  9. data/bin/bgv2json +18 -36
  10. data/bin/cfg2asm +24 -0
  11. data/bin/seafoam +1 -1
  12. data/demos/box-unbox-stats +65 -0
  13. data/docs/bgv.md +2 -1
  14. data/docs/getting-graphs.md +8 -0
  15. data/examples/Fib.java +1 -1
  16. data/examples/fib-java.bgv.gz +0 -0
  17. data/examples/fib.js +1 -1
  18. data/examples/java/JavaExamples.java +1 -1
  19. data/examples/ruby/clamps.rb +20 -0
  20. data/examples/ruby/graal.patch +15 -0
  21. data/examples/ruby/ruby_examples.rb +278 -0
  22. data/lib/seafoam.rb +5 -1
  23. data/lib/seafoam/annotators/graal.rb +1 -1
  24. data/lib/seafoam/bgv/bgv_parser.rb +10 -2
  25. data/lib/seafoam/cfg/cfg_parser.rb +93 -0
  26. data/lib/seafoam/cfg/disassembler.rb +70 -0
  27. data/lib/seafoam/commands.rb +190 -30
  28. data/lib/seafoam/graal/source.rb +23 -0
  29. data/lib/seafoam/graph.rb +25 -1
  30. data/lib/seafoam/graphviz_writer.rb +21 -2
  31. data/lib/seafoam/isabelle_writer.rb +46 -0
  32. data/lib/seafoam/json_writer.rb +58 -0
  33. data/lib/seafoam/version.rb +1 -1
  34. data/seafoam.gemspec +4 -2
  35. data/spec/seafoam/annotators/graal_spec.rb +7 -7
  36. data/spec/seafoam/bgv/bgv_parser_spec.rb +13 -3
  37. data/spec/seafoam/cfg/cfg_parser_spec.rb +21 -0
  38. data/spec/seafoam/cfg/disassembler_spec.rb +32 -0
  39. data/spec/seafoam/command_spec.rb +86 -40
  40. data/spec/seafoam/json_writer_spec.rb +14 -0
  41. data/spec/seafoam/spec_helpers.rb +4 -0
  42. data/spec/seafoam/spotlight_spec.rb +1 -1
  43. data/tools/render-all +2 -2
  44. metadata +33 -96
  45. data/.github/workflows/rubocop.yml +0 -10
  46. data/.github/workflows/specs.yml +0 -19
  47. data/examples/fib-java.bgv +0 -0
  48. data/examples/fib-js.bgv +0 -0
  49. data/examples/fib-ruby.bgv +0 -0
  50. data/examples/identity.bgv +0 -0
  51. data/examples/java/exampleArithOperator.bgv +0 -0
  52. data/examples/java/exampleArithOperator.cfg +0 -925
  53. data/examples/java/exampleArrayAllocation.bgv +0 -0
  54. data/examples/java/exampleArrayAllocation.cfg +0 -5268
  55. data/examples/java/exampleArrayRead.bgv +0 -0
  56. data/examples/java/exampleArrayRead.cfg +0 -2263
  57. data/examples/java/exampleArrayWrite.bgv +0 -0
  58. data/examples/java/exampleArrayWrite.cfg +0 -2315
  59. data/examples/java/exampleCatch.bgv +0 -0
  60. data/examples/java/exampleCatch.cfg +0 -4150
  61. data/examples/java/exampleCompareOperator.bgv +0 -0
  62. data/examples/java/exampleCompareOperator.cfg +0 -1109
  63. data/examples/java/exampleDoubleSynchronized.bgv +0 -0
  64. data/examples/java/exampleDoubleSynchronized.cfg +0 -26497
  65. data/examples/java/exampleExactArith.bgv +0 -0
  66. data/examples/java/exampleExactArith.cfg +0 -1888
  67. data/examples/java/exampleFieldRead.bgv +0 -0
  68. data/examples/java/exampleFieldRead.cfg +0 -1228
  69. data/examples/java/exampleFieldWrite.bgv +0 -0
  70. data/examples/java/exampleFieldWrite.cfg +0 -1102
  71. data/examples/java/exampleFor.bgv +0 -0
  72. data/examples/java/exampleFor.cfg +0 -3936
  73. data/examples/java/exampleFullEscape.bgv +0 -0
  74. data/examples/java/exampleFullEscape.cfg +0 -5893
  75. data/examples/java/exampleIf.bgv +0 -0
  76. data/examples/java/exampleIf.cfg +0 -2462
  77. data/examples/java/exampleIfNeverTaken.bgv +0 -0
  78. data/examples/java/exampleIfNeverTaken.cfg +0 -2476
  79. data/examples/java/exampleInstanceOfManyImpls.bgv +0 -0
  80. data/examples/java/exampleInstanceOfManyImpls.cfg +0 -6391
  81. data/examples/java/exampleInstanceOfOneImpl.bgv +0 -0
  82. data/examples/java/exampleInstanceOfOneImpl.cfg +0 -2604
  83. data/examples/java/exampleIntSwitch.bgv +0 -0
  84. data/examples/java/exampleIntSwitch.cfg +0 -3121
  85. data/examples/java/exampleInterfaceCallManyImpls.bgv +0 -0
  86. data/examples/java/exampleInterfaceCallManyImpls.cfg +0 -1358
  87. data/examples/java/exampleInterfaceCallOneImpl.bgv +0 -0
  88. data/examples/java/exampleInterfaceCallOneImpl.cfg +0 -3859
  89. data/examples/java/exampleLocalInstanceOf.bgv +0 -0
  90. data/examples/java/exampleLocalInstanceOf.cfg +0 -5276
  91. data/examples/java/exampleLocalSynchronized.bgv +0 -0
  92. data/examples/java/exampleLocalSynchronized.cfg +0 -1364
  93. data/examples/java/exampleLocalVariables.bgv +0 -0
  94. data/examples/java/exampleLocalVariables.cfg +0 -1195
  95. data/examples/java/exampleLocalVariablesState.bgv +0 -0
  96. data/examples/java/exampleLocalVariablesState.cfg +0 -1673
  97. data/examples/java/exampleNestedWhile.bgv +0 -0
  98. data/examples/java/exampleNestedWhile.cfg +0 -15499
  99. data/examples/java/exampleNestedWhileBreak.bgv +0 -0
  100. data/examples/java/exampleNestedWhileBreak.cfg +0 -11162
  101. data/examples/java/exampleNoEscape.bgv +0 -0
  102. data/examples/java/exampleNoEscape.cfg +0 -974
  103. data/examples/java/exampleObjectAllocation.bgv +0 -0
  104. data/examples/java/exampleObjectAllocation.cfg +0 -5287
  105. data/examples/java/examplePartialEscape.bgv +0 -0
  106. data/examples/java/examplePartialEscape.cfg +0 -7042
  107. data/examples/java/examplePhi.bgv +0 -0
  108. data/examples/java/examplePhi.cfg +0 -3227
  109. data/examples/java/exampleReducible.bgv +0 -0
  110. data/examples/java/exampleReducible.cfg +0 -5578
  111. data/examples/java/exampleSimpleCall.bgv +0 -0
  112. data/examples/java/exampleSimpleCall.cfg +0 -1435
  113. data/examples/java/exampleStamp.bgv +0 -0
  114. data/examples/java/exampleStamp.cfg +0 -913
  115. data/examples/java/exampleStaticCall.bgv +0 -0
  116. data/examples/java/exampleStaticCall.cfg +0 -1154
  117. data/examples/java/exampleStringSwitch.bgv +0 -0
  118. data/examples/java/exampleStringSwitch.cfg +0 -15377
  119. data/examples/java/exampleSynchronized.bgv +0 -0
  120. data/examples/java/exampleSynchronized.cfg +0 -26027
  121. data/examples/java/exampleThrow.bgv +0 -0
  122. data/examples/java/exampleThrow.cfg +0 -780
  123. data/examples/java/exampleThrowCatch.bgv +0 -0
  124. data/examples/java/exampleThrowCatch.cfg +0 -744
  125. data/examples/java/exampleUnsafeRead.bgv +0 -0
  126. data/examples/java/exampleUnsafeRead.cfg +0 -912
  127. data/examples/java/exampleUnsafeWrite.bgv +0 -0
  128. data/examples/java/exampleUnsafeWrite.cfg +0 -962
  129. data/examples/java/exampleWhile.bgv +0 -0
  130. data/examples/java/exampleWhile.cfg +0 -3936
  131. data/examples/java/exampleWhileBreak.bgv +0 -0
  132. data/examples/java/exampleWhileBreak.cfg +0 -5963
  133. data/examples/matmult-java.bgv +0 -0
  134. data/examples/matmult-ruby.bgv +0 -0
  135. data/examples/overflow.bgv +0 -0
  136. data/spec/seafoam/bgv/fixtures/not.bgv +0 -1
  137. data/spec/seafoam/bgv/fixtures/unsupported.bgv +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85ce198d6b6117c1e691ea871829e0d93d480ab26709f6ba494aa8f73957fefb
4
- data.tar.gz: 83275a9095d3827a6f5c7d8eab9d9ea49ed35b6fe3f527d6c6299f6719a65956
3
+ metadata.gz: 6f5cdd6b29d9c25bc7db525b2f49d6937fb996bc108a7bf18ddf0364575e6999
4
+ data.tar.gz: 510608b5d784ef4c58768aafb42372bdd33aad226a6123e9ad72ea77845a8050
5
5
  SHA512:
6
- metadata.gz: d5b74e656d6a80af67233f4fcae60bbdfc291bab4a6d4a92ce283450b5dd4e318da59440a4d78d539033910cba2560068c57f112213e4ce8b493e731e92ff799
7
- data.tar.gz: a7acdd55bcb41bc5f78b0f06583cb678d7e1d2beaadab02c6e2e42945fac8d6d4c4dfccddabe64c9b47f223722e7808b5fb9dd1353d4912fdbe757ece60950c5
6
+ metadata.gz: 125d9c14699c1a9a72bc1311b2673cf24d725af3c4da38eac1c2c89ebce4d6157c3e08ad7cc7b8769f8c755227cd04da4b9a6f53ae30f0f3ce38e7a1cf12d4b2
7
+ data.tar.gz: 2430c0b5f04378767c5bbbb51274900deae22291fd905831f4a5d5847edd5e7497e3df94a434ab803689ee4f9b3f6cd5d6740bdc28dbf96d7da329c8610ac6e5
@@ -0,0 +1,40 @@
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: gem install bundler:1.17.2
10
+ - run: bundle install
11
+ - run: bundle exec rubocop
12
+ specs:
13
+ strategy:
14
+ matrix:
15
+ os: [ubuntu, macos]
16
+ ruby: [2.5, 2.6, 2.7, 3.0]
17
+ runs-on: ${{ matrix.os }}-latest
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ bundler-cache: true
24
+ - run: bundle install
25
+ - run: if [[ $(uname) == "Darwin" ]]; then brew install graphviz capstone; else sudo apt-get install graphviz libcapstone3; fi
26
+ - run: bundle exec rspec
27
+ specs-no-dependencies:
28
+ strategy:
29
+ matrix:
30
+ os: [ubuntu, macos]
31
+ ruby: [2.5, 2.6, 2.7, 3.0]
32
+ runs-on: ${{ matrix.os }}-latest
33
+ steps:
34
+ - uses: actions/checkout@v2
35
+ - uses: ruby/setup-ruby@v1
36
+ with:
37
+ ruby-version: ${{ matrix.ruby }}
38
+ bundler-cache: true
39
+ - run: bundle install
40
+ - run: NO_DEPENDENCIES_INSTALLED=true bundle exec rspec
data/.gitignore CHANGED
@@ -4,4 +4,3 @@
4
4
  *.svg
5
5
  *.class
6
6
  /.idea
7
- /Gemfile.lock
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.5
3
3
  Exclude:
4
- - examples/*
4
+ - examples/**/*.rb
5
5
 
6
6
  Style/FrozenStringLiteralComment:
7
7
  Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.8
1
+ 2.5.9
data/Gemfile.lock ADDED
@@ -0,0 +1,59 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ seafoam (0.7)
5
+ crabstone (~> 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.2)
11
+ benchmark-ips (2.8.4)
12
+ crabstone (4.0.3)
13
+ ffi
14
+ diff-lcs (1.4.4)
15
+ ffi (1.15.0)
16
+ parallel (1.20.1)
17
+ parser (3.0.1.1)
18
+ ast (~> 2.4.1)
19
+ rainbow (3.0.0)
20
+ regexp_parser (2.1.1)
21
+ rexml (3.2.5)
22
+ rspec (3.10.0)
23
+ rspec-core (~> 3.10.0)
24
+ rspec-expectations (~> 3.10.0)
25
+ rspec-mocks (~> 3.10.0)
26
+ rspec-core (3.10.1)
27
+ rspec-support (~> 3.10.0)
28
+ rspec-expectations (3.10.1)
29
+ diff-lcs (>= 1.2.0, < 2.0)
30
+ rspec-support (~> 3.10.0)
31
+ rspec-mocks (3.10.2)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.10.0)
34
+ rspec-support (3.10.2)
35
+ rubocop (0.93.1)
36
+ parallel (~> 1.10)
37
+ parser (>= 2.7.1.5)
38
+ rainbow (>= 2.2.2, < 4.0)
39
+ regexp_parser (>= 1.8)
40
+ rexml
41
+ rubocop-ast (>= 0.6.0)
42
+ ruby-progressbar (~> 1.7)
43
+ unicode-display_width (>= 1.4.0, < 2.0)
44
+ rubocop-ast (1.5.0)
45
+ parser (>= 3.0.1.1)
46
+ ruby-progressbar (1.11.0)
47
+ unicode-display_width (1.7.0)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ benchmark-ips (~> 2.7)
54
+ rspec (~> 3.8)
55
+ rubocop (~> 0.74)
56
+ seafoam!
57
+
58
+ BUNDLED WITH
59
+ 1.17.2
data/README.md CHANGED
@@ -14,15 +14,18 @@ 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 PNG output
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
24
28
  * diffing of graphs
25
- * visualization of basic blocks
26
29
  * breaking of edges for very congested graphs
27
30
  * the same speed in rendering big graphs - Seafoam is best suited for looking at graphs before lowering, which is what language developers are usually doing, or use spotlight
28
31
 
@@ -53,7 +56,7 @@ seafoam 0.1
53
56
  seafoam 0.1
54
57
  ```
55
58
 
56
- #### RedHat
59
+ ### RedHat
57
60
 
58
61
  ```
59
62
  % sudo yum install ruby graphviz
@@ -62,6 +65,15 @@ seafoam 0.1
62
65
  seafoam 0.1
63
66
  ```
64
67
 
68
+ ### Capstone
69
+
70
+ To use the `cfg2asm` disassembler, you'll then need to install Capstone.
71
+
72
+ ```
73
+ % brew install capstone # macOS
74
+ % sudo apt-get install libcapstone3 # Ubuntu
75
+ ```
76
+
65
77
  ## Quick-start demo
66
78
 
67
79
  ```
@@ -183,6 +195,26 @@ Output:
183
195
  }
184
196
  ```
185
197
 
198
+ #### Print node source information
199
+
200
+ ```
201
+ % seafoam examples/fib-ruby.bgv:8:2443 source
202
+ java.lang.Math#addExact
203
+ org.truffleruby.core.numeric.IntegerNodes$AddNode#add
204
+ org.truffleruby.core.numeric.IntegerNodesFactory$AddNodeFactory$AddNodeGen#executeAdd
205
+ org.truffleruby.core.inlined.InlinedAddNode#intAdd
206
+ org.truffleruby.core.inlined.InlinedAddNodeGen#execute
207
+ org.truffleruby.language.control.IfElseNode#execute
208
+ org.truffleruby.language.control.SequenceNode#execute
209
+ org.truffleruby.language.arguments.CheckArityNode#execute
210
+ org.truffleruby.language.control.SequenceNode#execute
211
+ org.truffleruby.language.methods.CatchForMethodNode#execute
212
+ org.truffleruby.language.methods.ExceptionTranslatingNode#execute
213
+ org.truffleruby.language.RubyRootNode#execute
214
+ org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#executeRootNode
215
+ org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#profiledPERoot
216
+ ```
217
+
186
218
  #### Render a graph
187
219
 
188
220
  Render a graph as a PDF image and have it opened automatically.
@@ -227,11 +259,52 @@ graph0 = # 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhas
227
259
  ...
228
260
  ```
229
261
 
262
+ Convert a BGV file to JSON.
263
+
264
+ ```
265
+ % bgv2json examples/fib-java.bgv
266
+ graph0 = # 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase
267
+ (add_node 0 StartNode [2] [8]
268
+ (add_node 1 (ParameterNode 0) [] [2, 5, 9, 11, 14, 16]
269
+ (add_node 2 FrameState [1] [0]
270
+ (add_node 3 (ConstantNode 1) [] []
271
+ (add_node 4 (ConstantNode 2) [] [5]
272
+ (add_node 5 IntegerLessThanNode [1, 4] [8]
273
+ (add_node 6 BeginNode [8] [13]
274
+ (add_node 7 BeginNode [8] [9]
275
+ (add_node 8 IfNode [0, 5] [7, 6]
276
+ ...
277
+ ```
278
+
279
+ #### Disassembling
280
+
281
+ ```
282
+ % cfg2asm examples/java/exampleArithOperator.cfg
283
+ [examples/java/exampleArithOperator.cfg]
284
+ ;Comment 0: 3
285
+ ;Comment 0: 1
286
+ 0x112e2f660: nop dword ptr [rax + rax]
287
+ ;Comment 5: block B0 null
288
+ ;Comment 5: 0 [rsi|DWORD, rdx|DWORD, rbp|QWORD] = LABEL numbPhis: 0 align: false label: ?
289
+ ;Comment 5: 4 [] = HOTSPOTLOCKSTACK frameMapBuilder: org.graalvm.compiler.lir.amd64.AMD64FrameMapBuilder@143082de0 slotKind: QWORD
290
+ ;Comment 5: 10 rsi|DWORD = ADD (x: rsi|DWORD, y: rdx|DWORD) size: DWORD
291
+ 0x112e2f665: add esi, edx
292
+ ;Comment 7: 12 rax|DWORD = MOVE rsi|DWORD moveKind: DWORD
293
+ 0x112e2f667: mov eax, esi
294
+ ;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
295
+ ;Comment 9: 12
296
+ 0x112e2f669: test dword ptr [rip - 0x46c4669], eax
297
+ 0x112e2f66f: vzeroupper
298
+ 0x112e2f672: ret
299
+ ...
300
+ ```
301
+
230
302
  ## Options for GraalVM graphs
231
303
 
232
304
  * `--show-frame-state` shows frame state nodes, which are hidden by default
233
305
  * `--hide-floating` hides nodes that aren't fixed by control flow
234
306
  * `--no-reduce-edges` turns off the option to reduce the number of edges by inlining simple nodes above their users
307
+ * `--draw-blocks` to draw basic block information if available
235
308
 
236
309
  ## Configuration
237
310
 
data/bin/bgv2isabelle CHANGED
@@ -2,52 +2,23 @@
2
2
 
3
3
  require 'seafoam'
4
4
 
5
- # definition eg_short_cut_or1 :: IRGraph where
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
- ARGV.each do |file|
24
- parser = Seafoam::BGV::BGVParser.new(file)
25
- parser.read_file_header
26
- parser.skip_document_props
7
+ begin
8
+ # Load configuraiton.
9
+ config = Seafoam::Config.new
10
+ config.load_config
27
11
 
28
- loop do
29
- index, = parser.read_graph_preheader
30
- break unless index
31
-
32
- graph_header = parser.read_graph_header
33
- graph = parser.read_graph
34
-
35
- puts "graph#{index} = # #{parser.graph_name(graph_header)}"
36
-
37
- graph.nodes.each_value do |node|
38
- node_class = node.props[:node_class][:node_class]
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
- ARGV.each do |file|
7
- parser = Seafoam::BGV::BGVParser.new(file)
8
- parser.read_file_header
9
- parser.skip_document_props
10
-
11
- loop do
12
- index, = parser.read_graph_preheader
13
- break unless index
14
-
15
- graph_header = parser.read_graph_header
16
-
17
- graph = parser.read_graph
18
- Seafoam::Annotators.apply graph
19
-
20
- name = parser.graph_name(graph_header)
21
-
22
- nodes = []
23
- edges = []
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
@@ -11,7 +11,7 @@ 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
17
  # Re-raise the exception so the user sees it, if debugging is
@@ -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)}%"