File: stakcach.c

package info (click to toggle)
rscheme 0.7.2-1.1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 10,672 kB
  • ctags: 12,430
  • sloc: lisp: 37,104; ansic: 29,763; cpp: 2,630; sh: 1,677; makefile: 568; yacc: 202; lex: 175; perl: 33
file content (164 lines) | stat: -rw-r--r-- 3,822 bytes parent folder | download | duplicates (4)
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
/*-----------------------------------------------------------------*-C-*---
 * File:    handc/runtime/stakcach.c
 *
 *          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.8
 * File mod date:    1997.11.29 23:10:49
 * System build:     v0.7.2, 97.12.21
 *
 * Purpose:          stack-cache stack implementation
 *------------------------------------------------------------------------*/

#include <rscheme/vinsns.h>
#include <rscheme/scheme.h>

#ifdef STACK_CACHE

obj the_stack_cache[CACHE_SIZE];
obj *cache_iteration;

#ifndef INLINES
#include "stakcach.ci"
#endif /* INLINES */

void init_stack_cache( void )
{
}

/*  FLUSH_STACK_CACHE() -- Does the obvious thing, which is flush the stack
    cache.  In effect, it guarantees that the current continuation
    is a REAL object, flushing the cache sufficiently to ensure the
    truth of this.
*/

void flush_stack_cache( void )
{
UINT_32 cr = VAL(continuation_reg);
#define x  ((obj *)(cr-POINTER_TAG))
obj n, prev, next, first;
rs_bool more;
UINT_32 i, size_in_bytes;

    if (!in_stack_cache(continuation_reg))
	return; /* nothing to do... already a real object */

#ifdef STEP_DUMP
    {
    extern FILE *step_dump_file;
    extern int do_step_dump;
    extern void touch_step_dump_file( void );
    
	if (do_step_dump && step_dump_file)
	{
	    touch_step_dump_file();
	    fprintf( step_dump_file, "** Flushing stack cache **\n" );
	}
    }
#endif /* STEP_DUMP */

    more = YES;
    prev = ZERO;
    first = ZERO;	/* suppress warning */
    do {
	next = x[3];
	if (in_stack_cache(next))
	{
	    size_in_bytes = VAL(next) - cr;
	}
	else
	{
	    size_in_bytes = cache_upper_limit - cr;
	    more = NO;
	}
	n = alloc( size_in_bytes, partcont_class );
	if (EQ(prev,ZERO))
	    first = n;
	else
	  {
	    /* it's not obvious, but this *is* an initializing write,
	       because we only fill in SLOT(3) of an allocated
	       <part-cont> here or outside of the loop 
	       */
	    gvec_write_init_ptr( prev, SLOT(3), n );
	  }
	gvec_write_init( n, SLOT(0), x[0] );   /* saved envt_reg */
	gvec_write_init( n, SLOT(1), x[1] );   /* saved literals_reg */
	gvec_write_init( n, SLOT(2), x[2] );   /* saved jump_addr */
	for (i=SLOT(4); i<size_in_bytes; i+=SLOT(1))
	{
	    gvec_write_init( n, i, *(obj *)(i+(char *)x) );
	}
	prev = n;
	cr = VAL(next);
    } while (more);
    gvec_write_init( n, SLOT(3), next );

    continuation_reg = first;
#undef x
}



/*
    Restores a dynamically-determined number of
    argument-passing registers (ie, for use in the
    extremely rare cases when it cannot be determined
    statically -- nb, this only happens when compiling
    to closure-threaded code) and the continuation
    register itself
*/

unsigned restore_arb( void )
{
#define x ((obj *)(cr - POINTER_TAG))
UINT_32 cr = VAL(continuation_reg), size_in_bytes, next;
unsigned n;

    if (cr < cache_upper_limit && cr >= cache_lower_limit)
    {
	next = VAL(x[3]);
	if (next < cache_upper_limit && next >= cache_lower_limit)
	{
	    size_in_bytes = next - cr;
	}
	else
	{
	    size_in_bytes = cache_upper_limit - cr;
	}
    }
    else
	size_in_bytes = SIZEOF_PTR(continuation_reg);

    n  = (size_in_bytes / sizeof(obj)) - CONT_FIXED;
    restore_cont( n );
    return n;
#undef x
}

int process_stack_roots( process_root_fn *fn, void *info )
{
obj *p;
obj item, *stop;
UINT_32 cr = VAL(continuation_reg);
int rc;

    p = (obj *)(cache_upper_limit - POINTER_TAG);

    if (!in_stack_cache(continuation_reg))
	return 0;

    stop = (obj *)(cr - POINTER_TAG);

    while (p > stop)
    {
      rc = fn( --p, info );
      if (rc)
	return rc;
    }
    return 0;
}

#endif /* STACK_CACHE */