コード例 #1
0
ファイル: gc.c プロジェクト: wlbksy/julia
static void gc_mark(void)
{
    // mark all roots

    // active tasks
    gc_push_root(jl_root_task);
    gc_push_root(jl_current_task);

    // modules
    gc_push_root(jl_main_module);
    gc_push_root(jl_current_module);

    // invisible builtin values
    if (jl_an_empty_cell) gc_push_root(jl_an_empty_cell);
    gc_push_root(jl_exception_in_transit);
    gc_push_root(jl_task_arg_in_transit);
    gc_push_root(jl_unprotect_stack_func);
    gc_push_root(jl_bottom_func);
    gc_push_root(jl_typetype_type);
    gc_push_root(jl_tupletype_type);

    // constants
    gc_push_root(jl_null);
    gc_push_root(jl_true);
    gc_push_root(jl_false);

    // libuv loops
    gc_mark_uv_state(jl_global_event_loop());

    jl_mark_box_caches();

    size_t i;

    // stuff randomly preserved
    for(i=0; i < preserved_values.len; i++) {
        gc_push_root((jl_value_t*)preserved_values.items[i]);
    }

    // objects currently being finalized
    for(i=0; i < to_finalize.len; i++) {
        gc_push_root(to_finalize.items[i]);
    }

    gc_mark_all();

    // find unmarked objects that need to be finalized.
    // this must happen last.
    for(i=0; i < finalizer_table.size; i+=2) {
        if (finalizer_table.table[i+1] != HT_NOTFOUND) {
            jl_value_t *v = finalizer_table.table[i];
            if (!gc_marked(v)) {
                gc_push_root(v);
                schedule_finalization(v);
            }
            gc_push_root(finalizer_table.table[i+1]);
        }
    }

    gc_mark_all();
}
コード例 #2
0
ats_void_type gc_collect () {
  int overflow, nchunk, nmarkstackpage ;
  jmp_buf reg_save ; // register contents are roots
#ifdef _ATS_MULTITHREAD
  threadinfolst infolst ; int nother ;
#endif
/*
  fprintf(
    stderr
  , "GC begs: the_chunk_count = %i and the_chunk_count_limit = %i\n"
  , the_chunk_count
  , the_chunk_count_limit
  ) ;
*/
  setjmp (reg_save) ; // push registers onto the stack
  asm volatile ("": : :"memory") ; // stop potential optimization

  nmarkstackpage = (the_chunk_count << CHUNK_WORDSIZE_LOG) ;
  nmarkstackpage /= (MARKSTACK_PAGESIZE * NCHUNK_PER_MARKSTACKPAGE) ;
  nmarkstackpage += 1 ; nmarkstackpage -= the_markstackpagecnt ;
/*
  fprintf (stderr, "gc_collect: nmarkstackpage = %i\n", nmarkstackpage) ;
*/
  the_markstack_extend (nmarkstackpage) ;

#ifdef _ATS_MULTITHREAD
  // put all of the other threads into sleep
  infolst = the_threadinfolst_fst ; nother = 0 ;
  while (infolst) {
    if (infolst != the_threadinfolst_self) {
      fprintf (stderr, "gc_collect: SIGUSR1: infolst->pid = %i\n", (int)(infolst->pid)) ;
      pthread_kill (infolst->pid, SIGUSR1) ; nother += 1 ;
    }
    infolst = infolst->next ;
  }
  while (nother) { // ordering is irrelevant
    fprintf (stderr, "gc_collect: sem_wait: bef: nother = %i\n", nother) ;
    sem_wait (&the_sleep_semaphore) ; nother -= 1 ;
    fprintf (stderr, "gc_collect: sem_wait: aft: nother = %i\n", nother) ;
  }
  fprintf (stderr, "gc_collect: nother = %i\n", nother) ;
#endif // end of [_ATS_MULTITHREAD]

  gc_markbits_clear_the_topsegtbl () ; // clear all mark bits
/*
  fprintf (
    stderr, "gc_collect: gc_markbits_clear_topsegtbl: done\n", nmarkstackpage
  ) ; // end of [fprintf]
*/

  overflow = gc_mark_all () ; // marking phase
/*
  fprintf (stderr, "gc_collect: gc_mark_all: done\n") ;
*/

#ifdef _ATS_MULTITHREAD
  // wake up all of the sleeping threads
  infolst = the_threadinfolst_fst ;
  while (infolst) {
    if (infolst != the_threadinfolst_self) {
      fprintf (stderr, "gc_collect: SIGUSR2: infolst->pid = %i\n", (int)(infolst->pid)) ;
      pthread_kill (infolst->pid, SIGUSR2) ;
    }
    infolst = infolst->next ;
  }
#endif // end of [_ATS_MULTITHREAD]

  the_freeitmlst_array_mark_unset () ; /* is this really needed? */
  // [gc_mark_threadinfolst_one] is not called on [the_threadinfolst_self]
  // Therefore [the_freeitmlst_array_clear_all] must be called!
  the_freeitmlst_array_clear_all () ; /* clear the freeitmlst array */
  gc_sweeplst_build_the_topsegtbl () ; // sweep chunks into [the_sweeplst_array]

  if (overflow > 0) {
/*
    fprintf (stderr, "gc_collect: markstack overflow happend.\n") ;
*/
    the_markstack_extend (MARKSTACK_EXTEND_INCREMENT) ;
  }
/*
  fprintf(
    stderr
  , "GC ends: the_chunk_count = %i and the_chunk_count_limit = %i\n"
  , the_chunk_count
  , the_chunk_count_limit
  ) ;
*/
  if (the_chunk_count_limit_max >= 0) {
    // [the_chunk_count_limit_max] is finite
    if (the_chunk_count_limit >= the_chunk_count_limit_max) {
      // fprintf(stderr, "GC: the_chunk_count_limit = %i\n", the_chunk_count_limit) ;
      // fprintf(stderr, "GC: the_chunk_count_limit_max = %i\n", the_chunk_count_limit_max) ;
      fprintf(stderr, "GC: Warning: the maximal chunk count limit is reached!\n") ;
      return ;
    }
  } /* end of [if] */

  if (the_chunk_count >= the_chunk_count_limit * CHUNK_LIMIT_EXTEND_CUTOFF)
    the_chunk_count_limit *= 2 ;
/*
  fprintf(
    stderr
  , "GC ends: update: the_chunk_count_limit = %i\n", the_chunk_count_limit
  ) ;
*/
  return ;

} /* end of [gc_collect] */