Skip to content

Commit 6258cfa

Browse files
committed
Call rb_memerror when OOM
1 parent 629ecd6 commit 6258cfa

3 files changed

Lines changed: 34 additions & 0 deletions

File tree

gc/mmtk/mmtk.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,11 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
909909
VALUE *alloc_obj = (VALUE *)rb_mmtk_alloc_fast_path(objspace, ractor_cache, alloc_size, MMTk_MIN_OBJ_ALIGN);
910910
if (!alloc_obj) {
911911
alloc_obj = mmtk_alloc(ractor_cache->mutator, alloc_size, MMTk_MIN_OBJ_ALIGN, 0, MMTK_ALLOCATION_SEMANTICS_DEFAULT);
912+
913+
// On heap exhaustion raise NoMemoryError.
914+
if (RB_UNLIKELY(alloc_obj == NULL)) {
915+
rb_memerror();
916+
}
912917
}
913918

914919
alloc_obj++;

gc/mmtk/src/collection.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::upcalls;
99
use crate::Ruby;
1010
use mmtk::memory_manager;
1111
use mmtk::scheduler::*;
12+
use mmtk::util::alloc::AllocationError;
1213
use mmtk::util::heap::GCTriggerPolicy;
1314
use mmtk::util::VMMutatorThread;
1415
use mmtk::util::VMThread;
@@ -63,6 +64,19 @@ impl Collection<Ruby> for VMCollection {
6364
(upcalls().block_for_gc)(tls);
6465
}
6566

67+
fn out_of_memory(_tls: VMThread, err_kind: AllocationError) {
68+
match err_kind {
69+
// The heap is exhausted and could not be grown. Return normally
70+
// without aborting.
71+
AllocationError::HeapOutOfMemory => {}
72+
// The OS refused an mmap. This is unrecoverable, so abort the
73+
// process via the same panic handler used for GC-thread panics.
74+
AllocationError::MmapOutOfMemory => {
75+
(upcalls().mutator_thread_panic_handler)();
76+
}
77+
}
78+
}
79+
6680
fn spawn_gc_thread(_tls: VMThread, ctx: GCThreadContext<Ruby>) {
6781
let join_handle = match ctx {
6882
GCThreadContext::Worker(mut worker) => thread::Builder::new()

test/mmtk/test_oom.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "helper"
4+
5+
module MMTk
6+
class TestOOM < TestCase
7+
def test_oom
8+
assert_in_out_err([{ "MMTK_HEAP_MAX" => "64MiB" }], <<~RUBY, [], ["[FATAL] failed to allocate memory"])
9+
10_000_000.times.map do
10+
Object.new
11+
end
12+
RUBY
13+
end
14+
end
15+
end

0 commit comments

Comments
 (0)