From 4867e7bc96bd9b5439c26a1b1f7419863bc1a4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= Date: Tue, 9 Sep 2014 12:44:01 +0200 Subject: [PATCH] VM: try and recover with a kernel error from the callback heap running out --- basis/debugger/debugger.factor | 44 ++++++++++++++++++---------------- core/kernel/kernel.factor | 6 ++++- vm/callbacks.cpp | 8 +++++-- vm/errors.hpp | 1 + 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/basis/debugger/debugger.factor b/basis/debugger/debugger.factor index cc98a168b6..e1c23923a1 100755 --- a/basis/debugger/debugger.factor +++ b/basis/debugger/debugger.factor @@ -148,6 +148,9 @@ HOOK: signal-error. os ( obj -- ) : interrupt-error. ( error -- ) "Interrupt" print drop ; +: callback-space-overflow. ( error -- ) + "Callback space overflow" print drop ; + PREDICATE: vm-error < array dup length 2 < [ drop f ] [ { @@ -158,26 +161,27 @@ PREDICATE: vm-error < array : vm-errors ( error -- n errors ) second { - [ expired-error. ] - [ io-error. ] - [ primitive-error. ] - [ type-check-error. ] - [ divide-by-zero-error. ] - [ signal-error. ] - [ array-size-error. ] - [ fixnum-range-error. ] - [ c-string-error. ] - [ ffi-error. ] - [ undefined-symbol-error. ] - [ datastack-underflow. ] - [ datastack-overflow. ] - [ retainstack-underflow. ] - [ retainstack-overflow. ] - [ callstack-underflow. ] - [ callstack-overflow. ] - [ memory-error. ] - [ fp-trap-error. ] - [ interrupt-error. ] + [ expired-error. ] + [ io-error. ] + [ primitive-error. ] + [ type-check-error. ] + [ divide-by-zero-error. ] + [ signal-error. ] + [ array-size-error. ] + [ fixnum-range-error. ] + [ c-string-error. ] + [ ffi-error. ] + [ undefined-symbol-error. ] + [ datastack-underflow. ] + [ datastack-overflow. ] + [ retainstack-underflow. ] + [ retainstack-overflow. ] + [ callstack-underflow. ] + [ callstack-overflow. ] + [ memory-error. ] + [ fp-trap-error. ] + [ interrupt-error. ] + [ callback-space-overflow. ] } ; inline M: vm-error summary drop "VM error" ; diff --git a/core/kernel/kernel.factor b/core/kernel/kernel.factor index a397331bcf..ddf1fa8fd2 100644 --- a/core/kernel/kernel.factor +++ b/core/kernel/kernel.factor @@ -352,6 +352,8 @@ CONSTANT: OBJ-WAITING-CALLBACKS 73 CONSTANT: OBJ-SIGNAL-PIPE 74 +CONSTANT: OBJ-INSTALL-PREFIX 75 + ! Context object count and identifiers must be kept in sync with: ! vm/contexts.hpp @@ -363,9 +365,10 @@ CONSTANT: CONTEXT-OBJ-CONTEXT 2 CONSTANT: CONTEXT-OBJ-IN-CALLBACK-P 3 ! Runtime errors must be kept in sync with: +! basis/debugger/debugger.factor ! vm/errors.hpp -CONSTANT: kernel-error-count 20 +CONSTANT: kernel-error-count 21 CONSTANT: ERROR-EXPIRED 0 CONSTANT: ERROR-IO 1 @@ -387,5 +390,6 @@ CONSTANT: ERROR-CALLSTACK-OVERFLOW 16 CONSTANT: ERROR-MEMORY 17 CONSTANT: ERROR-FP-TRAP 18 CONSTANT: ERROR-INTERRUPT 19 +CONSTANT: ERROR-CALLBACK-SPACE-OVERFLOW 20 PRIVATE> diff --git a/vm/callbacks.cpp b/vm/callbacks.cpp index 01811f297a..0f7bdfb940 100644 --- a/vm/callbacks.cpp +++ b/vm/callbacks.cpp @@ -61,8 +61,12 @@ code_block* callback_heap::add(cell owner, cell return_rewind) { cell size = array_capacity(insns.untagged()); cell bump = align(size + sizeof(code_block), data_alignment); - if (here + bump > seg->end) - fatal_error("Out of callback space", 0); + + if (here + bump > seg->end) { + parent->general_error(ERROR_CALLBACK_SPACE_OVERFLOW, + false_object, + false_object); + } free_heap_block* free_block = (free_heap_block*)here; free_block->make_free(bump); diff --git a/vm/errors.hpp b/vm/errors.hpp index 8d01571ee0..e580fa1234 100644 --- a/vm/errors.hpp +++ b/vm/errors.hpp @@ -24,6 +24,7 @@ enum vm_error_type { ERROR_MEMORY, ERROR_FP_TRAP, ERROR_INTERRUPT, + ERROR_CALLBACK_SPACE_OVERFLOW }; void fatal_error(const char* msg, cell tagged);