@@ -1738,6 +1738,20 @@ rb_str_tmp_frozen_acquire(VALUE orig)
1738
1738
VALUE
1739
1739
rb_str_tmp_frozen_no_embed_acquire (VALUE orig )
1740
1740
{
1741
+ WHEN_USING_MMTK ({
1742
+ // The default GC may lock (mprotect with PROT_NONE) pages of GC memory during compaction.
1743
+ // If that happens while a pointer to the string payload in an embedded string is used for
1744
+ // IO, with GVL released, the OS or external native programs may read or write protected
1745
+ // pages, causing segmentation fault. The intention of `rb_str_tmp_frozen_no_embed_acquire`
1746
+ // is working around this problem by forcing the given `orig` string to be allocated in the
1747
+ // malloc heap.
1748
+ //
1749
+ // When using MMTk, this doesn't make sense because MMTk never protect pages of live
1750
+ // objects, and we allocate non-embedded string buffers as `imemo:mmtk_strbuf` in the MMTk
1751
+ // heap. So we simply call `rb_str_tmp_frozen_acquire` instead.
1752
+ return rb_str_tmp_frozen_acquire (orig );
1753
+ })
1754
+
1741
1755
if (OBJ_FROZEN_RAW (orig ) && !STR_EMBED_P (orig ) && !rb_str_reembeddable_p (orig )) return orig ;
1742
1756
if (STR_SHARED_P (orig ) && !STR_EMBED_P (RSTRING (orig )-> as .heap .aux .shared )) return rb_str_tmp_frozen_acquire (orig );
1743
1757
@@ -1762,13 +1776,6 @@ rb_str_tmp_frozen_no_embed_acquire(VALUE orig)
1762
1776
RSTRING (str )-> as .heap .ptr = RSTRING (orig )-> as .heap .ptr ;
1763
1777
RBASIC (str )-> flags |= RBASIC (orig )-> flags & STR_NOFREE ;
1764
1778
RBASIC (orig )-> flags &= ~STR_NOFREE ;
1765
-
1766
- WHEN_USING_MMTK ({
1767
- // Note: The root may be no-free.
1768
- VALUE strbuf = rb_mmtk_str_get_strbuf_nullable (orig );
1769
- rb_mmtk_str_set_strbuf (str , strbuf );
1770
- })
1771
-
1772
1779
STR_SET_SHARED (orig , str );
1773
1780
}
1774
1781
0 commit comments