diff options
author | Peter Zhu <[email protected]> | 2023-12-06 16:38:59 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2023-12-07 10:49:06 -0500 |
commit | 0dc40bd2b740898fac4c6d4193ab6cd7ad52c05d (patch) | |
tree | 49db6a4273aedb82fb2d36fa67ec56cf8e9101bb | |
parent | b8df6b9e01d8971235ea42fc9098ce392f791928 (diff) |
Check need_major_gc during GC stress
need_major_gc is set when a major GC is required. However, if
gc_stress_no_major is also set, then it will not actually run a major
GC.
For example, the following script will sometimes crash:
```
GC.stress = 1
50000.times.map { [] }
```
With the following message:
```
[BUG] cannot create a new page after major GC
```
-rw-r--r-- | gc.c | 19 |
1 files changed, 9 insertions, 10 deletions
@@ -9460,19 +9460,18 @@ gc_start(rb_objspace_t *objspace, unsigned int reason) objspace->flags.immediate_sweep = !(flag & (1<<gc_stress_no_immediate_sweep)); } - else { - if (objspace->rgengc.need_major_gc) { - reason |= objspace->rgengc.need_major_gc; - do_full_mark = TRUE; - } - else if (RGENGC_FORCE_MAJOR_GC) { - reason = GPR_FLAG_MAJOR_BY_FORCE; - do_full_mark = TRUE; - } - objspace->rgengc.need_major_gc = GPR_FLAG_NONE; + if (objspace->rgengc.need_major_gc) { + reason |= objspace->rgengc.need_major_gc; + do_full_mark = TRUE; + } + else if (RGENGC_FORCE_MAJOR_GC) { + reason = GPR_FLAG_MAJOR_BY_FORCE; + do_full_mark = TRUE; } + objspace->rgengc.need_major_gc = GPR_FLAG_NONE; + if (do_full_mark && (reason & GPR_FLAG_MAJOR_MASK) == 0) { reason |= GPR_FLAG_MAJOR_BY_FORCE; /* GC by CAPI, METHOD, and so on. */ } |