finished: // ******************************************************************************************* cmpl $0,free // free >= 0 jg prepare_to_return garbage_collection2: # ifdef DEBUG_GC // int3 save_regs pushl $gc_message call _w_print_string addl $4,%esp pushl $'\n' call _w_print_char addl $4,%esp restore_regs # endif movl old_heap_pointer,heapP // release string memory # define usedCells %eax movl initfree,usedCells subl free,usedCells leal -32(heapP,usedCells,4),free // reserve usedCells * 4 from old heap start, gebruik l-entry # ifdef USE_CGTSA_AND_CGTSR movl ecx_backup,%ecx # else movl type_table_usage,%ecx movl root_node,%edx # endif movl esp_backup,%esp // restore B/C stackpointer popl %esi movl esi_backup,%esi # ifdef USE_CGTSA_AND_CGTSR call collect_1l # else call collect_2l # endif #undef usedCells nop nop nop nop nop movl $1,retry_after_gc jmp copy__graph__to__string__0x00010101 /* ** string format: */ prepare_to_return: movl esp_backup,%esp #define temp %eax prepare_to_return2: # ifdef COLOUR_GRAPH _set_default_undo_handler // misschien vooraf alles tussen heapP en end_heap vrijgeven. # define BK_BLOCK_N 0 # define BK_START_OFFSET 4 // offset (in bytes) from encoding start # define BK_SIZE 8 // block size (in bytes) # define BK_N_EN_NODES 12 // # EN-nodes in block # define BK_BASIC_BSIZE (BK_N_EN_NODES + 4) # define BK_BASIC_WSIZE (BK_BASIC_BSIZE / MACHINE_WORD_BSIZE) // in bytes // block table // store # blocks call MAKE_ID_FBI(lb_size) # define n_blocks %ecx // create index array for quick block array access subl n_blocks,free js GC_FIXED_STACK movl n_blocks,temp shll $2,temp movl temp,index_array_size // size of index array (in bytes) movl heapP,index_array_ptr // backup index array_pointer leal (heapP,n_blocks,4),heapP // create index array for blocks // create block array movl heapP,block_table_start // backup block table start subl $1,free js GC_FIXED_STACK movl n_blocks,(heapP) // amount of blocks # undef n_blocks addl $4,heapP movl $ create_block_table,%ecx // create block table call MAKE_ID_FBI(lb_map_array) movl $ insert_en_nodes_in_block_table,%ecx call MAKE_ID_FEN(lb_map_array) // overwrite index_array with block table # define block_table_p nodeP # define index_array_p descP # define block_table_end heapP movl block_table_start,block_table_p // load start address of block table movl index_array_ptr,index_array_p // load start address of index array movl index_array_p,block_table_start // new start address of block table 1: cmpl block_table_end,block_table_p jae 0f // block_table_p >= block_table_end # define temp2 arity movl (block_table_p),temp2 movl temp2,(index_array_p) # undef temp2 addl $4,block_table_p addl $4,index_array_p jmp 1b 0: subl index_array_size,heapP // free index array movl heapP,block_table_end2 # undef block_table_end # undef index_array_p # undef block_table_p # endif // COLOUR_GRAPH movl old_heap_pointer,%ecx movl heapP,%eax subl %ecx,%eax subl $8,%eax movl %eax,4(%ecx) // length (%eax) = heapP - old_heap_pointer - 8 #define t2 descP #define t3 stackP movl old_heap_pointer,temp leal 8(temp),temp // temp = ptr to string start # ifdef COLOUR_GRAPH // set header size movl $ HEADER_SIZE,t3 subl $4,t3 movl t3,HEADER_SIZE_OFFSET(%ecx) // header size // set version number of encoding routine movl $ VERSION_NUMBER,t2 movl t2,VERSION_NUMBER_OFFSET(%ecx) // set graph offset and size movl graph_start,t2 movl graph_end,t3 subl t2,t3 // t3 = graph_end - graph_start movl t3,GRAPH_SIZE(%ecx) subl temp,t2 // t2 = graph_start - string start movl t2,GRAPH_OFFSET(%ecx) // set block table offset and size movl block_table_start,t2 movl block_table_end2,t3 subl t2,t3 // t3 = graph_end - graph_start movl t3,BLOCK_TABLE_SIZE(%ecx) subl temp,t2 // t2 = graph_start - string start movl t2,BLOCK_TABLE_OFFSET(%ecx) movl $0x0,DYNAMIC_RTS_INFO_OFFSET(%ecx) movl $0x0,DYNAMIC_RTS_INFO_SIZE(%ecx) // End sharing for StdDynamic.icl // set string table offset and size movl string_table_start,t2 movl string_table_end,t3 subl t2,t3 movl t3,STRINGTABLE_SIZE(%ecx) subl temp,t2 movl t2,STRINGTABLE_OFFSET(%ecx) // set descriptor usage set offset and size movl dus_start,t2 movl dus_end,t3 subl t2,t3 movl t3,DESCADDRESSTABLE_SIZE(%ecx) subl temp,t2 movl t2,DESCADDTRESTABLE_OFFSET(%ecx) // set nodes movl n_nodes,t3 movl t3,N_NODES(%ecx) # else movl $ HEADER_SIZE,t3 subl $4,t3 movl t3,HEADER_SIZE_OFFSET(%ecx) // header size movl $ HEADER_SIZE,t3 movl t3,GRAPH_OFFSET(%ecx) // in future there may be a gap between header and graph offset movl $ VERSION_NUMBER,t2 movl t2,VERSION_NUMBER_OFFSET(%ecx) movl string_table_base,t2 subl temp,t2 movl t2,STRINGTABLE_OFFSET(%ecx) // set stringtable offset (t2_ subl t3,t2 movl t2,GRAPH_SIZE(%ecx) movl descriptor_address_table_base,t2 subl temp,t2 movl t2,DESCADDTRESTABLE_OFFSET(%ecx) movl STRINGTABLE_OFFSET(%ecx),t3 subl t3,t2 movl t2,STRINGTABLE_SIZE(%ecx) movl heapP,t3 subl temp,t3 subl DESCADDTRESTABLE_OFFSET(%ecx),t3 movl t3,DESCADDRESSTABLE_SIZE(%ecx) movl n_nodes,t3 movl t3,N_NODES(%ecx) # endif // COLOUR_GRAPH # ifdef COLOUR_GRAPH # else movl $0,BLOCK_TABLE_OFFSET(%ecx) movl $0,BLOCK_TABLE_SIZE(%ecx) # endif #undef temp // #undef t2 #undef t3 popl %esi # ifdef DYNAMIC_STRINGS pushl %ecx // backup ptr to encoded dynamic call MAKE_ID_FDS(lb_size) movl %ecx,%eax // %eax = n_elements to store addl %eax,%ecx addl %eax,%ecx addl $3,%ecx pushl %esi subl %ecx,free // reserve heap js GC_FIXED_STACK popl %esi movl %eax,%ecx # ifdef USE_CGTSA_AND_CGTSR movl %edi,backup_lazy_dynamic_index_array # else // not USE_CGTSA_AND_CGTSR movl %edi,-8(%esi) # endif movl $__ARRAY__+2,(%edi) // fill array header movl %ecx,4(%edi) movl $e__StdDynamicLowLevelInterface__rLazyDynamicReference+2,8(%edi) addl $12,%edi pushl %esi movl $ fill_dynamic_string,%ecx call MAKE_ID_FDS(lb_map_array) popl %esi # ifdef CONVERT_LAZY_RUN_TIME_ID call MAKE_ID_FRTID(lb_size) movl %ecx,%eax // n_elements to store addl %eax,%ecx addl %eax,%ecx addl $3,%ecx pushl %esi subl %ecx,free js GC_FIXED_STACK popl %esi movl %eax,%ecx // get n_elements back movl %edi,backup_runtime_ids movl $__ARRAY__+2,(%edi) movl %ecx,4(%edi) movl $e__DynamicLinkerInterface__rRunTimeIDW+2,8(%edi) addl $12,%edi pushl %esi movl $ fill_runtime_ids,%ecx call MAKE_ID_FRTID(lb_map_array) popl %esi # endif popl %ecx // restore ptr to encoded dynamic # ifndef USE_CGTSA_AND_CGTSR subl $4,%esi # endif // not USE_CGTSA_AND_CGTSR # else // not DYNAMIC_STRINGS // aanname: genoeg geheugen movl $__ARRAY__+2,(%edi) movl $0,4(%edi) movl $0,8(%edi) movl %edi,-8(%esi) addl $12,%edi subl $4,%esi # endif # ifdef USE_CGTSA_AND_CGTSR subl $ 12+CGTSR_ARG_BLOCK_SIZE,free js GC_FIXED_STACK pushl heapP # define temp %eax // Node // (%edi) : CopyGraphToStringResults-descriptor // 4(%edi) : string containing encoded dynamic (%ecx) // 8(%edi) : ptr to arg block movl $ e____SystemDynamic__rCopyGraphToStringResults+2,(heapP) movl %ecx,CGTSR_ENCODED_DYNAMIC(heapP) // ptr to encoded dynamic leal 12(heapP),temp movl temp,8(heapP) // ptr to arg block addl $12,heapP // Arg block // layout of argument block # define cgtsa %ebx movl ecx_backup,cgtsa movl 8(cgtsa),cgtsa // ptr to arg block movl CGTSA_CODE_LIBRARY_INSTANCES(cgtsa),temp movl temp,CGTSR_CODE_LIBRARY_INSTANCES(heapP) movl CGTSA_TYPE_LIBRARY_INSTANCES(cgtsa),temp movl temp,CGTSR_TYPE_LIBRARY_INSTANCES(heapP) movl backup_lazy_dynamic_index_array,temp movl temp,CGTSR_LAZY_DYNAMIC_REFERENCES(heapP) # ifdef CONVERT_LAZY_RUN_TIME_ID movl backup_runtime_ids,temp movl temp,CGTSR_RUNTIME_IDS(heapP) # endif addl $ CGTSR_ARG_BLOCK_SIZE,heapP # undef cgtsa popl %ecx // ptr to CGTSR-node # undef temp # else // not USE_CGTSA_AND_CGTSR movl %ecx,%edx movl type_table_usage,%ecx # endif // not USE_CGTSA_AND_CGTSR ret # ifdef DYNAMIC_STRINGS fill_dynamic_string: movl (%ecx),%eax movl %eax,(heapP) movl 4(%ecx),%eax movl %eax,4(heapP) movl 8(%ecx),%eax movl %eax,8(heapP) addl $12,heapP ret # endif // DYNAMIC_STRINGS # ifdef COLOUR_GRAPH // insert en-nodes in block table // Two tasks: // 1. fill variable sized part of block table // 2. min (BK_START_OFFSET,current offset) (en-nodes of a block are encoded succesive) insert_en_nodes_in_block_table: # define en_node %ecx # define temp descP movl EN_NODE_INDEX(en_node),temp // get node index pushl temp // backup node index andl $0x0000ffff,temp shrl $2,temp // temp = block index # define block_table_entry nodeP movl index_array_ptr,block_table_entry leal (block_table_entry,temp,4),block_table_entry movl (block_table_entry),block_table_entry # undef temp # define en_offset descP movl EN_BLOCK_OFFSET(en_node),en_offset // get offset in subl $ (HEADER_SIZE + 8),en_offset # undef en_node // store minimum offset of EN-nodes in block table # define current_block_offset arity movl ((- BK_BASIC_BSIZE) + BK_START_OFFSET)(block_table_entry),current_block_offset // get current block offset cmpl en_offset,current_block_offset jbe 0f // current_block_offset <= en_offset movl en_offset,((- BK_BASIC_BSIZE) + BK_START_OFFSET)(block_table_entry) // store smaller offset # undef current_block_offset 0: # define en_index arity popl en_index // restore node index cmpl $0,((- BK_BASIC_BSIZE) + BK_N_EN_NODES)(block_table_entry) je 1f shrl $16,en_index // extract entry node index movl en_offset,(block_table_entry,en_index,4) # undef en_offset 1: # undef block_table_entry ret // creates the block table create_block_table: # define bi_block %ecx subl $ BK_BASIC_WSIZE,free // allocate basic block js GC_FIXED_STACK // get & store block number # define block_n nodeP movl BI_INFO(bi_block),block_n andl $0x0000ffff,block_n shrl $2,block_n movl block_n,BK_BLOCK_N(heapP) # define temp descP movl index_array_ptr,temp leal (temp,block_n,4),temp // temp = address in index_array for block_n leal BK_BASIC_BSIZE(heapP),block_n movl block_n,(temp) // store address to variable sized of block_n # undef temp # undef block_n movl $0xffffffff,BK_START_OFFSET(heapP) // minimum of start offsets of the block EN-nodes // extract & store block size # define temp nodeP movl BI_INFO(bi_block),temp shrl $16,temp movl temp,BK_SIZE(heapP) # undef temp // store amount of block entry nodes # define n_en_nodes nodeP movl BI_N_EN_NODES(bi_block),n_en_nodes cmpl $1,n_en_nodes jne 0f decl n_en_nodes // n_en_nodes is zero 0: movl n_en_nodes,BK_N_EN_NODES(heapP) addl $ BK_BASIC_BSIZE,heapP // reserve heap memory for the block entry nodes subl n_en_nodes,free // reserve a machine word for each entry node js GC_FIXED_STACK shll $2,n_en_nodes addl n_en_nodes,heapP # undef n_en_nodes # undef bi_block ret # ifdef CONVERT_LAZY_RUN_TIME_ID fill_runtime_ids: # define temp %eax movl RTID_TYPE_STRING(%ecx),temp movl temp,RTID_TYPE_STRING(heapP) movl RTID_RUNTIME_ID(%ecx),temp movl temp,RTID_RUNTIME_ID(heapP) movl RTID_ASSIGNED_DISK_ID(%ecx),temp movl temp,RTID_ASSIGNED_DISK_ID(heapP) addl $ RTID_SIZE,heapP ret // CONVERT_LAZY_RUN_TIME_ID # undef temp # endif .data .align 4 index_array_ptr: .long 0 index_array_size: .long 0 // general graph_start: .long 0 graph_end: .long 0 block_table_start: .long 0 block_table_end2: .long 0 dus_start: .long 0 dus_end: .long 0 usage_bit_set_size: .long 0 n_usage_entries: .long 0 # endif // COLOUR_GRAPH .data .align 4 string_table_start: string_table_base: .long 0 string_table_end: .long 0 backup_lazy_dynamic_index_array: .long 0 # ifdef CONVERT_LAZY_RUN_TIME_ID backup_runtime_ids: .long 0 # endif