Exemple #1
0
Task*   import_heap_image__may_heapclean   (const char* fname, Heapcleaner_Args* params,  Roots* extra_roots) {
    //  ================================
    //
    // This fn is called (only) by   load_and_run_heap_image__may_heapclean   in   src/c/main/load-and-run-heap-image.c
    //
    Task*		task;
    Heapfile_Header	image_header;
    Heap_Header	heap_header;
    Val		*externs;
    Pthread_Image	image;
    Inbuf		inbuf;

    if (fname != NULL) {
	//
        // Resolve the name of the image.
        //  If the file exists use it, otherwise try the
        // pathname with the machine ID as an extension.

	if ((inbuf.file = fopen(fname, "rb"))) {
	    //
	    if (verbosity__global > 0)   say("loading %s ", fname);

	} else {
	    //
	    if ((inbuf.file = fopen(fname, "rb"))) {
		//
	        if (verbosity__global > 0)   say("loading %s ", fname);

	    } else {

		die ("unable to open heap image \"%s\"\n", fname);
	    }
	}

	inbuf.needs_to_be_byteswapped = FALSE;
	inbuf.buf	    = NULL;
	inbuf.nbytes    = 0;

    } else {
	//
	// fname == NULL, so try to find
	// an in-core heap image:

  	#if defined(DLOPEN) && !defined(OPSYS_WIN32)
	    //
	    void *lib = dlopen (NULL, RTLD_LAZY);
	    void *vimg, *vimglenptr;

	    if ((vimg       = dlsym(lib,HEAP_IMAGE_SYMBOL    )) == NULL)      die("no in-core heap image found\n");
	    if ((vimglenptr = dlsym(lib,HEAP_IMAGE_LEN_SYMBOL)) == NULL)      die("unable to find length of in-core heap image\n");

	    inbuf.file      = NULL;
	    inbuf.needs_to_be_byteswapped = FALSE;

	    inbuf.base      = vimg;
	    inbuf.buf       = inbuf.base;
	    inbuf.nbytes    = *(long*)vimglenptr;
        #else
	    die("in-core heap images not implemented\n");
        #endif
    }

    READ(&inbuf, image_header);

    if (image_header.byte_order != ORDER)						die ("incorrect byte order in heap image\n");
    if (image_header.magic != IMAGE_MAGIC)						die ("bad magic number (%#x) in heap image\n", image_header.magic);
    if ((image_header.kind != EXPORT_HEAP_IMAGE) && (image_header.kind != EXPORT_FN_IMAGE))	die ("bad image kind (%d) in heap image\n", image_header.kind);

    READ(&inbuf, heap_header);

    // Check for command-line overrides of heap parameters:
    //
    if (params->agegroup0_buffer_bytesize == 0) {
        params->agegroup0_buffer_bytesize = heap_header.agegroup0_buffer_bytesize;
    }
    if (params->active_agegroups < heap_header.active_agegroups) {
        params->active_agegroups = heap_header.active_agegroups;
    }
    if (params->oldest_agegroup_retaining_fromspace_sibs_between_heapcleanings < 0) {
        params->oldest_agegroup_retaining_fromspace_sibs_between_heapcleanings = heap_header.oldest_agegroup_retaining_fromspace_sibs_between_heapcleanings;
    } 

    task = make_task( /*is_boot:*/FALSE, params );					// make_task		def in   src/c/main/runtime-state.c

    // Get the run-time pointers into the heap:
    //
    *PTR_CAST( Val*, PERVASIVE_PACKAGE_PICKLE_LIST_REFCELL__GLOBAL )
        =
        heap_header.pervasive_package_pickle_list;

    // This carefully constructed fake looks like a normal
    // compiled package from the Mythryl side but actually
    // links to compile C code -- see the hack in
    //	
    //     src/c/main/load-compiledfiles.c
    //
    runtime_package__global =  heap_header.runtime_pseudopackage;

    #ifdef ASM_MATH
	mathvec__global = heap_header.math_package;
    #endif


    externs = heapio__read_externs_table (&inbuf);				// Read the externals table.

    READ(&inbuf, image);							// Read and initialize the Mythryl state info.
    //
    if (image_header.kind == EXPORT_HEAP_IMAGE) {

        // Load the live registers:
        //
	ASSIGN( POSIX_INTERPROCESS_SIGNAL_HANDLER_REFCELL__GLOBAL,
                image.posix_interprocess_signal_handler
              );
	//
	task->argument		= image.stdArg;
	task->fate		= image.stdCont;
	task->current_closure	= image.stdClos;
	task->program_counter	= image.pc;
	task->exception_fate	= image.exception_fate;
	task->current_thread	= image.current_thread;
	//
	task->callee_saved_registers[0]	= image.calleeSave[0];
	task->callee_saved_registers[1]	= image.calleeSave[1];
	task->callee_saved_registers[2]	= image.calleeSave[2];

	read_heap (&inbuf, &heap_header, task, externs);			// Read the Mythryl heap.

	/* heapcleaner_messages_are_enabled__global = TRUE; */			// Heapcleaning messages are on by default for interactive images.

    } else { 									// EXPORT_FN_IMAGE

        // Restore the signal handler:
        //
	ASSIGN( POSIX_INTERPROCESS_SIGNAL_HANDLER_REFCELL__GLOBAL, image.posix_interprocess_signal_handler );

        // Read the Mythryl heap:
        //
	task->argument		= image.stdArg;
	read_heap (&inbuf, &heap_header, task, externs);

        // Initialize the calling context (taken from run_mythryl_function__may_heapclean):			// run_mythryl_function__may_heapclean	def in   src/c/main/run-mythryl-code-and-runtime-eventloop.c
        //
	Val function_to_run	= task->argument;
	//
	task->exception_fate	= PTR_CAST( Val,  handle_uncaught_exception_closure_v + 1 );
	task->current_thread	= HEAP_VOID;
	//
	task->fate		= PTR_CAST( Val,  return_to_c_level_c );
	task->current_closure	= function_to_run;
	//
	task->program_counter	=
	task->link_register	= GET_CODE_ADDRESS_FROM_CLOSURE( function_to_run );				// Last use of 'function_to_run'.

        // Set up the arguments to the imported function:
        //
	Val program_name =  make_ascii_string_from_c_string__may_heapclean(task, mythryl_program_name__global, extra_roots);		Roots roots1 = { &program_name, extra_roots };
        //
	Val args         =  make_ascii_strings_from_vector_of_c_strings__may_heapclean (task, commandline_args_without_argv0_or_runtime_args__global, &roots1 );

	task->argument = make_two_slot_record( task, program_name, args );

	// debug_say("arg = %#x : [%#x, %#x]\n", task->argument, GET_TUPLE_SLOT_AS_VAL(task->argument, 0), GET_TUPLE_SLOT_AS_VAL(task->argument, 1));

        // Heapcleaner messages are off by
        // default for spawn_to_disk images:
        //
	heapcleaner_messages_are_enabled__global =  FALSE;
    }

    FREE( externs );

    if (inbuf.file)   fclose (inbuf.file);

    if (verbosity__global > 0)   say(" done\n");

    return task;
}								// fun import_heap_image__may_heapclean
Exemple #2
0
/* ImportHeapImage:
 */
lib7_state_t *ImportHeapImage (const char *fname, heap_params_t *params)
{
    lib7_state_t		*lib7_state;
    lib7_image_hdr_t	imHdr;
    lib7_heap_hdr_t	heapHdr;
    lib7_val_t		*externs;
    lib7_vproc_image_t	image;
    inbuf_t		inBuf;

    if (fname != NULL) {
      /* Resolve the name of the image.
       *  If the file exists use it, otherwise try the
       * pathname with the machine ID as an extension.
       */
      if ((inBuf.file = fopen(fname, "rb"))) {

	if (verbosity > 0)   say("loading %s ", fname);

      } else {

	if ((inBuf.file = fopen(fname, "rb"))) {

	  if (verbosity > 0)   say("loading %s ", fname);

	} else {
	    Die ("unable to open heap image \"%s\"\n", fname);
        }
      }

      inBuf.needsSwap = FALSE;
      inBuf.buf	    = NULL;
      inBuf.nbytes    = 0;
    } else {
      /* fname == NULL, so try to find an in-core heap image */
#if defined(DLOPEN) && !defined(OPSYS_WIN32)
      void *lib = dlopen (NULL, RTLD_LAZY);
      void *vimg, *vimglenptr;
      if ((vimg = dlsym(lib,HEAP_IMAGE_SYMBOL)) == NULL)
	Die("no in-core heap image found\n");
      if ((vimglenptr = dlsym(lib,HEAP_IMAGE_LEN_SYMBOL)) == NULL)
	Die("unable to find length of in-core heap image\n");

      inBuf.file = NULL;
      inBuf.needsSwap = FALSE;
      inBuf.base = vimg;
      inBuf.buf = inBuf.base;
      inBuf.nbytes = *(long*)vimglenptr;
#else
      Die("in-core heap images not implemented\n");
#endif
    }

    READ(&inBuf, imHdr);
    if (imHdr.byteOrder != ORDER)
	Die ("incorrect byte order in heap image\n");
    if (imHdr.magic != IMAGE_MAGIC)
	Die ("bad magic number (%#x) in heap image\n", imHdr.magic);
    if ((imHdr.kind != EXPORT_HEAP_IMAGE) && (imHdr.kind != EXPORT_FN_IMAGE))
	Die ("bad image kind (%d) in heap image\n", imHdr.kind);
    READ(&inBuf, heapHdr);

    /* Check for command-line overrides of heap parameters: */
    if (params->allocSz == 0) params->allocSz = heapHdr.allocSzB;
    if (params->numGens < heapHdr.numGens) params->numGens = heapHdr.numGens;
    if (params->cacheGen < 0) params->cacheGen = heapHdr.cacheGen;

    lib7_state = AllocLib7state (FALSE, params);

    /* Get the run-time pointers into the heap: */
    *PTR_LIB7toC(lib7_val_t, PervasiveStruct) = heapHdr.pervasiveStruct;
    runtimeCompileUnit = heapHdr.runtimeCompileUnit;
#ifdef ASM_MATH
    MathVec = heapHdr.mathVec;
#endif

    /* Read the externals table: */
    externs = HeapIO_ReadExterns (&inBuf);

    /* Read and initialize the Lib7 state info: */
    READ(&inBuf, image);
    if (imHdr.kind == EXPORT_HEAP_IMAGE) {
      /* Load the live registers */
	ASSIGN(Lib7SignalHandler, image.sigHandler);
	lib7_state->lib7_argument	= image.stdArg;
	lib7_state->lib7_fate		= image.stdCont;
	lib7_state->lib7_closure	= image.stdClos;
	lib7_state->lib7_program_counter= image.pc;
	lib7_state->lib7_exception_fate	= image.exception_fate;
	lib7_state->lib7_current_thread	= image.current_thread;
	lib7_state->lib7_calleeSave[0]	= image.calleeSave[0];
	lib7_state->lib7_calleeSave[1]	= image.calleeSave[1];
	lib7_state->lib7_calleeSave[2]	= image.calleeSave[2];
        /* Read the Lib7 heap */
	read_heap (&inBuf, &heapHdr, lib7_state, externs);
      /* GC message are on by default for interactive images */
      /* GCMessages = TRUE; */
    }
    else {  /* EXPORT_FN_IMAGE */

	lib7_val_t	funct, cmdName, args;

        /* Restore the signal handler: */
	ASSIGN(Lib7SignalHandler, image.sigHandler);

        /* Read the Lib7 heap: */
	lib7_state->lib7_argument		= image.stdArg;
	read_heap (&inBuf, &heapHdr, lib7_state, externs);

        /* Initialize the calling context (taken from ApplyLib7Fn) */
	funct				= lib7_state->lib7_argument;
	lib7_state->lib7_exception_fate	= PTR_CtoLib7(handle_v+1);
	lib7_state->lib7_current_thread	= LIB7_void;
	lib7_state->lib7_fate		= PTR_CtoLib7(return_c);
	lib7_state->lib7_closure	= funct;
	lib7_state->lib7_program_counter=
	lib7_state->lib7_link_register	= GET_CODE_ADDR(funct);

        /* Set up the arguments to the imported function */
	cmdName = LIB7_CString(lib7_state, Lib7CommandName);
	args = LIB7_CStringList (lib7_state, commandline_arguments);
	REC_ALLOC2(lib7_state, lib7_state->lib7_argument, cmdName, args);
/*
SayDebug("arg = %#x : [%#x, %#x]\n", lib7_state->lib7_argument, REC_SEL(lib7_state->lib7_argument, 0), REC_SEL(lib7_state->lib7_argument, 1));
*/
        /* GC message are off by default for spawn_to_disk images */
	GCMessages = FALSE;
    }

    FREE (externs);

    if (inBuf.file)   fclose (inBuf.file);

    if (verbosity > 0)   say(" done\n");

    return lib7_state;
}                                /* ImportHeapImage */