Split data out into separate vm-data struct

db4
Phil Dawes 2009-09-03 20:32:39 +01:00
parent b07550620f
commit e8d1612e8e
7 changed files with 1687 additions and 1407 deletions

View File

@ -1,36 +1,36 @@
/* :tabSize=2:indentSize=2:noTabs=true:
Copyright (C) 1989-94 Massachusetts Institute of Technology
Portions copyright (C) 2004-2008 Slava Pestov
Copyright (C) 1989-94 Massachusetts Institute of Technology
Portions copyright (C) 2004-2008 Slava Pestov
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and
Computer Science. Permission to copy and modify this software, to
redistribute either the original software or a modified version, and
to use this software for any purpose is granted, subject to the
following restrictions and understandings.
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and
Computer Science. Permission to copy and modify this software, to
redistribute either the original software or a modified version, and
to use this software for any purpose is granted, subject to the
following restrictions and understandings.
1. Any copy made of this software must include this copyright notice
in full.
1. Any copy made of this software must include this copyright notice
in full.
2. Users of this software agree to make their best efforts (a) to
return to the MIT Scheme project any improvements or extensions that
they make, so that these may be included in future releases; and (b)
to inform MIT of noteworthy uses of this software.
2. Users of this software agree to make their best efforts (a) to
return to the MIT Scheme project any improvements or extensions that
they make, so that these may be included in future releases; and (b)
to inform MIT of noteworthy uses of this software.
3. All materials developed as a consequence of the use of this
software shall duly acknowledge such use, in accordance with the usual
standards of acknowledging credit in academic research.
3. All materials developed as a consequence of the use of this
software shall duly acknowledge such use, in accordance with the usual
standards of acknowledging credit in academic research.
4. MIT has made no warrantee or representation that the operation of
this software will be error-free, and MIT is under no obligation to
provide any services, by way of maintenance, update, or otherwise.
4. MIT has made no warrantee or representation that the operation of
this software will be error-free, and MIT is under no obligation to
provide any services, by way of maintenance, update, or otherwise.
5. In conjunction with products arising from the use of this material,
there shall be no use of the name of the Massachusetts Institute of
Technology nor of any adaptation thereof in any advertising,
promotional, or sales literature without prior written consent from
MIT in each case. */
5. In conjunction with products arising from the use of this material,
there shall be no use of the name of the Massachusetts Institute of
Technology nor of any adaptation thereof in any advertising,
promotional, or sales literature without prior written consent from
MIT in each case. */
/* Changes for Scheme 48:
* - Converted to ANSI.
@ -338,8 +338,8 @@ bignum *factorvm::bignum_remainder(bignum * numerator, bignum * denominator)
#define FOO_TO_BIGNUM(name,type,utype) \
bignum * factorvm::name##_to_bignum(type n) \
{ \
bignum * factorvm::name##_to_bignum(type n) \
{ \
int negative_p; \
bignum_digit_type result_digits [BIGNUM_DIGITS_FOR(type)]; \
bignum_digit_type * end_digits = result_digits; \
@ -365,7 +365,7 @@ bignum *factorvm::bignum_remainder(bignum * numerator, bignum * denominator)
(*scan_result++) = (*scan_digits++); \
return (result); \
} \
}
}
/* all below allocate memory */
FOO_TO_BIGNUM(cell,cell,cell)
@ -374,7 +374,7 @@ FOO_TO_BIGNUM(long_long,s64,u64)
FOO_TO_BIGNUM(ulong_long,u64,u64)
#define BIGNUM_TO_FOO(name,type,utype) \
type factorvm::bignum_to_##name(bignum * bignum) \
type factorvm::bignum_to_##name(bignum * bignum) \
{ \
if (BIGNUM_ZERO_P (bignum)) \
return (0); \
@ -1348,7 +1348,7 @@ bignum * factorvm::allot_bignum_zeroed(bignum_length_type length, int negative_p
#define BIGNUM_REDUCE_LENGTH(source, length) \
source = reallot_array(source,length + 1)
source = reallot_array(source,length + 1)
/* allocates memory */
bignum *factorvm::bignum_shorten_length(bignum * bignum, bignum_length_type length)

View File

@ -3,13 +3,6 @@
namespace factor
{
/* Global variables used to pass fault handler state from signal handler to
user-space */
cell signal_number;
cell signal_fault_addr;
unsigned int signal_fpu_status;
stack_frame *signal_callstack_top;
void factorvm::out_of_memory()
{
print_string("Out of memory\n\n");

View File

@ -235,6 +235,8 @@ void* start_standalone_factor_thread(void *arg)
VM_C_API void start_standalone_factor(int argc, vm_char **argv)
{
factorvm *newvm = new factorvm;
newvm->print_vm_data();
printf("PHIL YEAH: %d %d %d %d\n",(void*)(newvm),(void*)(newvm+1),sizeof(newvm), sizeof(factorvm));
vm = newvm;
register_vm_with_thread(newvm);
return newvm->start_standalone_factor(argc,argv);
@ -247,4 +249,158 @@ VM_C_API THREADHANDLE start_standalone_factor_in_new_thread(int argc, vm_char **
return start_thread(start_standalone_factor_thread,args);
}
void factorvm::print_vm_data() {
printf("PHIL: stack_chain %d\n",&stack_chain);
printf("PHIL: nursery %d\n",&nursery);
printf("PHIL: cards_offset %d\n",&cards_offset);
printf("PHIL: decks_offset %d\n",&decks_offset);
printf("PHIL: userenv %d\n",&userenv);
printf("PHIL: ds_size %d\n",&ds_size);
printf("PHIL: rs_size %d\n",&rs_size);
printf("PHIL: unused_contexts %d\n",&unused_contexts);
printf("PHIL: T %d\n",&T);
printf("PHIL: profiling_p %d\n",&profiling_p);
printf("PHIL: signal_number %d\n",&signal_number);
printf("PHIL: signal_fault_addr %d\n",&signal_fault_addr);
printf("PHIL: signal_callstack_top %d\n",&signal_callstack_top);
printf("PHIL: secure_gc %d\n",&secure_gc);
printf("PHIL: gc_off %d\n",&gc_off);
printf("PHIL: data %d\n",&data);
printf("PHIL: heap_scan_ptr %d\n",&heap_scan_ptr);
printf("PHIL: allot_markers_offset %d\n",&allot_markers_offset);
printf("PHIL: newspace %d\n",&newspace);
printf("PHIL: performing_gc %d\n",&performing_gc);
printf("PHIL: performing_compaction %d\n",&performing_compaction);
printf("PHIL: collecting_gen %d\n",&collecting_gen);
printf("PHIL: collecting_aging_again %d\n",&collecting_aging_again);
printf("PHIL: gc_jmp %d\n",&gc_jmp);
printf("PHIL: stats %d\n",&stats);
printf("PHIL: cards_scanned %d\n",&cards_scanned);
printf("PHIL: decks_scanned %d\n",&decks_scanned);
printf("PHIL: card_scan_time %d\n",&card_scan_time);
printf("PHIL: code_heap_scans %d\n",&code_heap_scans);
printf("PHIL: last_code_heap_scan %d\n",&last_code_heap_scan);
printf("PHIL: growing_data_heap %d\n",&growing_data_heap);
printf("PHIL: old_data_heap %d\n",&old_data_heap);
printf("PHIL: gc_locals %d\n",&gc_locals);
printf("PHIL: gc_bignums %d\n",&gc_bignums);
printf("PHIL: fep_disabled %d\n",&fep_disabled);
printf("PHIL: full_output %d\n",&full_output);
printf("PHIL: look_for %d\n",&look_for);
printf("PHIL: obj %d\n",&obj);
printf("PHIL: bignum_zero %d\n",&bignum_zero);
printf("PHIL: bignum_pos_one %d\n",&bignum_pos_one);
printf("PHIL: bignum_neg_one %d\n",&bignum_neg_one);
printf("PHIL: code %d\n",&code);
printf("PHIL: forwarding %d\n",&forwarding);
printf("PHIL: code_relocation_base %d\n",&code_relocation_base);
printf("PHIL: data_relocation_base %d\n",&data_relocation_base);
printf("PHIL: megamorphic_cache_hits %d\n",&megamorphic_cache_hits);
printf("PHIL: megamorphic_cache_misses %d\n",&megamorphic_cache_misses);
printf("PHIL: max_pic_size %d\n",&max_pic_size);
printf("PHIL: cold_call_to_ic_transitions %d\n",&cold_call_to_ic_transitions);
printf("PHIL: ic_to_pic_transitions %d\n",&ic_to_pic_transitions);
printf("PHIL: pic_to_mega_transitions %d\n",&pic_to_mega_transitions);
printf("PHIL: pic_counts %d\n",&pic_counts);
}
// if you change this struct, also change vm.factor k--------
context *stack_chain;
zone nursery; /* new objects are allocated here */
cell cards_offset;
cell decks_offset;
cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */
// -------------------------------
// contexts
cell ds_size, rs_size;
context *unused_contexts;
// run
cell T; /* Canonical T object. It's just a word */
// profiler
bool profiling_p;
// errors
/* Global variables used to pass fault handler state from signal handler to
user-space */
cell signal_number;
cell signal_fault_addr;
unsigned int signal_fpu_status;
stack_frame *signal_callstack_top;
//data_heap
bool secure_gc; /* Set by the -securegc command line argument */
bool gc_off; /* GC is off during heap walking */
data_heap *data;
/* A heap walk allows useful things to be done, like finding all
references to an object for debugging purposes. */
cell heap_scan_ptr;
//write barrier
cell allot_markers_offset;
//data_gc
/* used during garbage collection only */
zone *newspace;
bool performing_gc;
bool performing_compaction;
cell collecting_gen;
/* if true, we are collecting aging space for the second time, so if it is still
full, we go on to collect tenured */
bool collecting_aging_again;
/* in case a generation fills up in the middle of a gc, we jump back
up to try collecting the next generation. */
jmp_buf gc_jmp;
gc_stats stats[max_gen_count];
u64 cards_scanned;
u64 decks_scanned;
u64 card_scan_time;
cell code_heap_scans;
/* What generation was being collected when copy_code_heap_roots() was last
called? Until the next call to add_code_block(), future
collections of younger generations don't have to touch the code
heap. */
cell last_code_heap_scan;
/* sometimes we grow the heap */
bool growing_data_heap;
data_heap *old_data_heap;
// local roots
/* If a runtime function needs to call another function which potentially
allocates memory, it must wrap any local variable references to Factor
objects in gc_root instances */
std::vector<cell> gc_locals;
std::vector<cell> gc_bignums;
//debug
bool fep_disabled;
bool full_output;
cell look_for;
cell obj;
//math
cell bignum_zero;
cell bignum_pos_one;
cell bignum_neg_one;
//code_heap
heap code;
unordered_map<heap_block *,char *> forwarding;
//image
cell code_relocation_base;
cell data_relocation_base;
//dispatch
cell megamorphic_cache_hits;
cell megamorphic_cache_misses;
//inline cache
cell max_pic_size;
cell cold_call_to_ic_transitions;
cell ic_to_pic_transitions;
cell pic_to_mega_transitions;
cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */
}

View File

@ -39,21 +39,20 @@ s64 current_micros()
- EPOCH_OFFSET) / 10;
}
FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
LONG factorvm::exception_handler(PEXCEPTION_POINTERS pe)
{
factorvm *myvm = SIGNAL_VM_PTR();
PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
CONTEXT *c = (CONTEXT*)pe->ContextRecord;
if(myvm->in_code_heap_p(c->EIP))
myvm->signal_callstack_top = (stack_frame *)c->ESP;
if(in_code_heap_p(c->EIP))
signal_callstack_top = (stack_frame *)c->ESP;
else
myvm->signal_callstack_top = NULL;
signal_callstack_top = NULL;
switch (e->ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION:
myvm->signal_fault_addr = e->ExceptionInformation[1];
c->EIP = (cell)memory_signal_handler_impl;
signal_fault_addr = e->ExceptionInformation[1];
c->EIP = (cell)factor::memory_signal_handler_impl;
break;
case STATUS_FLOAT_DENORMAL_OPERAND:
@ -65,10 +64,10 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
case STATUS_FLOAT_UNDERFLOW:
case STATUS_FLOAT_MULTIPLE_FAULTS:
case STATUS_FLOAT_MULTIPLE_TRAPS:
myvm->signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
X87SW(c) = 0;
MXCSR(c) &= 0xffffffc0;
c->EIP = (cell)fp_signal_handler_impl;
c->EIP = (cell)factor::fp_signal_handler_impl;
break;
case 0x40010006:
/* If the Widcomm bluetooth stack is installed, the BTTray.exe
@ -79,24 +78,30 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
enabled. Don't really have any idea what this exception means. */
break;
default:
myvm->signal_number = e->ExceptionCode;
c->EIP = (cell)misc_signal_handler_impl;
signal_number = e->ExceptionCode;
c->EIP = (cell)factor::misc_signal_handler_impl;
break;
}
return EXCEPTION_CONTINUE_EXECUTION;
}
FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
{
return SIGNAL_VM_PTR()->exception_handler(pe);
}
bool handler_added = 0;
void factorvm::c_to_factor_toplevel(cell quot)
{
if(!handler_added){
if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)exception_handler))
if(!AddVectoredExceptionHandler(0, (PVECTORED_EXCEPTION_HANDLER)factor::exception_handler))
fatal_error("AddVectoredExceptionHandler failed", 0);
handler_added = 1;
}
c_to_factor(quot,this);
RemoveVectoredExceptionHandler((void *)exception_handler);
RemoveVectoredExceptionHandler((void *)factor::exception_handler);
}
void factorvm::open_console()

116
vm/vm-data-dummy.hpp Normal file
View File

@ -0,0 +1,116 @@
namespace factor
{
// if you change this struct, also change vm.factor k--------
extern "C" context *stack_chain;
extern "C" zone nursery; /* new objects are allocated here */
extern "C" cell cards_offset;
extern "C" cell decks_offset;
//extern "C" cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */
// -------------------------------
// contexts
extern "C" cell ds_size, rs_size;
extern "C" context *unused_contexts;
// profiler
extern "C" bool profiling_p;
// errors
/* Global variables used to pass fault handler state from signal handler to
user-space */
extern "C" cell signal_number;
extern "C" cell signal_fault_addr;
extern "C" unsigned int signal_fpu_status;
extern "C" stack_frame *signal_callstack_top;
//data_heap
extern "C" bool secure_gc; /* Set by the -securegc command line argument */
extern "C" bool gc_off; /* GC is off during heap walking */
extern "C" data_heap *data;
/* A heap walk allows useful things to be done, like finding all
references to an object for debugging purposes. */
extern "C" cell heap_scan_ptr;
//write barrier
extern "C" cell allot_markers_offset;
//data_gc
/* used during garbage collection only */
extern "C" zone *newspace;
extern "C" bool performing_gc;
extern "C" bool performing_compaction;
extern "C" cell collecting_gen;
/* if true, we are collecting aging space for the second time, so if it is still
full, we go on to collect tenured */
extern "C" bool collecting_aging_again;
/* in case a generation fills up in the middle of a gc, we jump back
up to try collecting the next generation. */
extern "C" jmp_buf gc_jmp;
extern "C" gc_stats stats[max_gen_count];
extern "C" u64 cards_scanned;
extern "C" u64 decks_scanned;
extern "C" u64 card_scan_time;
extern "C" cell code_heap_scans;
/* What generation was being collected when copy_code_heap_roots() was last
called? Until the next call to add_code_block(), future
collections of younger generations don't have to touch the code
heap. */
extern "C" cell last_code_heap_scan;
/* sometimes we grow the heap */
extern "C" bool growing_data_heap;
extern "C" data_heap *old_data_heap;
// local roots
/* If a runtime function needs to call another function which potentially
allocates memory, it must wrap any local variable references to Factor
objects in gc_root instances */
//extern "C" segment *gc_locals_region;
//extern "C" cell gc_locals;
//extern "C" segment *gc_bignums_region;
//extern "C" cell gc_bignums;
//debug
extern "C" bool fep_disabled;
extern "C" bool full_output;
extern "C" cell look_for;
extern "C" cell obj;
//math
extern "C" cell bignum_zero;
extern "C" cell bignum_pos_one;
extern "C" cell bignum_neg_one;
//code_heap
extern "C" heap code;
extern "C" unordered_map<heap_block *,char *> forwarding;
//image
extern "C" cell code_relocation_base;
extern "C" cell data_relocation_base;
//dispatch
extern "C" cell megamorphic_cache_hits;
extern "C" cell megamorphic_cache_misses;
//inline cache
extern "C" cell max_pic_size;
extern "C" cell cold_call_to_ic_transitions;
extern "C" cell ic_to_pic_transitions;
extern "C" cell pic_to_mega_transitions;
extern "C" cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */
struct factorvmdata {
cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */
// run
cell T; /* Canonical T object. It's just a word */
// local roots
/* If a runtime function needs to call another function which potentially
allocates memory, it must wrap any local variable references to Factor
objects in gc_root instances */
std::vector<cell> gc_locals;
std::vector<cell> gc_bignums;
};
}

105
vm/vm-data.hpp Normal file
View File

@ -0,0 +1,105 @@
namespace factor
{
struct factorvmdata {
// if you change this struct, also change vm.factor k--------
context *stack_chain;
zone nursery; /* new objects are allocated here */
cell cards_offset;
cell decks_offset;
cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */
// -------------------------------
// contexts
cell ds_size, rs_size;
context *unused_contexts;
// run
cell T; /* Canonical T object. It's just a word */
// profiler
bool profiling_p;
// errors
/* Global variables used to pass fault handler state from signal handler to
user-space */
cell signal_number;
cell signal_fault_addr;
unsigned int signal_fpu_status;
stack_frame *signal_callstack_top;
//data_heap
bool secure_gc; /* Set by the -securegc command line argument */
bool gc_off; /* GC is off during heap walking */
data_heap *data;
/* A heap walk allows useful things to be done, like finding all
references to an object for debugging purposes. */
cell heap_scan_ptr;
//write barrier
cell allot_markers_offset;
//data_gc
/* used during garbage collection only */
zone *newspace;
bool performing_gc;
bool performing_compaction;
cell collecting_gen;
/* if true, we are collecting aging space for the second time, so if it is still
full, we go on to collect tenured */
bool collecting_aging_again;
/* in case a generation fills up in the middle of a gc, we jump back
up to try collecting the next generation. */
jmp_buf gc_jmp;
gc_stats stats[max_gen_count];
u64 cards_scanned;
u64 decks_scanned;
u64 card_scan_time;
cell code_heap_scans;
/* What generation was being collected when copy_code_heap_roots() was last
called? Until the next call to add_code_block(), future
collections of younger generations don't have to touch the code
heap. */
cell last_code_heap_scan;
/* sometimes we grow the heap */
bool growing_data_heap;
data_heap *old_data_heap;
// local roots
/* If a runtime function needs to call another function which potentially
allocates memory, it must wrap any local variable references to Factor
objects in gc_root instances */
std::vector<cell> gc_locals;
std::vector<cell> gc_bignums;
//debug
bool fep_disabled;
bool full_output;
cell look_for;
cell obj;
//math
cell bignum_zero;
cell bignum_pos_one;
cell bignum_neg_one;
//code_heap
heap code;
unordered_map<heap_block *,char *> forwarding;
//image
cell code_relocation_base;
cell data_relocation_base;
//dispatch
cell megamorphic_cache_hits;
cell megamorphic_cache_misses;
//inline cache
cell max_pic_size;
cell cold_call_to_ic_transitions;
cell ic_to_pic_transitions;
cell pic_to_mega_transitions;
cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */
};
}

105
vm/vm.hpp
View File

@ -1,106 +1,8 @@
#include "vm-data-dummy.hpp"
namespace factor
{
struct factorvmdata {
// if you change this struct, also change vm.factor k--------
context *stack_chain;
zone nursery; /* new objects are allocated here */
cell cards_offset;
cell decks_offset;
cell userenv[USER_ENV]; /* TAGGED user environment data; see getenv/setenv prims */
// -------------------------------
// contexts
cell ds_size, rs_size;
context *unused_contexts;
// run
cell T; /* Canonical T object. It's just a word */
// profiler
bool profiling_p;
// errors
/* Global variables used to pass fault handler state from signal handler to
user-space */
cell signal_number;
cell signal_fault_addr;
unsigned int signal_fpu_status;
stack_frame *signal_callstack_top;
//data_heap
bool secure_gc; /* Set by the -securegc command line argument */
bool gc_off; /* GC is off during heap walking */
data_heap *data;
/* A heap walk allows useful things to be done, like finding all
references to an object for debugging purposes. */
cell heap_scan_ptr;
//write barrier
cell allot_markers_offset;
//data_gc
/* used during garbage collection only */
zone *newspace;
bool performing_gc;
bool performing_compaction;
cell collecting_gen;
/* if true, we are collecting aging space for the second time, so if it is still
full, we go on to collect tenured */
bool collecting_aging_again;
/* in case a generation fills up in the middle of a gc, we jump back
up to try collecting the next generation. */
jmp_buf gc_jmp;
gc_stats stats[max_gen_count];
u64 cards_scanned;
u64 decks_scanned;
u64 card_scan_time;
cell code_heap_scans;
/* What generation was being collected when copy_code_heap_roots() was last
called? Until the next call to add_code_block(), future
collections of younger generations don't have to touch the code
heap. */
cell last_code_heap_scan;
/* sometimes we grow the heap */
bool growing_data_heap;
data_heap *old_data_heap;
// local roots
/* If a runtime function needs to call another function which potentially
allocates memory, it must wrap any local variable references to Factor
objects in gc_root instances */
std::vector<cell> gc_locals;
std::vector<cell> gc_bignums;
//debug
bool fep_disabled;
bool full_output;
cell look_for;
cell obj;
//math
cell bignum_zero;
cell bignum_pos_one;
cell bignum_neg_one;
//code_heap
heap code;
unordered_map<heap_block *,char *> forwarding;
//image
cell code_relocation_base;
cell data_relocation_base;
//dispatch
cell megamorphic_cache_hits;
cell megamorphic_cache_misses;
//inline cache
cell max_pic_size;
cell cold_call_to_ic_transitions;
cell ic_to_pic_transitions;
cell pic_to_mega_transitions;
cell pic_counts[4]; /* PIC_TAG, PIC_HI_TAG, PIC_TUPLE, PIC_HI_TAG_TUPLE */
};
struct factorvm : factorvmdata {
// segments
@ -694,6 +596,7 @@ struct factorvm : factorvmdata {
#if defined(WINNT)
void open_console();
LONG exception_handler(PEXCEPTION_POINTERS pe);
// next method here:
#endif
#else // UNIX
@ -702,9 +605,11 @@ struct factorvm : factorvmdata {
#endif
void print_vm_data();
};
#define FACTOR_SINGLE_THREADED_SINGLETON
#ifdef FACTOR_SINGLE_THREADED_SINGLETON