/
cpu_dep.c
141 lines (95 loc) · 2.57 KB
/
cpu_dep.c
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
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
$Id$
=head1 NAME
src/cpu_dep.c - CPU-dependent functions
=head1 DESCRIPTION
These functions are called while stackwalking during dead object
destruction. They implement conditional CPU-specific behaviour related
to register windowing.
Register windowing is a technique which avoids having to empty registers
by moving a virtual window up/down the register stack restricting the
number of registers which are visible.
Remember you read something about it in F<docs/infant.dev>?
=head2 Functions
=over 4
=cut
*/
#include "parrot/parrot.h"
#ifdef __ia64__
# include <ucontext.h>
extern void *flush_reg_store(void);
# define BACKING_STORE_BASE 0x80000fff80000000
#endif
static void trace_system_stack(Interp *interpreter);
/*
=item C<void trace_system_areas(Interp *interpreter)>
Traces the system stack and any additional CPU-specific areas.
=cut
*/
void
trace_system_areas(Interp *interpreter)
{
#if defined(__sparc) /* Flush register windows */
static union {
unsigned int insns[4];
double align_hack[2];
} u = { {
# ifdef __sparcv9
0x81580000, /* flushw */
# else
0x91d02003, /* ta ST_FLUSH_WINDOWS */
# endif
0x81c3e008, /* retl */
0x01000000 /* nop */
} };
static void (*fn_ptr)(void) = (void (*)(void))&u.align_hack[0];
fn_ptr();
#elif defined(__ia64__)
struct ucontext ucp;
void *current_regstore_top;
getcontext(&ucp);
current_regstore_top = flush_reg_store();
trace_mem_block(interpreter, 0x80000fff80000000,
(size_t)current_regstore_top);
#else
# ifdef PARROT_HAS_HEADER_SETJMP
Parrot_jump_buff env;
/* Zero the Parrot_jump_buff, otherwise you will trace stale objects */
memset(&env, 0, sizeof(env));
/* this should put registers in env, which then get marked in
* trace_system_stack below
*/
setjmp(env);
# endif
#endif
trace_system_stack(interpreter);
}
/*
=item C<static void
trace_system_stack(Interp *interpreter)>
Traces the memory block starting at C<< interpreter->lo_var_ptr >>.
=cut
*/
static void
trace_system_stack(Interp *interpreter)
{
size_t lo_var_ptr = (size_t)interpreter->lo_var_ptr;
trace_mem_block(interpreter, (size_t)lo_var_ptr,
(size_t)&lo_var_ptr);
}
/*
=back
=head1 SEE ALSO
F<src/dod.c>, F<include/parrot/dod.h> and F<docs/infant.dev>.
=cut
*/
/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: expandtab shiftwidth=4:
*/