vm: replace assert with FACTOR_ASSERT

Factor is finally a real C++ project and has a custom assert macro. Assertion failures were still getting caught as exceptions and causing failure loops. Write our own macro that calls factor::abort on failure.
db4
Joe Groff 2011-11-17 20:42:30 -08:00
parent 6c0ecf631a
commit 0a1a252cdb
39 changed files with 93 additions and 81 deletions

View File

@ -68,6 +68,7 @@ ifdef CONFIG
vm/words.o
MASTER_HEADERS = $(PLAF_MASTER_HEADERS) \
vm/assert.hpp \
vm/layouts.hpp \
vm/platform.hpp \
vm/primitives.hpp \

View File

@ -8,7 +8,7 @@ namespace factor
inline object *factor_vm::allot_object(cell type, cell size)
{
#ifdef FACTOR_DEBUG
assert(!current_gc);
FACTOR_ASSERT(!current_gc);
#endif
/* If the object is smaller than the nursery, allocate it in the nursery,

View File

@ -4,8 +4,8 @@ namespace factor
inline cell array_nth(array *array, cell slot)
{
#ifdef FACTOR_DEBUG
assert(slot < array_capacity(array));
assert(array->type() == ARRAY_TYPE);
FACTOR_ASSERT(slot < array_capacity(array));
FACTOR_ASSERT(array->type() == ARRAY_TYPE);
#endif
return array->data()[slot];
}
@ -13,8 +13,8 @@ inline cell array_nth(array *array, cell slot)
inline void factor_vm::set_array_nth(array *array, cell slot, cell value)
{
#ifdef FACTOR_DEBUG
assert(slot < array_capacity(array));
assert(array->type() == ARRAY_TYPE);
FACTOR_ASSERT(slot < array_capacity(array));
FACTOR_ASSERT(array->type() == ARRAY_TYPE);
#endif
cell *slot_ptr = &array->data()[slot];
*slot_ptr = value;

16
vm/assert.hpp Normal file
View File

@ -0,0 +1,16 @@
namespace factor
{
void abort();
}
#ifndef NDEBUG
#define FACTOR_ASSERT(condition) ((condition) \
? (void)0 \
: ( \
::fprintf(stderr, "assertion \"%s\" failed: file \"%s\", line %d\n", \
#condition, __FILE__, __LINE__), \
::factor::abort() \
))
#else
#define FACTOR_ASSERT(condition) ((void)0)
#endif

View File

@ -7,7 +7,7 @@ void factor_vm::check_frame(stack_frame *frame)
{
#ifdef FACTOR_DEBUG
check_code_pointer((cell)frame->entry_point);
assert(frame->size != 0);
FACTOR_ASSERT(frame->size != 0);
#endif
}

View File

@ -54,8 +54,8 @@ cell factor_vm::code_block_owner(code_block *compiled)
tagged<quotation> quot(owner.as<quotation>());
tagged<array> elements(quot->array);
#ifdef FACTOR_DEBUG
assert(array_capacity(elements.untagged()) == 5);
assert(array_nth(elements.untagged(),4) == special_objects[PIC_MISS_WORD]
FACTOR_ASSERT(array_capacity(elements.untagged()) == 5);
FACTOR_ASSERT(array_nth(elements.untagged(),4) == special_objects[PIC_MISS_WORD]
|| array_nth(elements.untagged(),4) == special_objects[PIC_MISS_TAIL_WORD]);
#endif
tagged<wrapper> word_wrapper(array_nth(elements.untagged(),0));

View File

@ -38,7 +38,7 @@ struct code_block
{
cell size = header & ~7;
#ifdef FACTOR_DEBUG
assert(size > 0);
FACTOR_ASSERT(size > 0);
#endif
return size;
}
@ -86,12 +86,12 @@ struct code_block
VM_C_API void undefined_symbol(void);
inline code_block *word::code() const {
assert(entry_point != NULL);
FACTOR_ASSERT(entry_point != NULL);
return (code_block*)entry_point - 1;
}
inline code_block *quotation::code() const {
assert(entry_point != NULL);
FACTOR_ASSERT(entry_point != NULL);
return (code_block*)entry_point - 1;
}

View File

@ -60,7 +60,7 @@ void code_heap::clear_mark_bits()
void code_heap::free(code_block *compiled)
{
assert(!uninitialized_p(compiled));
FACTOR_ASSERT(!uninitialized_p(compiled));
points_to_nursery.erase(compiled);
points_to_aging.erase(compiled);
all_blocks.erase(compiled);
@ -76,10 +76,10 @@ code_block *code_heap::code_block_for_address(cell address)
{
std::set<code_block*>::const_iterator blocki =
all_blocks.upper_bound((code_block*)address);
assert(blocki != all_blocks.begin());
FACTOR_ASSERT(blocki != all_blocks.begin());
--blocki;
code_block* found_block = *blocki;
assert((cell)found_block->entry_point() <= address
FACTOR_ASSERT((cell)found_block->entry_point() <= address
&& address - (cell)found_block->entry_point() < found_block->size());
return found_block;
}
@ -265,8 +265,8 @@ struct code_block_accumulator {
if it were a fixnum, and have library code shift it to the
left by 4. */
cell entry_point = (cell)compiled->entry_point();
assert((entry_point & (data_alignment - 1)) == 0);
assert((entry_point & TAG_MASK) == FIXNUM_TYPE);
FACTOR_ASSERT((entry_point & (data_alignment - 1)) == 0);
FACTOR_ASSERT((entry_point & TAG_MASK) == FIXNUM_TYPE);
objects.push_back(entry_point);
}
};

View File

@ -20,7 +20,7 @@ struct code_root {
~code_root()
{
#ifdef FACTOR_DEBUG
assert(parent->code_roots.back() == this);
FACTOR_ASSERT(parent->code_roots.back() == this);
#endif
parent->code_roots.pop_back();
}

View File

@ -110,7 +110,7 @@ void factor_vm::init_contexts(cell datastack_size_, cell retainstack_size_, cell
void factor_vm::delete_contexts()
{
assert(!ctx);
FACTOR_ASSERT(!ctx);
std::list<context *>::const_iterator iter = unused_contexts.begin();
std::list<context *>::const_iterator end = unused_contexts.end();
while(iter != end)

View File

@ -22,9 +22,9 @@ inline static void check_call_site(cell return_address)
{
u32 insn = *(u32 *)return_address;
/* Check that absolute bit is 0 */
assert((insn & 0x2) == 0x0);
FACTOR_ASSERT((insn & 0x2) == 0x0);
/* Check that instruction is branch */
assert((insn >> 26) == 0x12);
FACTOR_ASSERT((insn >> 26) == 0x12);
}
static const u32 b_mask = 0x3fffffc;

View File

@ -51,7 +51,7 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
{
// Make a fake frame for the leaf procedure
code_block *leaf_block = code->code_block_for_address(*pc);
assert(leaf_block != NULL);
FACTOR_ASSERT(leaf_block != NULL);
cell newsp = *sp - 4*sizeof(cell);
*(cell*)(newsp + 3*sizeof(cell)) = 4*sizeof(cell);
@ -61,7 +61,7 @@ void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler)
handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
}
else
assert(false);
FACTOR_ASSERT(false);
*pc = (cell)handler_word->entry_point;
}

View File

@ -1,5 +1,3 @@
#include <assert.h>
namespace factor
{
@ -30,7 +28,7 @@ inline static unsigned char call_site_opcode(cell return_address)
inline static void check_call_site(cell return_address)
{
unsigned char opcode = call_site_opcode(return_address);
assert(opcode == call_opcode || opcode == jmp_opcode);
FACTOR_ASSERT(opcode == call_opcode || opcode == jmp_opcode);
}
inline static void *get_call_target(cell return_address)

View File

@ -43,7 +43,7 @@ data_heap::data_heap(cell young_size_,
nursery = new nursery_space(young_size,aging_semispace->end);
assert(seg->end - nursery->end <= deck_size);
FACTOR_ASSERT(seg->end - nursery->end <= deck_size);
}
data_heap::~data_heap()

View File

@ -45,7 +45,7 @@ struct gc_bignum {
~gc_bignum()
{
#ifdef FACTOR_DEBUG
assert(parent->bignum_roots.back() == (cell)addr);
FACTOR_ASSERT(parent->bignum_roots.back() == (cell)addr);
#endif
parent->bignum_roots.pop_back();
}

View File

@ -586,7 +586,7 @@ void factor_vm::factorbug()
{
exit_fep(this);
general_error(ERROR_INTERRUPT,false_object,false_object);
assert(false);
FACTOR_ASSERT(false);
}
else if(strcmp(cmd,"data") == 0)
dump_objects(TYPE_COUNT);

View File

@ -17,7 +17,7 @@ struct free_heap_block
{
cell size = header & ~7;
#ifdef FACTOR_DEBUG
assert(size > 0);
FACTOR_ASSERT(size > 0);
#endif
return size;
}
@ -25,7 +25,7 @@ struct free_heap_block
void make_free(cell size)
{
#ifdef FACTOR_DEBUG
assert(size > 0);
FACTOR_ASSERT(size > 0);
#endif
header = size | 1;
}

View File

@ -140,7 +140,7 @@ void free_list_allocator<Block>::sweep()
{
/* find size */
cell size = state.unmarked_block_size(start);
assert(size > 0);
FACTOR_ASSERT(size > 0);
free_heap_block *free_block = (free_heap_block *)start;
free_block->make_free(size);

View File

@ -145,14 +145,14 @@ void factor_vm::set_current_gc_op(gc_op op)
void factor_vm::gc(gc_op op, cell requested_size, bool trace_contexts_p)
{
assert(!gc_off);
assert(!current_gc);
FACTOR_ASSERT(!gc_off);
FACTOR_ASSERT(!current_gc);
/* Important invariant: tenured space must have enough contiguous free
space to fit the entire contents of the aging space and nursery. This is
because when doing a full collection, objects from younger generations
are promoted before any unreachable tenured objects are freed. */
assert(!data->high_fragmentation_p());
FACTOR_ASSERT(!data->high_fragmentation_p());
current_gc = new gc_state(op,this);
atomic::store(&current_gc_p, true);
@ -223,7 +223,7 @@ void factor_vm::gc(gc_op op, cell requested_size, bool trace_contexts_p)
current_gc = NULL;
/* Check the invariant again, just in case. */
assert(!data->high_fragmentation_p());
FACTOR_ASSERT(!data->high_fragmentation_p());
}
/* primitive_minor_gc() is invoked by inline GC checks, and it needs to fill in
@ -246,7 +246,7 @@ struct call_frame_scrubber {
code_block *compiled = parent->frame_code(frame);
gc_info *info = compiled->block_gc_info();
assert(return_address < compiled->size());
FACTOR_ASSERT(return_address < compiled->size());
cell index = info->return_address_index(return_address);
if(index != (cell)-1)
ctx->scrub_stacks(info,index);

View File

@ -4,7 +4,7 @@ namespace factor
template<typename Array> cell array_capacity(const Array *array)
{
#ifdef FACTOR_DEBUG
assert(array->type() == Array::type_number);
FACTOR_ASSERT(array->type() == Array::type_number);
#endif
return array->capacity >> TAG_BITS;
}

View File

@ -22,13 +22,13 @@ jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
parent(vm)
{
fixnum old_count = atomic::fetch_add(&parent->current_jit_count, 1);
assert(old_count >= 0);
FACTOR_ASSERT(old_count >= 0);
}
jit::~jit()
{
fixnum old_count = atomic::fetch_subtract(&parent->current_jit_count, 1);
assert(old_count >= 1);
FACTOR_ASSERT(old_count >= 1);
}
void jit::emit_relocation(cell relocation_template_)

View File

@ -89,7 +89,7 @@ static inline const char *type_name(cell type)
case DLL_TYPE:
return "dll";
default:
assert(false);
FACTOR_ASSERT(false);
return "";
}
}
@ -123,7 +123,7 @@ inline static bool immediate_p(cell obj)
inline static fixnum untag_fixnum(cell tagged)
{
#ifdef FACTOR_DEBUG
assert(TAG(tagged) == FIXNUM_TYPE);
FACTOR_ASSERT(TAG(tagged) == FIXNUM_TYPE);
#endif
return ((fixnum)tagged) >> TAG_BITS;
}

View File

@ -62,7 +62,7 @@ void factor_vm::call_fault_handler(
handler = (cell)factor::synchronous_signal_handler_impl;
}
assert(handler != 0);
FACTOR_ASSERT(handler != 0);
dispatch_signal_handler(
(cell*)&MACH_STACK_POINTER(thread_state),
@ -81,7 +81,7 @@ static void call_fault_handler(
{
/* Look up the VM instance involved */
THREADHANDLE thread_id = pthread_from_mach_thread_np(thread);
assert(thread_id);
FACTOR_ASSERT(thread_id);
std::map<THREADHANDLE, factor_vm*>::const_iterator vm = thread_vms.find(thread_id);
/* Handle the exception */
@ -211,6 +211,7 @@ mach_exception_thread (void *arg)
abort ();
}
}
return NULL; // quiet warning
}
/* Initialize the Mach exception handler thread. */

View File

@ -82,7 +82,7 @@ template<typename Block> struct mark_bits {
else
{
#ifdef FACTOR_DEBUG
assert(start.first < bits_size);
FACTOR_ASSERT(start.first < bits_size);
#endif
bits[start.first] |= ~start_mask;
@ -92,7 +92,7 @@ template<typename Block> struct mark_bits {
if(end_mask != 0)
{
#ifdef FACTOR_DEBUG
assert(end.first < bits_size);
FACTOR_ASSERT(end.first < bits_size);
#endif
bits[end.first] |= end_mask;
}
@ -126,7 +126,7 @@ template<typename Block> struct mark_bits {
Block *forward_block(const Block *original)
{
#ifdef FACTOR_DEBUG
assert(marked_p(original));
FACTOR_ASSERT(marked_p(original));
#endif
std::pair<cell,cell> position = bitmap_deref(original);
@ -136,7 +136,7 @@ template<typename Block> struct mark_bits {
cell new_line_number = approx_popcount + popcount(marked[position.first] & mask);
Block *new_block = line_block(new_line_number);
#ifdef FACTOR_DEBUG
assert(new_block <= original);
FACTOR_ASSERT(new_block <= original);
#endif
return new_block;
}

View File

@ -13,10 +13,6 @@
#include <errno.h>
#endif
#ifdef FACTOR_DEBUG
#include <assert.h>
#endif
/* C headers */
#include <fcntl.h>
#include <limits.h>
@ -26,7 +22,6 @@
#include <string.h>
#include <time.h>
#include <wchar.h>
#include <assert.h>
/* C++ headers */
#include <algorithm>
@ -88,6 +83,7 @@ namespace factor
}
/* Factor headers */
#include "assert.hpp"
#include "layouts.hpp"
#include "platform.hpp"
#include "primitives.hpp"

View File

@ -12,7 +12,7 @@ void init_mvm()
void register_vm_with_thread(factor_vm *vm)
{
assert(!global_vm);
FACTOR_ASSERT(!global_vm);
global_vm = vm;
}

View File

@ -8,7 +8,7 @@ factor_vm *current_vm_p();
inline factor_vm *current_vm()
{
factor_vm *vm = current_vm_p();
assert(vm != NULL);
FACTOR_ASSERT(vm != NULL);
return vm;
}

View File

@ -33,7 +33,7 @@ cell object_start_map::find_object_containing_card(cell card_index)
{
#ifdef FACTOR_DEBUG
/* First card should start with an object */
assert(card_index > 0);
FACTOR_ASSERT(card_index > 0);
#endif
card_index--;
}

View File

@ -493,7 +493,7 @@ void *stdin_loop(void *arg)
void factor_vm::open_console()
{
assert(!stdin_thread_initialized_p);
FACTOR_ASSERT(!stdin_thread_initialized_p);
safe_pipe(&control_read,&control_write);
safe_pipe(&size_read,&size_write);
safe_pipe(&stdin_read,&stdin_write);
@ -513,7 +513,7 @@ void factor_vm::close_console()
void factor_vm::lock_console()
{
assert(stdin_thread_initialized_p);
FACTOR_ASSERT(stdin_thread_initialized_p);
/* Lock the stdin_mutex and send the stdin_loop thread a signal to interrupt
any read() it has in progress. When the stdin loop iterates again, it will
try to lock the same mutex and wait until unlock_console() is called. */
@ -523,7 +523,7 @@ void factor_vm::lock_console()
void factor_vm::unlock_console()
{
assert(stdin_thread_initialized_p);
FACTOR_ASSERT(stdin_thread_initialized_p);
pthread_mutex_unlock(&stdin_mutex);
}
@ -544,7 +544,7 @@ void factor_vm::handle_ctrl_c()
sigaction_safe(SIGINT,&fep_sigaction,NULL);
}
void factor_vm::abort()
void abort()
{
sig_t ret;
do
@ -553,7 +553,7 @@ void factor_vm::abort()
}
while(ret == SIG_ERR && errno == EINTR);
close_console();
factor_vm::close_console();
::abort();
}

View File

@ -294,7 +294,7 @@ static BOOL WINAPI ctrl_handler(DWORD dwCtrlType)
Since in practice nobody uses the multi-VM stuff yet, we just grab the first
VM we can get. This will not be a good idea when we actually support native
threads. */
assert(thread_vms.size() == 1);
FACTOR_ASSERT(thread_vms.size() == 1);
factor_vm *vm = thread_vms.begin()->second;
vm->safepoint.enqueue_fep(vm);
return TRUE;
@ -337,17 +337,17 @@ void factor_vm::sampler_thread_loop()
DWORD ok;
ok = QueryPerformanceFrequency(&units_per_second);
assert(ok);
FACTOR_ASSERT(ok);
ok = QueryPerformanceCounter(&counter);
assert(ok);
FACTOR_ASSERT(ok);
counter.QuadPart *= samples_per_second;
while (atomic::load(&sampling_profiler_p))
{
SwitchToThread();
ok = QueryPerformanceCounter(&new_counter);
assert(ok);
FACTOR_ASSERT(ok);
new_counter.QuadPart *= samples_per_second;
cell samples = 0;
while (new_counter.QuadPart - counter.QuadPart > units_per_second.QuadPart)
@ -359,16 +359,16 @@ void factor_vm::sampler_thread_loop()
if (samples > 0)
{
DWORD suscount = SuspendThread(thread);
assert(suscount == 0);
FACTOR_ASSERT(suscount == 0);
CONTEXT context;
memset((void*)&context, 0, sizeof(CONTEXT));
context.ContextFlags = CONTEXT_CONTROL;
BOOL context_ok = GetThreadContext(thread, &context);
assert(context_ok);
FACTOR_ASSERT(context_ok);
suscount = ResumeThread(thread);
assert(suscount == 1);
FACTOR_ASSERT(suscount == 1);
safepoint.enqueue_samples(this, samples, context.EIP, false);
}
@ -403,7 +403,7 @@ void factor_vm::end_sampling_profiler_timer()
sampler_thread = NULL;
}
void factor_vm::abort()
void abort()
{
::abort();
}

View File

@ -82,7 +82,7 @@ inline static THREADHANDLE thread_id()
FALSE,
id
);
assert(threadHandle != NULL);
FACTOR_ASSERT(threadHandle != NULL);
return threadHandle;
}

View File

@ -392,7 +392,7 @@ cell factor_vm::lazy_jit_compile(cell quot_)
{
data_root<quotation> quot(quot_,this);
assert(!quot_compiled_p(quot.untagged()));
FACTOR_ASSERT(!quot_compiled_p(quot.untagged()));
code_block *compiled = jit_compile_quot(quot.value(),quot.value(),true);
quot.untagged()->entry_point = compiled->entry_point();

View File

@ -8,9 +8,9 @@ void factor_vm::primitive_exit()
exit((int)to_fixnum(ctx->pop()));
}
void factor_vm::exit(int status)
void exit(int status)
{
close_console();
factor_vm::close_console();
::exit(status);
}

View File

@ -1,4 +1,7 @@
namespace factor
{
void abort();
void exit(int status);
}

View File

@ -50,7 +50,7 @@ void safepoint_state::handle_safepoint(factor_vm *parent, cell pc) volatile
}
else if (atomic::load(&parent->sampling_profiler_p))
{
assert(parent->code->seg->in_segment_p(pc));
FACTOR_ASSERT(parent->code->seg->in_segment_p(pc));
code_block *block = parent->code->code_block_for_address(pc);
bool prolog_p = (cell)block->entry_point() == pc;

View File

@ -55,7 +55,7 @@ void factor_vm::record_callstack_sample(cell *begin, cell *end, bool prolog_p)
stack_frame *frame = ctx->bottom_frame();
if (prolog_p)
{
assert(frame >= ctx->callstack_top);
FACTOR_ASSERT(frame >= ctx->callstack_top);
stack_frame *next_frame = frame_successor(frame);
while (next_frame >= ctx->callstack_top)
{

View File

@ -317,7 +317,7 @@ struct call_frame_slot_visitor {
code_block *compiled = visitor->fixup.translate_code(parent->frame_code(frame));
gc_info *info = compiled->block_gc_info();
assert(return_address < compiled->size());
FACTOR_ASSERT(return_address < compiled->size());
cell callsite = info->return_address_index(return_address);
if(callsite == (cell)-1)
return;

View File

@ -37,7 +37,7 @@ struct tagged
cell value() const
{
#ifdef FACTOR_DEBUG
assert(type_p());
FACTOR_ASSERT(type_p());
#endif
return value_;
}
@ -45,7 +45,7 @@ struct tagged
Type *untagged() const
{
#ifdef FACTOR_DEBUG
assert(type_p());
FACTOR_ASSERT(type_p());
#endif
return (Type *)(UNTAG(value_));
}

View File

@ -190,7 +190,6 @@ struct factor_vm
void primitive_nano_count();
void primitive_sleep();
void primitive_set_slot();
static void exit(int status);
// objects
void primitive_special_object();
@ -380,7 +379,7 @@ struct factor_vm
{
#ifdef FACTOR_DEBUG
if(!(current_gc && current_gc->op == collect_growing_heap_op))
assert(data->seg->in_segment_p((cell)pointer));
FACTOR_ASSERT(data->seg->in_segment_p((cell)pointer));
#endif
}
@ -739,8 +738,6 @@ struct factor_vm
static void unlock_console();
static void ignore_ctrl_c();
static void handle_ctrl_c();
static void abort();
static void exit();
// os-windows
#if defined(WINDOWS)