fix codetest failure - trailing whitespace
[parrot.git] / src / pmc_freeze.c
blob53ebd52f240027ddef5bd4a6f63b65dc387d6f0f
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc_freeze.c - Freeze and thaw functionality
9 =head1 DESCRIPTION
11 Thawing PMCs uses a list with (maximum) size of the amount of PMCs to
12 keep track of retrieved PMCs.
14 The individual information of PMCs is frozen/thawed by their vtables.
16 To avoid recursion, the whole functionality is driven by
17 C<< pmc->vtable->visit >>, which is called for the first PMC initially.
18 Container PMCs call a "todo-callback" for all contained PMCs. The
19 individual action vtable (freeze/thaw) is then called for all todo-PMCs.
21 =cut
25 #include "parrot/parrot.h"
26 #include "pmc/pmc_callcontext.h"
27 #include "pmc_freeze.str"
29 /* when thawing a string longer then this size, we first do a GC run and then
30 * block GC - the system can't give us more headers */
32 #define THAW_BLOCK_GC_SIZE 100000
34 /* HEADERIZER HFILE: include/parrot/pmc_freeze.h */
38 =head2 Public Interface
40 =over 4
42 =item C<STRING* Parrot_freeze(PARROT_INTERP, PMC *pmc)>
44 Freeze using either method.
46 =cut
50 PARROT_EXPORT
51 PARROT_WARN_UNUSED_RESULT
52 PARROT_CAN_RETURN_NULL
53 STRING*
54 Parrot_freeze(PARROT_INTERP, ARGIN(PMC *pmc))
56 ASSERT_ARGS(Parrot_freeze)
57 PMC *image = Parrot_pmc_new(interp, enum_class_ImageIO);
58 VTABLE_set_pmc(interp, image, pmc);
59 return VTABLE_get_string(interp, image);
64 =item C<UINTVAL Parrot_freeze_size(PARROT_INTERP, PMC *pmc)>
66 Get the size of an image to be frozen without allocating a large buffer.
68 Used in C<Packfile_Constant_pack_size>.
70 =cut
74 PARROT_EXPORT
75 PARROT_WARN_UNUSED_RESULT
76 PARROT_CAN_RETURN_NULL
77 UINTVAL
78 Parrot_freeze_size(PARROT_INTERP, ARGIN(PMC *pmc))
80 ASSERT_ARGS(Parrot_freeze_size)
81 UINTVAL int_result;
82 PMC *pmc_result;
83 PMC *visitor = Parrot_pmc_new(interp, enum_class_ImageIOSize);
84 VTABLE_set_pmc(interp, visitor, pmc);
85 pmc_result = VTABLE_get_pmc(interp, visitor);
86 int_result = VTABLE_get_integer(interp, pmc_result);
87 return int_result;
93 =item C<PMC* Parrot_thaw(PARROT_INTERP, STRING *image)>
95 Thaws a PMC. Called from the C<thaw> opcode.
97 For now it seems cheaper to use a list for remembering contained
98 aggregates. We could of course decide dynamically, which strategy to
99 use, e.g.: given a big image, the first thawed item is a small
100 aggregate. This implies, it probably contains (or some big strings) more
101 nested containers, for which another approach could be a win.
103 =cut
107 PARROT_EXPORT
108 PARROT_WARN_UNUSED_RESULT
109 PARROT_CAN_RETURN_NULL
110 PMC*
111 Parrot_thaw(PARROT_INTERP, ARGIN(STRING *image))
113 ASSERT_ARGS(Parrot_thaw)
115 PMC *info = Parrot_pmc_new(interp, enum_class_ImageIO);
116 int gc_block = 0;
117 PMC *result;
120 * if we are thawing a lot of PMCs, it's cheaper to do
121 * a GC run first and then block GC - the limit should be
122 * chosen so that no more then one GC run would be triggered
124 * XXX
126 * md5_3.pir shows a segfault during thawing the config hash
127 * info->thaw_ptr becomes invalid - seems that the hash got
128 * collected under us.
130 if (1 || (Parrot_str_byte_length(interp, image) > THAW_BLOCK_GC_SIZE)) {
131 Parrot_block_GC_mark(interp);
132 Parrot_block_GC_sweep(interp);
133 gc_block = 1;
136 VTABLE_set_string_native(interp, info, image);
137 result = VTABLE_get_pmc(interp, info);
139 if (gc_block) {
140 Parrot_unblock_GC_mark(interp);
141 Parrot_unblock_GC_sweep(interp);
144 return result;
150 =item C<PMC* Parrot_thaw_constants(PARROT_INTERP, STRING *image)>
152 Thaws constants, used by PackFile for unpacking PMC constants.
153 This is a lie. It does nothing different from Parrot_thaw at the moment.
155 =cut
159 PARROT_EXPORT
160 PARROT_WARN_UNUSED_RESULT
161 PARROT_CAN_RETURN_NULL
162 PMC*
163 Parrot_thaw_constants(PARROT_INTERP, ARGIN(STRING *image))
165 ASSERT_ARGS(Parrot_thaw_constants)
166 return Parrot_thaw(interp, image);
172 =item C<PMC* Parrot_clone(PARROT_INTERP, PMC *pmc)>
174 There are for sure shortcuts to clone faster, e.g. always thaw the image
175 immediately or use a special callback. For now we just thaw a frozen PMC.
177 =cut
181 PARROT_EXPORT
182 PARROT_WARN_UNUSED_RESULT
183 PARROT_CAN_RETURN_NULL
184 PMC*
185 Parrot_clone(PARROT_INTERP, ARGIN(PMC *pmc))
187 ASSERT_ARGS(Parrot_clone)
188 return VTABLE_clone(interp, pmc);
193 =item C<void Parrot_visit_loop_visit(PARROT_INTERP, PMC *info)>
195 Iterate a visitor PMC visiting each encountered target PMC.
197 =cut
201 void
202 Parrot_visit_loop_visit(PARROT_INTERP, ARGIN(PMC *info)) {
203 ASSERT_ARGS(Parrot_visit_loop_visit)
205 INTVAL i;
206 PMC * const todo = VTABLE_get_iter(interp, info);
208 /* can't cache upper limit, visit may append items */
209 for (i = 0; i < VTABLE_elements(interp, todo); i++) {
210 PMC *current = VTABLE_get_pmc_keyed_int(interp, todo, i);
211 if (!current)
212 Parrot_ex_throw_from_c_args(interp, NULL, 1,
213 "NULL current PMC in visit_loop_todo_list");
215 PARROT_ASSERT(current->vtable);
217 VTABLE_visit(interp, current, info);
219 VISIT_PMC(interp, info, PMC_metadata(current));
225 =item C<void Parrot_visit_loop_thawfinish(PARROT_INTERP, PMC *info)>
227 Iterate a visitor PMC thawfinishing each encountered target PMC.
229 =cut
233 void
234 Parrot_visit_loop_thawfinish(PARROT_INTERP, ARGIN(PMC *info)) {
235 ASSERT_ARGS(Parrot_visit_loop_thawfinish)
237 /* call thawfinish for each processed PMC */
239 * Thaw in reverse order. We have to fully thaw younger PMCs
240 * before use them in older.
242 * XXX There are no younger or older pmcs in a directed graph
243 * that allows cycles. Any code that requires a specific
244 * order here is likely broken.
247 PMC * const todo = VTABLE_get_iter(interp, info);
248 const INTVAL n = VTABLE_elements(interp, todo);
249 int i;
251 for (i = n-1; i >= 0; --i) {
252 PMC *current = VTABLE_get_pmc_keyed_int(interp, todo, i);
253 if (!PMC_IS_NULL(current))
254 VTABLE_thawfinish(interp, current, info);
260 =back
262 =head1 TODO
264 The seen-hash version for freezing might go away sometime.
266 =head1 SEE ALSO
268 Lot of discussion on p6i and F<docs/dev/pmc_freeze.pod>.
270 =head1 HISTORY
272 Initial version by leo 2003.11.03 - 2003.11.07.
274 =cut
280 * Local variables:
281 * c-file-style: "parrot"
282 * End:
283 * vim: expandtab shiftwidth=4: