/* * Ikarus Scheme -- A compiler for R6RS Scheme. * Copyright (C) 2006,2007 Abdulaziz Ghuloum * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IKARUS_H #define IKARUS_H #include "ikarus-getaddrinfo.h" #include #include extern int total_allocated_pages; extern int total_malloced; extern int hash_table_count; #define cardsize 512 #define cards_per_page 8 #define most_bytes_in_minor 0x10000000 #define old_gen_mask 0x00000007 #define new_gen_mask 0x00000008 #define gen_mask 0x0000000F #define new_gen_tag 0x00000008 #define meta_dirty_mask 0x000000F0 #define type_mask 0x00000F00 #define scannable_mask 0x0000F000 #define dealloc_mask 0x000F0000 #define large_object_mask 0x00100000 #define meta_dirty_shift 4 #define hole_type 0x00000000 #define mainheap_type 0x00000100 #define mainstack_type 0x00000200 #define pointers_type 0x00000300 #define dat_type 0x00000400 #define code_type 0x00000500 #define weak_pairs_type 0x00000600 #define symbols_type 0x00000700 #define scannable_tag 0x00001000 #define unscannable_tag 0x00000000 #define dealloc_tag_un 0x00010000 #define dealloc_tag_at 0x00020000 #define retain_tag 0x00000000 #define large_object_tag 0x00100000 #define hole_mt (hole_type | unscannable_tag | retain_tag) #define mainheap_mt (mainheap_type | unscannable_tag | retain_tag) #define mainstack_mt (mainstack_type | unscannable_tag | retain_tag) #define pointers_mt (pointers_type | scannable_tag | dealloc_tag_un) #define symbols_mt (symbols_type | scannable_tag | dealloc_tag_un) #define data_mt (dat_type | unscannable_tag | dealloc_tag_un) #define code_mt (code_type | scannable_tag | dealloc_tag_un) #define weak_pairs_mt (weak_pairs_type | scannable_tag | dealloc_tag_un) static int inthash(int key) { key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); return key; return inthash(key); } #define wordsize 4 #define wordshift 2 #define pagesize 4096 #define generation_count 5 /* generations 0 (nursery), 1, 2, 3, 4 */ typedef unsigned long int ikptr; typedef int ikchar; void ik_error(ikptr args); typedef struct ikpage{ ikptr base; struct ikpage* next; } ikpage; typedef struct ikpages{ ikptr base; int size; struct ikpages* next; } ikpages; typedef struct ikdl{ /* double-link */ struct ikdl* prev; struct ikdl* next; } ikdl; #define ik_ptr_page_size \ ((pagesize - sizeof(int) - sizeof(struct ik_ptr_page*))/sizeof(ikptr)) typedef struct ik_ptr_page{ int count; struct ik_ptr_page* next; ikptr ptr[ik_ptr_page_size]; } ik_ptr_page; typedef struct ikpcb{ /* the first locations may be accessed by some */ /* compiled code to perform overflow/underflow ops */ ikptr allocation_pointer; /* offset = 0 */ ikptr allocation_redline; /* offset = 4 */ ikptr frame_pointer; /* offset = 8 */ ikptr frame_base; /* offset = 12 */ ikptr frame_redline; /* offset = 16 */ ikptr next_k; /* offset = 20 */ ikptr system_stack; /* offset = 24 */ ikptr dirty_vector; /* offset = 28 */ ikptr arg_list; /* offset = 32 */ ikptr engine_counter; /* offset = 36 */ ikptr interrupted; /* offset = 40 */ ikptr base_rtd; /* offset = 44 */ ikptr collect_key; /* offset = 48 */ /* the rest are not used by any scheme code */ /* they only support the runtime system (gc, etc.) */ ikptr* root0; ikptr* root1; unsigned int* segment_vector; ikptr weak_pairs_ap; ikptr weak_pairs_ep; ikptr heap_base; int heap_size; ikpages* heap_pages; ikpage* cached_pages; /* pages cached so that we don't map/unmap */ ikpage* uncached_pages; /* ikpages cached so that we don't malloc/free */ ikptr cached_pages_base; int cached_pages_size; ikptr stack_base; int stack_size; ikptr symbol_table; ikptr gensym_table; ik_ptr_page* guardians[generation_count]; ik_ptr_page* guardians_dropped[generation_count]; unsigned int* dirty_vector_base; unsigned int* segment_vector_base; ikptr memory_base; ikptr memory_end; int collection_id; int allocation_count_minor; int allocation_count_major; struct timeval collect_utime; struct timeval collect_stime; struct timeval collect_rtime; } ikpcb; ikpcb* ik_collect(int req, ikpcb* pcb); void ikarus_usage_short(void); void* ik_malloc(int); void ik_free(void*, int); ikptr ik_mmap(int); ikptr ik_mmap_typed(int size, unsigned int type, ikpcb*); ikptr ik_mmap_ptr(int size, int gen, ikpcb*); ikptr ik_mmap_data(int size, int gen, ikpcb*); ikptr ik_mmap_code(int size, int gen, ikpcb*); ikptr ik_mmap_mixed(int size, ikpcb*); void ik_munmap(ikptr, int); void ik_munmap_from_segment(ikptr, int, ikpcb*); ikpcb* ik_make_pcb(); void ik_delete_pcb(ikpcb*); void ik_free_symbol_table(ikpcb* pcb); void ik_fasl_load(ikpcb* pcb, char* filename); void ik_relocate_code(ikptr); ikptr ik_exec_code(ikpcb* pcb, ikptr code_ptr); void ik_print(ikptr x); void ik_fprint(FILE*, ikptr x); ikptr ikrt_string_to_symbol(ikptr, ikpcb*); ikptr ikrt_strings_to_gensym(ikptr, ikptr, ikpcb*); ikptr ik_cstring_to_symbol(char*, ikpcb*); ikptr ik_asm_enter(ikpcb*, ikptr code_object, ikptr arg); ikptr ik_asm_reenter(ikpcb*, ikptr code_object, ikptr val); ikptr ik_underflow_handler(ikpcb*); ikptr ik_unsafe_alloc(ikpcb* pcb, int size); ikptr ik_safe_alloc(ikpcb* pcb, int size); #define IK_FASL_HEADER "#@IK01" #define IK_FASL_HEADER_LEN (strlen(IK_FASL_HEADER)) #define IK_FASL_CODE_HEADER_SIZE 12 #define code_pri_tag vector_tag #define code_tag ((ikptr)0x2F) #define disp_code_code_size (1 * wordsize) #define disp_code_reloc_vector (2 * wordsize) #define disp_code_freevars (3 * wordsize) #define disp_code_annotation (4 * wordsize) #define disp_code_unused (5 * wordsize) #define disp_code_data (6 * wordsize) #define off_code_annotation (disp_code_annotation - code_pri_tag) #define off_code_data (disp_code_data - code_pri_tag) #define off_code_reloc_vector (disp_code_reloc_vector - code_pri_tag) #define IK_ALIGN_SHIFT 3 #define align_shift 3 #define IK_ALIGN_SIZE 8 #define align_size 8 #define IK_ALIGN(n) \ ((((n) + IK_ALIGN_SIZE - 1) >> IK_ALIGN_SHIFT) << IK_ALIGN_SHIFT) #define align(n) \ ((((n) + align_size - 1) >> align_shift) << align_shift) #define IK_FX_SHIFT 2 #define IK_FX_MASK 3 #define fx_shift 2 #define fx_mask 3 #define unfix(x) (((long int)(x)) >> fx_shift) #define fix(x) ((ikptr)(((long int)(x)) << fx_shift)) #define is_fixnum(x) ((((unsigned long)(x)) & fx_mask) == 0) #define IK_FIXNUMP(x) \ ((((int)(x)) & IK_FX_MASK) == 0) #define ref(x,n) \ (((ikptr*)(((char*)(long int)(x)) + ((long int)(n))))[0]) #define IK_MASK(x,m) (((long int)(x)) & ((long int)(m))) #define IK_PTAG(x) (((int)(x)) & 7) #define tagof(x) (((int)(x)) & 7) #define IK_STAG(x) REF(x, -IK_PTAG(x)) #define immediate_tag 7 #define IK_UNFIX(x) (((int)(x)) >> IK_FX_SHIFT) #define IK_FIX(x) ((ikptr)((x) << IK_FX_SHIFT)) #define IK_CODE_P(x) \ ((IK_PTAG(x) == IK_CODE_PRI_TAG) && (IK_STAG(x) == IK_CODE_SEC_TAG)) #define IK_FALSE_OBJECT ((ikptr)0x2F) #define IK_TRUE_OBJECT ((ikptr)0x3F) #define false_object ((ikptr)0x2F) #define true_object ((ikptr)0x3F) #define IK_NULL_OBJECT ((ikptr)0x4F) #define null_object ((ikptr)0x4F) #define void_object ((ikptr)0x7F) #define bwp_object ((ikptr)0x8F) #define unbound_object ((ikptr)0x6F) #define IK_CHAR_TAG 0x0F #define IK_CHAR_MASK 0xFF #define IK_CHAR_SHIFT 8 #define IK_CHAR_VAL(x) (((int)(x)) >> IK_CHAR_SHIFT) #define int_to_scheme_char(x) \ ((ikptr)((((unsigned long int)(x)) << IK_CHAR_SHIFT) | IK_CHAR_TAG)) #define IK_PAIR_SIZE 8 #define pair_size 8 #define pair_mask 7 #define pair_tag 1 #define disp_car 0 #define disp_cdr 4 #define off_car (disp_car - pair_tag) #define off_cdr (disp_cdr - pair_tag) #define IK_PAIR_TAG 1 #define IK_DISP_CAR 0 #define IK_DISP_CDR 4 #define IK_OFF_CAR (IK_DISP_CAR - IK_PAIR_TAG) #define IK_OFF_CDR (IK_DISP_CDR - IK_PAIR_TAG) #define IK_HEAP_EXT_SIZE (32 * 4096) #define IK_HEAPSIZE (1024 * 4096) /* 4 MB */ #define IK_PAIRP(x) (IK_PTAG(x) == IK_PAIR_TAG) #define IK_CHARP(x) (IK_MASK(x,IK_CHAR_MASK) == IK_CHAR_TAG) #define is_char(x) (IK_MASK(x,IK_CHAR_MASK) == IK_CHAR_TAG) #define IK_STRING_TAG 6 #define string_tag 6 #define disp_string_length 0 #define disp_string_data wordsize #define off_string_length (disp_string_length - string_tag) #define off_string_data (disp_string_data - string_tag) #define string_set(x,i,c) \ (((ikchar*)(((long)(x)) + off_string_data))[i] = ((ikchar)(c))) #define integer_to_char(x) \ ((ikchar)((((int)(x)) << IK_CHAR_SHIFT) + IK_CHAR_TAG)) #define string_char_size 4 #define vector_tag 5 #define disp_vector_length 0 #define disp_vector_data wordsize #define off_vector_data (disp_vector_data - vector_tag) #define off_vector_length (disp_vector_length - vector_tag) #define bytevector_tag 2 #define disp_bytevector_length 0 #define disp_bytevector_data 8 #define off_bytevector_length (disp_bytevector_length - bytevector_tag) #define off_bytevector_data (disp_bytevector_data - bytevector_tag) #define symbol_record_tag ((ikptr) 0x5F) #define disp_symbol_record_string (1 * wordsize) #define disp_symbol_record_ustring (2 * wordsize) #define disp_symbol_record_value (3 * wordsize) #define disp_symbol_record_proc (4 * wordsize) #define disp_symbol_record_plist (5 * wordsize) #define symbol_record_size (6 * wordsize) #define off_symbol_record_string (disp_symbol_record_string - record_tag) #define off_symbol_record_ustring (disp_symbol_record_ustring - record_tag) #define off_symbol_record_value (disp_symbol_record_value - record_tag) #define off_symbol_record_proc (disp_symbol_record_proc - record_tag) #define off_symbol_record_plist (disp_symbol_record_plist - record_tag) #define closure_tag 3 #define closure_mask 7 #define disp_closure_code 0 #define disp_closure_data wordsize #define off_closure_code (disp_closure_code - closure_tag) #define off_closure_data (disp_closure_data - closure_tag) #define is_closure(x) ((((long int)(x)) & closure_mask) == closure_tag) #define is_pair(x) ((((long int)(x)) & pair_mask) == pair_tag) #define record_tag vector_tag #define disp_record_rtd 0 #define disp_record_data wordsize #define off_record_rtd (disp_record_rtd - record_tag) #define off_record_data (disp_record_data - record_tag) #define rtd_tag record_tag #define disp_rtd_rtd 0 #define disp_rtd_name (1 * wordsize) #define disp_rtd_length (2 * wordsize) #define disp_rtd_fields (3 * wordsize) #define disp_rtd_printer (4 * wordsize) #define disp_rtd_symbol (5 * wordsize) #define rtd_size (6 * wordsize) #define off_rtd_rtd (disp_rtd_rtd - rtd_tag) #define off_rtd_name (disp_rtd_name - rtd_tag) #define off_rtd_length (disp_rtd_length - rtd_tag) #define off_rtd_fields (disp_rtd_fields - rtd_tag) #define off_rtd_printer (disp_rtd_printer - rtd_tag) #define off_rtd_symbol (disp_rtd_symbol - rtd_tag) #define continuation_tag ((ikptr)0x1F) #define disp_continuation_top (1 * wordsize) #define disp_continuation_size (2 * wordsize) #define disp_continuation_next (3 * wordsize) #define continuation_size (4 * wordsize) #define off_continuation_top (disp_continuation_top - vector_tag) #define off_continuation_size (disp_continuation_size - vector_tag) #define off_continuation_next (disp_continuation_next - vector_tag) #define pagesize 4096 #define pageshift 12 #define align_to_next_page(x) \ (((pagesize - 1 + (unsigned long int)(x)) >> pageshift) << pageshift) #define align_to_prev_page(x) \ ((((unsigned long int)(x)) >> pageshift) << pageshift) #define disp_frame_size -17 // FIXME #define port_tag 0x3F #define port_mask 0x3F #define port_size (14 * wordsize) #define disp_tcbucket_tconc (0 * wordsize) #define disp_tcbucket_key (1 * wordsize) #define disp_tcbucket_val (2 * wordsize) #define disp_tcbucket_next (3 * wordsize) #define tcbucket_size (4 * wordsize) #define off_tcbucket_tconc (disp_tcbucket_tconc - vector_tag) #define off_tcbucket_key (disp_tcbucket_key - vector_tag) #define off_tcbucket_val (disp_tcbucket_val - vector_tag) #define off_tcbucket_next (disp_tcbucket_next - vector_tag) #define bignum_mask 0x7 #define bignum_tag 0x3 #define bignum_sign_mask 0x8 #define bignum_sign_shift 3 #define bignum_length_shift 4 #define disp_bignum_data wordsize #define off_bignum_data (disp_bignum_data - vector_tag) #define flonum_tag ((ikptr)0x17) #define flonum_size 16 #define disp_flonum_data 8 /* not wordsize */ #define off_flonum_data (disp_flonum_data - vector_tag) #define flonum_data(x) (*((double*)(((char*)(long)(x))+off_flonum_data))) #define ratnum_tag ((ikptr) 0x27) #define disp_ratnum_num (1 * wordsize) #define disp_ratnum_den (2 * wordsize) #define disp_ratnum_unused (3 * wordsize) #define ratnum_size (4 * wordsize) #define ik_eof_p(x) ((x) == ik_eof_object) #define page_index(x) (((unsigned long int)(x)) >> pageshift) #endif