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