1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
/*-----------------------------------------------------------------*-C-*---
* File: handc/runtime/readwrit.ci
*
* Copyright (C)1997 Donovan Kolbly <d.kolbly@rscheme.org>
* as part of the RScheme project, licensed for free use.
* See <http://www.rscheme.org/> for the latest information.
*
* File version: 1.9
* File mod date: 1997.11.29 23:10:53
* System build: v0.7.2, 97.12.21
*
*------------------------------------------------------------------------*/
#include <rscheme/gcserver.h>
/******************** Memory Read Functions ********************/
#ifdef DEBUG_SMEMORY
CI_DECL obj gvec_read( obj gvec, UINT_32 byte_offset )
{
obj item;
#ifdef VALIDATE_BLOCKS
validate_block( PTR_TO_GCPTR(gvec) );
#endif
assert( (byte_offset & 3) == 0 );
assert( byte_offset < SIZEOF_PTR(gvec) );
item = *(obj *)(((char *)PTR_TO_DATAPTR(gvec)) + byte_offset);
/* if there is a read barrier, we need to apply it to the
* extracted value, since it may be the first time this value
* gets into the root set
*/
return READ_BARRIER(item);
}
#endif
CI_DECL UINT_8 bvec_read_uint8( obj bvec, UINT_32 byte_offset )
{
#ifdef VALIDATE_BLOCKS
validate_block( PTR_TO_GCPTR(bvec) );
#endif
assert( byte_offset < SIZEOF_PTR(bvec) );
return ((UINT_8 *)PTR_TO_DATAPTR(bvec))[byte_offset];
}
/******************** Memory Write Functions ********************/
CI_DECL void gvec_write( obj gvec, UINT_32 byte_offset, obj value )
{
obj *dest = (obj *)(((char *)PTR_TO_DATAPTR(gvec)) + byte_offset);
assert( !EQ(*dest,DEBUG_TRAP_OBJ) );
if (OBJ_ISA_PTR(value))
{
write_barrier( PTR_TO_GCPTR(gvec), dest, PTR_TO_GCPTR(value) );
}
else
{
write_barrier_lval_clobber( PTR_TO_GCPTR(gvec), dest );
}
assert( (byte_offset & 3) == 0 );
assert( byte_offset < SIZEOF_PTR(gvec) );
*dest = value;
}
CI_DECL void gvec_write_ptr( obj gvec, UINT_32 byte_offset, obj value )
{
assert( OBJ_ISA_PTR(value) );
gvec_write( gvec, byte_offset, value );
}
CI_DECL void gvec_write_non_ptr( obj gvec, UINT_32 byte_offset, obj value )
{
obj *dest = (obj *)(((char *)PTR_TO_DATAPTR(gvec)) + byte_offset);
assert( !OBJ_ISA_PTR(value) );
assert( (byte_offset & 3) == 0 );
assert( byte_offset < SIZEOF_PTR(gvec) );
write_barrier_lval_clobber( PTR_TO_GCPTR(gvec), dest );
*dest = value;
}
/* an object is FRESH from the time it is allocated to
the next GC_SAFE_POINT. This is extraordinarily useful
if you are allocating white, in which case the write
barrier becomes a NOP
*/
CI_DECL void gvec_write_fresh( obj gvec, UINT_32 byte_offset, obj value )
{
obj *dest = (obj *)(((char *)PTR_TO_DATAPTR(gvec)) + byte_offset);
assert( !EQ(*dest,DEBUG_TRAP_OBJ) );
if (OBJ_ISA_PTR(value))
{
write_barrier_lval_fresh( PTR_TO_GCPTR(gvec),
dest,
PTR_TO_GCPTR(value) );
}
assert( (byte_offset & 3) == 0 );
assert( byte_offset < SIZEOF_PTR(gvec) );
*dest = value;
}
/* an initializing write is the first write to that slot
of the target object.
!!! The gvec is necessarily FRESH, because a gvec MUST
!!! be fully initialized before the next gc safe point
*/
CI_DECL void gvec_write_init( obj gvec, UINT_32 byte_offset, obj value )
{
obj *dest = (obj *)(((char *)PTR_TO_DATAPTR(gvec)) + byte_offset);
assert( EQ(*dest,DEBUG_TRAP_OBJ) );
if (OBJ_ISA_PTR(value))
{
write_barrier_lval_init(PTR_TO_GCPTR(gvec),dest,PTR_TO_GCPTR(value));
}
assert( (byte_offset & 3) == 0 );
assert( byte_offset < SIZEOF_PTR(gvec) );
*dest = value;
}
CI_DECL void gvec_write_fresh_ptr( obj gvec, UINT_32 byte_offset, obj value )
{
assert( OBJ_ISA_PTR(value) );
gvec_write_fresh( gvec, byte_offset, value );
}
CI_DECL void gvec_write_fresh_non_ptr( obj gvec, UINT_32 byte_offset, obj value )
{
assert( !OBJ_ISA_PTR(value) );
gvec_write_fresh( gvec, byte_offset, value );
}
CI_DECL void gvec_write_init_ptr( obj gvec, UINT_32 byte_offset, obj value )
{
assert( OBJ_ISA_PTR(value) );
gvec_write_init( gvec, byte_offset, value );
}
CI_DECL void gvec_write_init_non_ptr( obj gvec, UINT_32 byte_offset, obj value )
{
assert( !OBJ_ISA_PTR(value) );
gvec_write_init( gvec, byte_offset, value );
}
/* Allocate a gvec filled with FALSE_OBJ's */
CI_DECL obj gvec_alloc( UINT_32 len, obj obj_class )
{
UINT_32 i;
obj thing;
thing = alloc( sizeof(obj) * len, obj_class );
for (i=0; i<len; i++)
gvec_write_init_non_ptr( thing, SLOT(i), FALSE_OBJ );
return thing;
}
|