1 /*
2 Copyright (C) 2010-2012, Parrot Foundation.
3
4 =head1 NAME
5
6 src/pointer_array.c - Implementation Pointer Array storage.
7
8 =head1 DESCRIPTION
9
10 This compilation unit implements pointer array storage.
11
12 =cut
13
14 */
15
16 #include "parrot/parrot.h"
17 #include "parrot/pointer_array.h"
18
19
20 /* HEADERIZER HFILE: include/parrot/pointer_array.h */
21
22 /*
23
24 =over 4
25
26 =item C<Parrot_Pointer_Array * Parrot_pa_new(PARROT_INTERP)>
27
28 Allocate new Pointer_Array.
29
30 =cut
31
32 */
33
34 PARROT_EXPORT
35 PARROT_MALLOC
36 PARROT_CANNOT_RETURN_NULL
37 Parrot_Pointer_Array *
Parrot_pa_new(SHIM_INTERP)38 Parrot_pa_new(SHIM_INTERP)
39 {
40 ASSERT_ARGS(Parrot_pa_new)
41 Parrot_Pointer_Array * const res = mem_internal_allocate_zeroed_typed(Parrot_Pointer_Array);
42 return res;
43 }
44
45 /*
46
47 =item C<void Parrot_pa_destroy(PARROT_INTERP, Parrot_Pointer_Array *self)>
48
49 Destroy Pointer_Arra and free allocated memory.
50
51 =cut
52
53 */
54
55 PARROT_EXPORT
56 void
Parrot_pa_destroy(SHIM_INTERP,ARGFREE (Parrot_Pointer_Array * self))57 Parrot_pa_destroy(SHIM_INTERP, ARGFREE(Parrot_Pointer_Array *self))
58 {
59 ASSERT_ARGS(Parrot_pa_destroy)
60 size_t i;
61 for (i = 0; i < self->total_chunks; i++)
62 mem_sys_free(self->chunks[i]);
63 mem_sys_free(self->chunks);
64 mem_sys_free(self);
65 }
66
67 /*
68
69 =item C<size_t Parrot_pa_count_allocated(PARROT_INTERP, const
70 Parrot_Pointer_Array *self)>
71
72 Get count of allocated objects.
73
74 =cut
75
76 */
77 PARROT_WARN_UNUSED_RESULT
78 PARROT_PURE_FUNCTION
79 size_t
Parrot_pa_count_allocated(SHIM_INTERP,ARGIN (const Parrot_Pointer_Array * self))80 Parrot_pa_count_allocated(SHIM_INTERP, ARGIN(const Parrot_Pointer_Array *self))
81 {
82 ASSERT_ARGS(Parrot_pa_count_allocated)
83 return self->total_chunks * CELL_PER_CHUNK;
84 }
85
86 /*
87
88 =item C<size_t Parrot_pa_count_used(PARROT_INTERP, const Parrot_Pointer_Array
89 *self)>
90
91 Get count of allocated objects.
92
93 =cut
94
95 */
96 PARROT_WARN_UNUSED_RESULT
97 size_t
Parrot_pa_count_used(SHIM_INTERP,ARGIN (const Parrot_Pointer_Array * self))98 Parrot_pa_count_used(SHIM_INTERP, ARGIN(const Parrot_Pointer_Array *self))
99 {
100 ASSERT_ARGS(Parrot_pa_count_used)
101 size_t count = 0;
102 POINTER_ARRAY_ITER(self, count++;);
103 return count;
104 }
105
106
107 /*
108
109 =item C<int Parrot_pa_is_owned(const Parrot_Pointer_Array *self, const void
110 *orig, const void *ref)>
111
112 Check that C<orig> pointer is stored in C<ref> cell. Used during system stack t
113
114 =cut
115
116 */
117 PARROT_EXPORT
118 PARROT_WARN_UNUSED_RESULT
119 int
Parrot_pa_is_owned(ARGIN (const Parrot_Pointer_Array * self),ARGIN (const void * orig),ARGIN_NULLOK (const void * ref))120 Parrot_pa_is_owned(ARGIN(const Parrot_Pointer_Array *self),
121 ARGIN(const void *orig), ARGIN_NULLOK(const void *ref))
122 {
123 ASSERT_ARGS(Parrot_pa_is_owned)
124 size_t i;
125
126 /* Return early if ref is null */
127 if (!ref)
128 return 0;
129
130 /* We can't just deref pointer. It can be garbage */
131 /* So, ensure that C<ref> is looks like real pointer */
132 for (i = 0; i < self->total_chunks; i++) {
133 const Parrot_Pointer_Array_Chunk * const chunk = self->chunks[i];
134 if (PTR2UINTVAL(ref) < PTR2UINTVAL(chunk->data))
135 continue;
136 if (PTR2UINTVAL(ref) > PTR2UINTVAL(chunk) + CHUNK_SIZE)
137 continue;
138 return (*(void * const *)ref == orig);
139 }
140
141 return 0;
142 }
143
144 /*
145
146 =back
147
148 =head1 SEE ALSO
149
150 F<include/parrot/pointer_array.h>
151
152 =cut
153
154 */
155
156 /*
157 * Local variables:
158 * c-file-style: "parrot"
159 * End:
160 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
161 */
162