Example #1
0
msgc_context_t *msgc_begin( gc_t *gc )
{
  caddr_t lowest, highest;
  int doublewords;
  msgc_context_t *context;

  context = must_malloc( sizeof( msgc_context_t ) );
  context->gc = gc;

  gclib_memory_range( &lowest, &highest );
  context->lowest_heap_address = (word*)lowest;
  context->highest_heap_address = (word*)highest;
  doublewords = roundup(highest-lowest,(2*sizeof(word)))/(2*sizeof(word));
  context->words_in_bitmap = 
    roundup(doublewords,(8*sizeof(word)))/(8*sizeof(word));
  context->bitmap = 
    gclib_alloc_rts( context->words_in_bitmap * sizeof(word), 0 );

  memset( context->bitmap, 0, context->words_in_bitmap*sizeof(word) );
  context->stack.seg = 0;
  context->stack.stkp = 0;
  context->stack.stkbot = 0;
  context->stack.stklim = 0;
  push_segment( &context->stack );
  context->los_stack.seg = 0;
  context->los_stack.stkp = 0;
  context->los_stack.stkbot = 0;
  context->los_stack.stklim = 0;
  push_segment( &context->los_stack );

  return context;
}
Example #2
0
static remset_t *
create_labelled_remset_with_owner_attrib
  ( int tbl_entries,    /* size of hash table, 0=default */
    int pool_entries,   /* size of remset, 0 = default */
    int major_id,       /* for stats */
    int minor_id,       /* for stats */
    unsigned owner_attrib
    )
{
  word *heapptr;
  remset_t *rs;
  remset_data_t *data;
  pool_t *p;

  assert( tbl_entries >= 0 && (tbl_entries == 0 || ilog2( tbl_entries ) != -1));
  assert( pool_entries >= 0 );

  if (pool_entries == 0) pool_entries = DEFAULT_REMSET_POOLSIZE;
  if (tbl_entries == 0) tbl_entries = DEFAULT_REMSET_TBLSIZE;

  annoyingmsg( "Allocated remembered set\n  hash=%d pool=%d",
	       tbl_entries, pool_entries );

  rs   = (remset_t*)must_malloc( sizeof( remset_t ) );
  data = (remset_data_t*)must_malloc( sizeof( remset_data_t ) );

  while(1) {
    heapptr = gclib_alloc_rts( tbl_entries*sizeof(word), 
			       owner_attrib );
    if (heapptr != 0) break;
    memfail( MF_RTS, "Can't allocate table and SSB for remembered set." );
  }

  /* Hash table */
  data->tbl_bot = heapptr;
  heapptr += tbl_entries;
  data->tbl_lim = heapptr;

  /* Node pool */
  p = allocate_pool_segment( pool_entries, data->mem_attribute ); /* XXX */
  data->first_pool = data->curr_pool = p;
  assert( data->curr_pool != 0 );
  data->numpools = 1;

  /* Misc */
  memset( &data->stats, 0, sizeof( data->stats ));
  data->pool_entries = pool_entries;
  data->self = stats_new_remembered_set( major_id, minor_id );
  data->mem_attribute = owner_attrib;

  rs->live = 0;
  rs->has_overflowed = FALSE;
  rs->data = data;

  rs_clear( rs );

  return rs;
}
Example #3
0
static tnode_t *alloc_tnode( extbmp_t *ebmp, 
                             enum tnode_tag tag, 
                             int length_in_bytes )
{
  tnode_t *retval;

  retval = (tnode_t*)
    /* XXX FIXME use pooled allocation */
    gclib_alloc_rts( length_in_bytes, MB_REMSET );

#if INCLUDE_REDUNDANT_FIELDS
  retval->metadata.tag             = tag;
  retval->metadata.length_in_bytes = length_in_bytes;
#endif

  return retval;
}
Example #4
0
static void push_segment( msgc_stack_t *stack )
{
  msgc_stackseg_t *sp;
  
  if (stack->seg != 0 && stack->seg->next != 0)
    sp = stack->seg->next;
  else {
    sp = gclib_alloc_rts( sizeof(msgc_stackseg_t), 0 );
    sp->prev = stack->seg;
    if (stack->seg != 0) stack->seg->next = sp;
    sp->next = 0;
  }
  
  stack->seg = sp;
  stack->stkbot = stack->seg->data;
  stack->stklim = stack->seg->data+STACKSIZE;
  stack->stkp = stack->stkbot;
}
Example #5
0
msgc_context_t *msgc_begin_range( gc_t *gc, caddr_t lowest, caddr_t highest )
{
  int doublewords;
  msgc_context_t *context;

  context = must_malloc( sizeof( msgc_context_t ) );
  context->gc = gc;

  context->lowest_heap_address = (word*)lowest;
  context->highest_heap_address = (word*)highest;
  doublewords = roundup(highest-lowest,(2*sizeof(word)))/(2*sizeof(word));
  context->words_in_bitmap = 
    roundup(doublewords,(8*sizeof(word)))/(8*sizeof(word));
  context->bitmap = 
    gclib_alloc_rts( context->words_in_bitmap * sizeof(word), 0 );
  context->object_visitor = NULL;
  context->object_visitor_data = NULL;

  context->stop_when = NULL;
  context->stop_when_data = NULL;
  context->signal_stop = FALSE;
  context->stopped_on_obj = 0x0;
  context->stopped_on_src = 0x0;

  memset( context->bitmap, 0, context->words_in_bitmap*sizeof(word) );
  context->stack.seg = 0;
  context->stack.stkp = 0;
  context->stack.stkbot = 0;
  context->stack.stklim = 0;
  push_segment( &context->stack );
  context->los_stack.seg = 0;
  context->los_stack.stkp = 0;
  context->los_stack.stkbot = 0;
  context->los_stack.stklim = 0;
  push_segment( &context->los_stack );

  return context;
}
Example #6
0
void scheme_start( word *globals )
{
  cont_t f = 0;
  word *stkp = (word*)globals[ G_STKP ];
  int x;
  jmp_buf *old_jump_buffer = dispatch_jump_buffer;
  if (already_running)
    annoyingmsg( "Recursive call to scheme_start (FFI?)" );
  already_running = 1;

  dispatch_jump_buffer = gclib_alloc_rts(sizeof(jmp_buf), 0);
  if (dispatch_jump_buffer == NULL)
    panic_abort("Couldn't allocate fresh jmp_buf");

#if 0
  /* Patch in bootstrap code if necessary */
  if (procedure_ref( globals[ G_REG0 ], IDX_PROC_CODE ) == FALSE_CONST)
    procedure_set( globals[ G_REG0 ], IDX_PROC_CODE, (word)twobit_start );
#endif

  /* Return address for bottom-most frame */
  stkp[ STK_RETADDR ] = (word)i386_dispatch_loop_return;
  stkp[ STK_REG0 ] = 0;

  /* The dispatch loop is a doubly-nested quasi-loop.  

     The outer loop uses setjmp/longjmp for control and is entered but 
     rarely; most of the time is spent in the inner loop.  The job of
     the outer loop is to provide the inner loop with the address of
     the first block to execute.

     The inner loop is implemented entirely in compiled code: we just
     jump to the entry point, and any return is done through a longjmp
     to the outer loop.
     */

  /* Outer loop */
  switch (x = setjmp( *dispatch_jump_buffer )) {
  case 0 :
  case DISPATCH_CALL_R0 :
    assert2( tagof( globals[ G_REG0 ]) == PROC_TAG );
    f = procedure_ref( globals[ G_REG0 ], IDX_PROC_CODE );
    f = (cont_t)(ptrof(f)+1); /* skip over bytevector header */
    break;
  case DISPATCH_EXIT:
    already_running = 0;
    gclib_free(dispatch_jump_buffer, sizeof(jmp_buf));
    dispatch_jump_buffer = old_jump_buffer;
    return;
  case DISPATCH_RETURN_FROM_S2S_CALL :
    panic_exit( "DISPATCH_RETURN_FROM_S2S_CALL shouldn't happen." );
    break;
  case DISPATCH_STKUFLOW :
    f = refill_stack_cache( globals );
    globals[ G_STKP ] += 4+4*STK_RETADDR; /* The '4*' compensates for layouts.cfg oversight */
    break;
  case DISPATCH_SIGFPE :
    handle_sigfpe( globals );
    panic_exit( "handle_sigfpe() returned." );
  default :
    panic_exit( "Unexpected value %d from setjmp in scheme_start()", x );
  }

  /* Inner loop */
  i386_scheme_jump(globals,f);   /* Never returns */  
}