/* NOTE: A copy of this code exists in Sparc/memory.s; if you change * anything here, check that code as well. */ int stk_restore_frame( word *globals ) { word *stktop, *hframe, *p; word retoffs, proc, codeaddr, codeptr, header; unsigned size; assert2(globals[ G_STKP ] == globals[ G_STKBOT ]); hframe = ptrof( globals[ G_CONT ] ); size = roundup8( sizefield( *hframe ) + 4 ); /* bytes to copy */ stktop = (word*)globals[ G_STKP ]; stktop -= size / 4; if (stktop < (word*)globals[ G_ETOP ]) { supremely_annoyingmsg( "Failed to create stack." ); return 0; } globals[ G_STKP ] = (word)stktop; globals[ G_STKUFLOW ] += 1; #if 0 annoyingmsg("Restore: %d", size); #endif /* copy the frame onto the stack */ p = stktop; while (size) { *p++ = *hframe++; *p++ = *hframe++; size -= 8; } /* Follow continuation chain. */ globals[ G_CONT ] = *(stktop+STK_DYNLINK); header = *(stktop+HC_HEADER); retoffs = *(stktop+HC_RETOFFSET); proc = *(stktop+HC_PROC); /* convert the header back to a fixnum */ *(stktop+STK_CONTSIZE) = sizefield(header); /* convert the return address */ if (proc != 0) { codeptr = *(ptrof( proc )+PROC_CODEPTR); if (tagof( codeptr ) == BVEC_TAG) { codeaddr = (word)ptrof( codeptr ); *(stktop+STK_RETADDR) = (codeaddr+4)+retoffs; } else { *(stktop+STK_RETADDR) = retoffs; } } else { *(stktop+STK_RETADDR) = retoffs; } return 1; }
int stk_size_for_top_stack_frame( word *globals ) { #if OLD_GC_CODE return nativeint( *(word*)globals[ G_STKP ] )*sizeof( word ) + STACK_BASE_SIZE; #else int frame_size; if (globals[ G_STKP ] == globals[ G_STKBOT]) frame_size = sizefield( *ptrof( globals[ G_CONT ] ) ); else frame_size = *((word*)globals[ G_STKP ] + STK_CONTSIZE); return roundup8( frame_size + 4 ) + STACK_BASE_SIZE; #endif }
static void* visit_measuring_float( word *addr, int tag, void *accum ) { struct visit_measuring_float_data *data = (struct visit_measuring_float_data*)accum; word obj; bool marked; bool marked_via_remsets; int words; struct float_counts *type_counts; obj = tagptr( addr, tag ); marked = msfloat_object_marked_p( data->context, obj ); marked_via_remsets = msfloat_object_marked_p( data->context_incl_remsets, obj ); data->objs.total += 1 ; if (!marked && !marked_via_remsets) { data->objs.zzflt += 1; } if (!marked && marked_via_remsets) { data->objs.rsflt += 1; } switch (tag) { case PAIR_TAG: words = 2; break; case VEC_TAG: case BVEC_TAG: case PROC_TAG: words = roundup8( sizefield( *addr )+4 ) / 4; break; default: assert(0); } data->words.total += words; if (!marked && !marked_via_remsets) data->words.zzflt += words; if (!marked && marked_via_remsets) data->words.rsflt += words; return data; }
static bool fill_from_los_stack( msgc_context_t *context ) { int next, k, n, i; word obj; if (context->los_stack.stkp == context->los_stack.stkbot) { /* underflow */ if (!pop_segment( &context->los_stack )) return FALSE; } obj = *--context->los_stack.stkp; next = (int)*--context->los_stack.stkp; n = bytes2words( sizefield( *ptrof(obj) ) ); k = min( n-next, LARGE_OBJECT_LIMIT ); for ( i=0 ; i < k ; i++ ) PUSH( context, vector_ref( obj, i+next ) ); if (next+k < n) LOS_PUSH( context, next+k, obj ); return TRUE; }
static int push_constituents( msgc_context_t *context, word w ) { int i, n; switch (tagof(w)) { case PAIR_TAG : PUSH( context, pair_cdr( w ) ); /* Do the CDR last */ PUSH( context, pair_car( w ) ); /* Do the CAR first */ return 2; case VEC_TAG : case PROC_TAG : n = bytes2words( sizefield(*ptrof(w)) ); if (n > LARGE_OBJECT_LIMIT) LOS_PUSH( context, 0, w ); /* Treat large objects specially */ else for ( i=0 ; i < n ; i++ ) PUSH( context, vector_ref( w, i ) ); return n+1; default : return 0; } }
static int push_constituents( msgc_context_t *context, word w ) { int i, n; switch (tagof(w)) { case PAIR_TAG : return push_pair_constiuents( context, w ); case VEC_TAG : case PROC_TAG : assert2_tag_hdr_consistency( context, w ); n = bytes2words( sizefield(*ptrof(w)) ); if (n > LARGE_OBJECT_LIMIT) LOS_PUSH( context, 0, w ); /* Treat large objects specially */ else { assert2_object_contents_mapped( context, w, n ); for ( i=0 ; i < n ; i++ ) { PUSH( context, vector_ref( w, i ), w, i+1 ); } } return n+1; default : return 0; } }