2 * Copyright (C) 2008 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
24 #include "swfdec_as_gcable.h"
26 #include "swfdec_as_context.h"
29 swfdec_as_gcable_alloc (SwfdecAsContext
*context
, gsize size
)
34 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
35 g_return_val_if_fail (size
> sizeof (SwfdecAsGcable
), NULL
);
37 swfdec_as_context_use_mem (context
, size
);
38 mem
= g_slice_alloc0 (size
);
39 if (G_LIKELY ((GPOINTER_TO_SIZE (mem
) & SWFDEC_AS_GC_FLAG_MASK
) == 0))
42 g_slice_free1 (size
, mem
);
43 mem
= g_slice_alloc0 (size
+ SWFDEC_AS_GC_FLAG_MASK
);
44 diff
= GPOINTER_TO_SIZE (mem
) & SWFDEC_AS_GC_FLAG_MASK
;
48 diff
= SWFDEC_AS_GC_FLAG_MASK
+ 1 - diff
;
50 g_assert ((GPOINTER_TO_SIZE (mem
) & SWFDEC_AS_GC_FLAG_MASK
) == 0);
51 SWFDEC_AS_GCABLE_SET_FLAG (mem
, SWFDEC_AS_GC_ALIGN
);
52 ((guint8
*) mem
)[-1] = diff
;
58 swfdec_as_gcable_free (SwfdecAsContext
*context
, gpointer mem
, gsize size
)
62 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context
));
63 g_return_if_fail (mem
!= NULL
);
64 g_return_if_fail (size
> sizeof (SwfdecAsGcable
));
67 swfdec_as_context_unuse_mem (context
, size
);
68 if (G_UNLIKELY (SWFDEC_AS_GCABLE_FLAG_IS_SET (gc
, SWFDEC_AS_GC_ALIGN
))) {
69 mem
= ((guint8
*) mem
) - ((guint8
*) mem
)[-1];
70 size
+= SWFDEC_AS_GC_FLAG_MASK
;
72 g_slice_free1 (size
, mem
);
76 swfdec_as_gcable_collect (SwfdecAsContext
*context
, SwfdecAsGcable
*gc
,
77 SwfdecAsGcableDestroyNotify notify
)
79 SwfdecAsGcable
*prev
, *cur
, *tmp
;
81 g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context
), NULL
);
87 if (SWFDEC_AS_GCABLE_FLAG_IS_SET (cur
, SWFDEC_AS_GC_MARK
| SWFDEC_AS_GC_ROOT
)) {
88 if (SWFDEC_AS_GCABLE_FLAG_IS_SET (cur
, SWFDEC_AS_GC_MARK
))
89 SWFDEC_AS_GCABLE_UNSET_FLAG (cur
, SWFDEC_AS_GC_MARK
);
92 tmp
= SWFDEC_AS_GCABLE_NEXT (cur
);
93 notify (context
, cur
);
97 SWFDEC_AS_GCABLE_SET_NEXT (prev
, cur
);
103 cur
= SWFDEC_AS_GCABLE_NEXT (cur
);