seafoam 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/workflows.yml +39 -0
  3. data/.rubocop.yml +1 -1
  4. data/README.md +75 -2
  5. data/bin/bgv2isabelle +16 -45
  6. data/bin/bgv2json +18 -36
  7. data/bin/cfg2asm +24 -0
  8. data/bin/seafoam +1 -1
  9. data/demos/box-unbox-stats +65 -0
  10. data/docs/getting-graphs.md +4 -0
  11. data/examples/fib-java.bgv.gz +0 -0
  12. data/examples/fib.js +1 -1
  13. data/examples/java/JavaExamples.java +1 -1
  14. data/examples/ruby/clamps.rb +20 -0
  15. data/examples/ruby/graal.patch +15 -0
  16. data/examples/ruby/ruby_examples.rb +278 -0
  17. data/lib/seafoam.rb +5 -0
  18. data/lib/seafoam/annotators/graal.rb +1 -1
  19. data/lib/seafoam/cfg/cfg_parser.rb +93 -0
  20. data/lib/seafoam/cfg/disassembler.rb +70 -0
  21. data/lib/seafoam/commands.rb +185 -29
  22. data/lib/seafoam/graal/source.rb +23 -0
  23. data/lib/seafoam/isabelle_writer.rb +46 -0
  24. data/lib/seafoam/json_writer.rb +58 -0
  25. data/lib/seafoam/version.rb +1 -1
  26. data/seafoam.gemspec +2 -1
  27. data/spec/seafoam/annotators/graal_spec.rb +7 -7
  28. data/spec/seafoam/bgv/bgv_parser_spec.rb +2 -2
  29. data/spec/seafoam/cfg/cfg_parser_spec.rb +21 -0
  30. data/spec/seafoam/cfg/disassembler_spec.rb +32 -0
  31. data/spec/seafoam/command_spec.rb +78 -30
  32. data/spec/seafoam/json_writer_spec.rb +14 -0
  33. data/spec/seafoam/spec_helpers.rb +4 -0
  34. data/tools/render-all +2 -2
  35. metadata +36 -102
  36. data/.github/workflows/rubocop.yml +0 -10
  37. data/.github/workflows/specs.yml +0 -19
  38. data/examples/fib-java.bgv +0 -0
  39. data/examples/fib-js.bgv +0 -0
  40. data/examples/fib-ruby.bgv +0 -0
  41. data/examples/identity.bgv +0 -0
  42. data/examples/java/exampleArithOperator.bgv +0 -0
  43. data/examples/java/exampleArithOperator.cfg +0 -925
  44. data/examples/java/exampleArrayAllocation.bgv +0 -0
  45. data/examples/java/exampleArrayAllocation.cfg +0 -5268
  46. data/examples/java/exampleArrayRead.bgv +0 -0
  47. data/examples/java/exampleArrayRead.cfg +0 -2263
  48. data/examples/java/exampleArrayWrite.bgv +0 -0
  49. data/examples/java/exampleArrayWrite.cfg +0 -2315
  50. data/examples/java/exampleCatch.bgv +0 -0
  51. data/examples/java/exampleCatch.cfg +0 -4150
  52. data/examples/java/exampleCompareOperator.bgv +0 -0
  53. data/examples/java/exampleCompareOperator.cfg +0 -1109
  54. data/examples/java/exampleDoubleSynchronized.bgv +0 -0
  55. data/examples/java/exampleDoubleSynchronized.cfg +0 -26497
  56. data/examples/java/exampleExactArith.bgv +0 -0
  57. data/examples/java/exampleExactArith.cfg +0 -1888
  58. data/examples/java/exampleFieldRead.bgv +0 -0
  59. data/examples/java/exampleFieldRead.cfg +0 -1228
  60. data/examples/java/exampleFieldWrite.bgv +0 -0
  61. data/examples/java/exampleFieldWrite.cfg +0 -1102
  62. data/examples/java/exampleFor.bgv +0 -0
  63. data/examples/java/exampleFor.cfg +0 -3936
  64. data/examples/java/exampleFullEscape.bgv +0 -0
  65. data/examples/java/exampleFullEscape.cfg +0 -5893
  66. data/examples/java/exampleIf.bgv +0 -0
  67. data/examples/java/exampleIf.cfg +0 -2462
  68. data/examples/java/exampleIfNeverTaken.bgv +0 -0
  69. data/examples/java/exampleIfNeverTaken.cfg +0 -2476
  70. data/examples/java/exampleInstanceOfManyImpls.bgv +0 -0
  71. data/examples/java/exampleInstanceOfManyImpls.cfg +0 -6391
  72. data/examples/java/exampleInstanceOfOneImpl.bgv +0 -0
  73. data/examples/java/exampleInstanceOfOneImpl.cfg +0 -2604
  74. data/examples/java/exampleIntSwitch.bgv +0 -0
  75. data/examples/java/exampleIntSwitch.cfg +0 -3121
  76. data/examples/java/exampleInterfaceCallManyImpls.bgv +0 -0
  77. data/examples/java/exampleInterfaceCallManyImpls.cfg +0 -1358
  78. data/examples/java/exampleInterfaceCallOneImpl.bgv +0 -0
  79. data/examples/java/exampleInterfaceCallOneImpl.cfg +0 -3859
  80. data/examples/java/exampleLocalInstanceOf.bgv +0 -0
  81. data/examples/java/exampleLocalInstanceOf.cfg +0 -5276
  82. data/examples/java/exampleLocalSynchronized.bgv +0 -0
  83. data/examples/java/exampleLocalSynchronized.cfg +0 -1364
  84. data/examples/java/exampleLocalVariables.bgv +0 -0
  85. data/examples/java/exampleLocalVariables.cfg +0 -1195
  86. data/examples/java/exampleLocalVariablesState.bgv +0 -0
  87. data/examples/java/exampleLocalVariablesState.cfg +0 -1673
  88. data/examples/java/exampleNestedWhile.bgv +0 -0
  89. data/examples/java/exampleNestedWhile.cfg +0 -15499
  90. data/examples/java/exampleNestedWhileBreak.bgv +0 -0
  91. data/examples/java/exampleNestedWhileBreak.cfg +0 -11162
  92. data/examples/java/exampleNoEscape.bgv +0 -0
  93. data/examples/java/exampleNoEscape.cfg +0 -974
  94. data/examples/java/exampleObjectAllocation.bgv +0 -0
  95. data/examples/java/exampleObjectAllocation.cfg +0 -5287
  96. data/examples/java/examplePartialEscape.bgv +0 -0
  97. data/examples/java/examplePartialEscape.cfg +0 -7042
  98. data/examples/java/examplePhi.bgv +0 -0
  99. data/examples/java/examplePhi.cfg +0 -3227
  100. data/examples/java/exampleReducible.bgv +0 -0
  101. data/examples/java/exampleReducible.cfg +0 -5578
  102. data/examples/java/exampleSimpleCall.bgv +0 -0
  103. data/examples/java/exampleSimpleCall.cfg +0 -1435
  104. data/examples/java/exampleStamp.bgv +0 -0
  105. data/examples/java/exampleStamp.cfg +0 -913
  106. data/examples/java/exampleStaticCall.bgv +0 -0
  107. data/examples/java/exampleStaticCall.cfg +0 -1154
  108. data/examples/java/exampleStringSwitch.bgv +0 -0
  109. data/examples/java/exampleStringSwitch.cfg +0 -15377
  110. data/examples/java/exampleSynchronized.bgv +0 -0
  111. data/examples/java/exampleSynchronized.cfg +0 -26027
  112. data/examples/java/exampleThrow.bgv +0 -0
  113. data/examples/java/exampleThrow.cfg +0 -780
  114. data/examples/java/exampleThrowCatch.bgv +0 -0
  115. data/examples/java/exampleThrowCatch.cfg +0 -744
  116. data/examples/java/exampleUnsafeRead.bgv +0 -0
  117. data/examples/java/exampleUnsafeRead.cfg +0 -912
  118. data/examples/java/exampleUnsafeWrite.bgv +0 -0
  119. data/examples/java/exampleUnsafeWrite.cfg +0 -962
  120. data/examples/java/exampleWhile.bgv +0 -0
  121. data/examples/java/exampleWhile.cfg +0 -3936
  122. data/examples/java/exampleWhileBreak.bgv +0 -0
  123. data/examples/java/exampleWhileBreak.cfg +0 -5963
  124. data/examples/matmult-java.bgv +0 -0
  125. data/examples/matmult-ruby.bgv +0 -0
  126. data/examples/overflow.bgv +0 -0
  127. data/spec/seafoam/bgv/fixtures/not.bgv +0 -1
  128. data/spec/seafoam/bgv/fixtures/unsupported.bgv +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e76a6115614baaa5be993aa488f4aa245f8442066dc0bb92c6b7b9f9e1b78cad
4
- data.tar.gz: 987fdd58f2d0f7d5023c9760295fb458dabcd70a724567eb8445dcf2ff1ba271
3
+ metadata.gz: '08ef3412a15721b9bfd6184645579568626e2079ff1aaaeb9d9181270c25209f'
4
+ data.tar.gz: a139c2adb73d4912131b886a61482d2c67ee2090f1117a51669cfe334202ea37
5
5
  SHA512:
6
- metadata.gz: 1e81bcd44349ac1e6dd738e234fc31498ea47c2382d3682bf71535af2a9f54f3f6a3d06ff32a939abbd25112ccb366bacc9870a5ce599664e31be0efceb6e240
7
- data.tar.gz: 33e76594a4e77aebf5065f53c885bbe5212ab009f1a089b155d7a9859181461b794f057beb0af2ae5760031eecb7b5c422da967c1eec1073a8f0ab7a9a8c11b5
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
@@ -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/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 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
@@ -53,7 +57,7 @@ seafoam 0.1
53
57
  seafoam 0.1
54
58
  ```
55
59
 
56
- #### RedHat
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
- # 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)}%"
@@ -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.
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