Skip to content

[C extension parser] Disable function outlining on Clang#1055

Merged
byroot merged 1 commit into
ruby:masterfrom
samyron:sm/no-outline
Jul 22, 2026
Merged

[C extension parser] Disable function outlining on Clang#1055
byroot merged 1 commit into
ruby:masterfrom
samyron:sm/no-outline

Conversation

@samyron

@samyron samyron commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Starting with commit cc010c46889c8516a9a357336b262ce35779985f some of the generated instructions in the C extension parser started getting outlined into function calls when compiling with Clang on ARM64. This is most noticeable in json_eat_whitespace_resume_at:

image

Example of one of the outlined functions. They're all small.
image

Comparing the commit cc010c46889c8516a9a357336b262ce35779985f with cc010c46889c8516a9a357336b262ce35779985f:

== Parsing twitter.json (567916 bytes)
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after   103.000 i/100ms
Calculating -------------------------------------
               after      1.080k (± 0.6%) i/s  (926.34 μs/i) -      5.459k in   5.056880s

Comparison:
before:     1182.5 i/s
 after:     1079.5 i/s - 1.10x  slower


== Parsing citm_catalog.json (1727030 bytes)
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after    45.000 i/100ms
Calculating -------------------------------------
               after    454.163 (± 1.1%) i/s    (2.20 ms/i) -      2.295k in   5.053253s

Comparison:
before:      552.4 i/s
 after:      454.2 i/s - 1.22x  slower

Compiling with -Rpass=machine-outliner shows the result of the outlining pass:

remark: Saved 56 bytes by outlining 4 instructions from 6 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:866:17,
      ../../../../../../ext/json/ext/parser/parser.c:866:17, ../../../../../../ext/json/ext/parser/parser.c:866:17,
      ../../../../../../ext/json/ext/parser/parser.c:866:17, ../../../../../../ext/json/ext/parser/parser.c:866:17,
      ../../../../../../ext/json/ext/parser/parser.c:866:17) [-Rpass=machine-outliner]
remark: Saved 56 bytes by outlining 5 instructions from 5 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:851:74,
      ../../../../../../ext/json/ext/parser/parser.c:851:74, ../../../../../../ext/json/ext/parser/parser.c:851:74,
      ../../../../../../ext/json/ext/parser/parser.c:851:74, ../../../../../../ext/json/ext/parser/parser.c:851:74) [-Rpass=machine-outliner]
remark: Saved 52 bytes by outlining 4 instructions from 6 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:0:0,
      ../../../../../../ext/json/ext/parser/parser.c:0:0, ../../../../../../ext/json/ext/parser/parser.c:0:0,
      ../../../../../../ext/json/ext/parser/parser.c:0:0, ../../../../../../ext/json/ext/parser/parser.c:0:0,
      ../../../../../../ext/json/ext/parser/parser.c:0:0) [-Rpass=machine-outliner]
remark: Saved 40 bytes by outlining 4 instructions from 5 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:839:30,
      ../../../../../../ext/json/ext/parser/parser.c:839:30, ../../../../../../ext/json/ext/parser/parser.c:839:30,
      ../../../../../../ext/json/ext/parser/parser.c:839:30, ../../../../../../ext/json/ext/parser/parser.c:839:30) [-Rpass=machine-outliner]
remark: Saved 20 bytes by outlining 7 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1751:30,
      ../../../../../../ext/json/ext/parser/parser.c:1722:30) [-Rpass=machine-outliner]
remark: Saved 20 bytes by outlining 8 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/../simd/simd.h:116:54,
      ../../../../../../ext/json/ext/parser/../simd/simd.h:116:54) [-Rpass=machine-outliner]
remark: Saved 16 bytes by outlining 7 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1878:41,
      ../../../../../../ext/json/ext/parser/parser.c:1925:41) [-Rpass=machine-outliner]
remark: Saved 12 bytes by outlining 2 instructions from 6 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1674:25,
      ../../../../../../ext/json/ext/parser/parser.c:1877:44, ../../../../../../ext/json/ext/parser/parser.c:1651:25,
      ../../../../../../ext/json/ext/parser/parser.c:1384:18, ../../../../../../ext/json/ext/parser/parser.c:1921:28,
      ../../../../../../ext/json/ext/parser/parser.c:0:0) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 4 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:866:17,
      ../../../../../../ext/json/ext/parser/parser.c:866:17) [-Rpass=machine-outliner]
remark: Saved 12 bytes by outlining 2 instructions from 6 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1741:34,
      ../../../../../../ext/json/ext/parser/parser.c:1712:34, ../../../../../../ext/json/ext/parser/parser.c:1381:22,
      ../../../../../../ext/json/ext/parser/parser.c:1872:26, ../../../../../../ext/json/ext/parser/parser.c:0:0,
      ../../../../../../ext/json/ext/parser/parser.c:1381:22) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 4 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1269:17,
      ../../../../../../ext/json/ext/parser/parser.c:1269:17) [-Rpass=machine-outliner]
remark: Saved 12 bytes by outlining 2 instructions from 6 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:845:21,
      ../../../../../../ext/json/ext/parser/parser.c:845:21, ../../../../../../ext/json/ext/parser/parser.c:845:21,
      ../../../../../../ext/json/ext/parser/parser.c:845:21, ../../../../../../ext/json/ext/parser/parser.c:845:21,
      ../../../../../../ext/json/ext/parser/parser.c:845:21) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 3 instructions from 3 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1873:63,
      ../../../../../../ext/json/ext/parser/parser.c:1824:54, ../../../../../../ext/json/ext/parser/parser.c:1847:54) [-Rpass=machine-outliner]
remark: Saved 24 bytes by outlining 5 instructions from 6 locations. (Found at:
      .asdf/installs/ruby/4.0.5/include/ruby-4.0.0/ruby/internal/arithmetic/long_long.h:85:12,
      .asdf/installs/ruby/4.0.5/include/ruby-4.0.0/ruby/internal/arithmetic/long_long.h:98:12, ../../../../../../ext/json/ext/parser/parser.c:1537:1,
      ../../../../../../ext/json/ext/parser/parser.c:1121:12, ../../../../../../ext/json/ext/parser/parser.c:1161:16,
      ../../../../../../ext/json/ext/parser/parser.c:0:0) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 5 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1570:28,
      ../../../../../../ext/json/ext/parser/parser.c:1570:28) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 2 instructions from 5 locations. (Found at: <UNKNOWN LOCATION>, <UNKNOWN LOCATION>, <UNKNOWN LOCATION>,
      <UNKNOWN LOCATION>, <UNKNOWN LOCATION>) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 5 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1454:37,
      ../../../../../../ext/json/ext/parser/parser.c:1454:37) [-Rpass=machine-outliner]
remark: Saved 8 bytes by outlining 2 instructions from 5 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:587:12,
      ../../../../../../ext/json/ext/parser/parser.c:587:12, ../../../../../../ext/json/ext/parser/parser.c:587:12,
      ../../../../../../ext/json/ext/parser/parser.c:587:12, ../../../../../../ext/json/ext/parser/parser.c:587:12) [-Rpass=machine-outliner]
remark: Saved 4 bytes by outlining 3 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1674:25,
      ../../../../../../ext/json/ext/parser/parser.c:1651:25) [-Rpass=machine-outliner]
remark: Saved 4 bytes by outlining 3 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1271:57,
      ../../../../../../ext/json/ext/parser/parser.c:1271:57) [-Rpass=machine-outliner]
remark: Saved 4 bytes by outlining 3 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:464:53,
      ../../../../../../ext/json/ext/parser/parser.c:464:53) [-Rpass=machine-outliner]
remark: Saved 4 bytes by outlining 3 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1877:13,
      ../../../../../../ext/json/ext/parser/parser.c:1924:13) [-Rpass=machine-outliner]
remark: Saved 4 bytes by outlining 4 instructions from 2 locations. (Found at: ../../../../../../ext/json/ext/parser/parser.c:1250:51,
      ../../../../../../ext/json/ext/parser/parser.c:1169:74) [-Rpass=machine-outliner]
remark: Saved 4 bytes by outlining 4 instructions from 2 locations. (Found at:
      .asdf/installs/ruby/4.0.5/include/ruby-4.0.0/ruby/internal/value_type.h:191:30,
      .asdf/installs/ruby/4.0.5/include/ruby-4.0.0/ruby/internal/value_type.h:191:30) [-Rpass=machine-outliner]

Comparing master with this branch:

== Parsing twitter.json (567916 bytes)
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after   109.000 i/100ms
Calculating -------------------------------------
               after      1.185k (± 0.5%) i/s  (843.83 μs/i) -      5.995k in   5.058765s

Comparison:
before:     1095.5 i/s
 after:     1185.1 i/s - 1.08x  faster


== Parsing citm_catalog.json (1727030 bytes)
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +YJIT +PRISM [arm64-darwin24]
Warming up --------------------------------------
               after    54.000 i/100ms
Calculating -------------------------------------
               after    539.726 (± 0.9%) i/s    (1.85 ms/i) -      2.700k in   5.002536s

Comparison:
before:      436.2 i/s
 after:      539.7 i/s - 1.24x  faster

Note: It might be worthwhile to consider leaving function outlining enabled if Ruby was compiled with -Os or Oz but I have not attempted to do that.

@byroot
byroot merged commit f5fc245 into ruby:master Jul 22, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants