-
Notifications
You must be signed in to change notification settings - Fork 138
/
pointer_array.c
158 lines (111 loc) · 2.83 KB
/
pointer_array.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
Copyright (C) 2010-2011, Parrot Foundation.
=head1 NAME
src/pointer_array.c - Implementation Pointer Array storage.
=head1 DESCRIPTION
=cut
*/
#include "parrot/parrot.h"
#include "parrot/pointer_array.h"
/* HEADERIZER HFILE: include/parrot/pointer_array.h */
/*
=over 4
=item C<Parrot_Pointer_Array * Parrot_pa_new(PARROT_INTERP)>
Allocate new Pointer_Array.
=cut
*/
PARROT_EXPORT
PARROT_MALLOC
PARROT_CANNOT_RETURN_NULL
Parrot_Pointer_Array *
Parrot_pa_new(PARROT_INTERP)
{
ASSERT_ARGS(Parrot_pa_new)
Parrot_Pointer_Array * const res = mem_allocate_zeroed_typed(Parrot_Pointer_Array);
return res;
}
/*
=item C<void Parrot_pa_destroy(PARROT_INTERP, Parrot_Pointer_Array *self)>
Destroy Pointer_Arra and free allocated memory.
=cut
*/
PARROT_EXPORT
void
Parrot_pa_destroy(PARROT_INTERP, ARGFREE(Parrot_Pointer_Array *self))
{
ASSERT_ARGS(Parrot_pa_destroy)
size_t i;
for (i = 0; i < self->total_chunks; i++)
mem_sys_free(self->chunks[i]);
mem_sys_free(self->chunks);
mem_sys_free(self);
}
/*
=item C<size_t Parrot_pa_count_allocated(PARROT_INTERP, const
Parrot_Pointer_Array *self)>
Get count of allocated objects.
=cut
*/
PARROT_WARN_UNUSED_RESULT
PARROT_PURE_FUNCTION
size_t
Parrot_pa_count_allocated(PARROT_INTERP, ARGIN(const Parrot_Pointer_Array *self))
{
ASSERT_ARGS(Parrot_pa_count_allocated)
return self->total_chunks * CELL_PER_CHUNK;
}
/*
=item C<size_t Parrot_pa_count_used(PARROT_INTERP, const Parrot_Pointer_Array
*self)>
Get count of allocated objects.
=cut
*/
PARROT_WARN_UNUSED_RESULT
size_t
Parrot_pa_count_used(PARROT_INTERP, ARGIN(const Parrot_Pointer_Array *self))
{
ASSERT_ARGS(Parrot_pa_count_used)
size_t count = 0;
POINTER_ARRAY_ITER(self, count++;);
return count;
}
/*
=item C<int Parrot_pa_is_owned(PARROT_INTERP, Parrot_Pointer_Array *self, void
*orig, void *ref)>
Check that C<orig> pointer is stored in C<ref> cell. Used during system stack t
=cut
*/
PARROT_EXPORT
int
Parrot_pa_is_owned(PARROT_INTERP, ARGIN(Parrot_Pointer_Array *self),
ARGIN(void *orig), ARGIN_NULLOK(void *ref))
{
ASSERT_ARGS(Parrot_pa_is_owned)
size_t i;
/* Return early if ref is null */
if (!ref)
return 0;
/* We can't just deref pointer. It can be garbage */
/* So, ensure that C<ref> is looks like real pointer */
for (i = 0; i < self->total_chunks; i++) {
const Parrot_Pointer_Array_Chunk * const chunk = self->chunks[i];
if (PTR2UINTVAL(ref) < PTR2UINTVAL(chunk->data))
continue;
if (PTR2UINTVAL(ref) > PTR2UINTVAL(chunk) + CHUNK_SIZE)
continue;
return (*(void **)ref == orig);
}
return 0;
}
/*
=back
=head1 SEE ALSO
F<include/parrot/pointer_array.h>
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/