home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
-
- #include <stream.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include "tags.h"
- #include "instr.h"
- #include "hash_table.h"
- #include "string_table.h"
- #include "memory.h"
- #include "top_level.h"
-
- CellPtr S, B0, B, E0, E, TR0, TR, H0, H, R0, R;
- InstrPtr P0, CP0, FP0, NP0, MP0, P;
-
- #ifdef WITH_GC
- CellPtr H2, TR2, E2;
- CellPtr HMIN, HMAXSOFT, HMAXHARD;
- unsigned char* MKMIN;
- #endif
-
- Cell X[NUMBER_OF_REGISTERS];
-
- void memory_allocator_error(char* s)
- {
- cout << s << "\n";
- exit(2);
- }
-
- extern int getrlimit(...);
- extern int setrlimit(...);
-
- int amem()
- {
- int vfork();
- int execl(...);
- int wait(...);
- int pid;
- switch (pid = vfork()) {
- case 0:
- execl("pasmem", "pasmem", 0);
- break;
- case -1:
- cout << "can't fork out amem\n";
- exit(-1);
- default:
- wait(0);
- break;
- }
- filebuf* f1 = new filebuf;
- if (f1->open(".pas_data_limit", input) == 0) {
- cerr << "can't open .pas_data_limit\n";
- exit(1);
- }
- istream* i = new istream(f1);
- int size;
- *i >> size;
- return size;
- }
-
- int get_limit()
- {
- struct rlimit rl;
- if (getrlimit(RLIMIT_DATA, &rl)) return -1;
- rl.rlim_cur = rl.rlim_max;
- if (setrlimit(RLIMIT_DATA, &rl)) return -1;
- int size = amem();
- int i;
- for (i = 1; i <= size; i <<= 1)
- ;
- return i / 2;
- }
-
- struct AllocMem {
- int* p;
- int size;
- AllocMem(int* P =0, int SIZE =0) {p = P; size = SIZE;}
- };
-
- static int pagesize;
- const int MIN_NUMBER_OF_PAGES = 32;
- const int NUMBER_OF_PAGES_FREE = 32;
- const float MEM_SHARE_CONST = 0.5;
-
- AllocMem allocate_mem_civically(int size)
- {
- extern int getpagesize();
- pagesize = getpagesize();
- size = (int) (MEM_SHARE_CONST * size);
- size -= pagesize * NUMBER_OF_PAGES_FREE;
- size /= sizeof(int);
- for (int* p = 0;;) {
- p = new int[size];
- if (p == 0 && size > 0)
- size >>= 1;
- else
- break;
- }
- AllocMem A(p, size);
- return A;
- }
-
- void is_enough_memory(int size)
- {
- if (size < pagesize * MIN_NUMBER_OF_PAGES)
- memory_allocator_error("not enough memory");
- }
-
- AllocMem get_memory()
- {
- AllocMem A = allocate_mem_civically(get_limit());
- is_enough_memory(A.size);
- return A;
- }
-
- int memory_sizes[LAST_SIZE];
- static int memory_coeffs[] = {
- #define use(Name,ID,Coeff,Reg,Type)\
- Coeff,
- #include "memory_sizes.h"
- #undef use
- };
-
- static inline int round(int i)
- {
- int size = pagesize >> 2;
- return ((int) (i / size)) * size;
- }
-
- void compute_memory_sizes(int size)
- {
- int total_weight = 0;
- for (int i = 0; i < LAST_SIZE; i++)
- total_weight += memory_coeffs[i];
- for (i = 0; i < LAST_SIZE; i++)
- memory_sizes[i] = round((size * memory_coeffs[i]) / total_weight);
- }
-
- void partition_memory(AllocMem mem)
- {
- #define use(Name,ID,Coeff,Reg,Type)\
- Reg = (Type*) mem.p;\
- mem.p += memory_sizes[ID];\
- memory_sizes[ID] /= sizeof(Type) /sizeof(int);
- #include "memory_sizes.h"
- #undef use
- }
-
- void Memory::allocate()
- {
- AllocMem mem = get_memory();
- int* top = mem.p + mem.size;
- compute_memory_sizes(mem.size);
- partition_memory(mem);
- TR0 += memory_sizes[TRAIL_SIZE] - 1;
- B0 += memory_sizes[CP_SIZE] - 1;
- }
-
- void Memory::init()
- {
- Cell* NewE = E0 + E_TOP_OFFSET;
- B0 -= FIXED_CP_SIZE;
- NewE[B_ENV_OFFSET] = cell(B0);
- NewE[E_ENV_OFFSET] = cell(E0);
- NewE[P_ENV_OFFSET] = cell(CP0);
- E0 = NewE;
-
- B0[E_CP_OFFSET] = cell(E0);
- B0[H_CP_OFFSET] = cell(H0);
- B0[TR_CP_OFFSET] = cell(TR0);
- B0[P_CP_OFFSET] = cell(NP0);
- B0[SIZE_CP_OFFSET] = 0;
- }
-
- int next_instruction;
- Cell NIL;
- Cell LIST_FUNCTOR;
-
- Memory::Memory(StringTable& table)
- {
- ST = &table;
- NIL = make_atom(ST->intern("[]"));
- LIST_FUNCTOR = make_atom(ST->intern("./2"));
- }
-