Skip to content
Browse files

add patch (modified) from bacek++ to fix TT #1872

  • Loading branch information...
1 parent 61d023e commit a34696c8d8b895e5ffd9b24473e5aa8025bfa098 @mikehh mikehh committed Nov 26, 2010
Showing with 56 additions and 2 deletions.
  1. +15 −1 include/parrot/pointer_array.h
  2. +5 −1 src/gc/gc_ms2.c
  3. +36 −0 src/pointer_array.c
View
16 include/parrot/pointer_array.h
@@ -20,7 +20,8 @@ Lower bit in cell masked to indicate pointer-to-free-cell.
#define PARROT_POINTER_ARRAY_H_GUARD
/* Calculate size of chunk data "header" */
-#define CELL_PER_CHUNK ((4096 - 2 * sizeof(size_t) / sizeof (void *)))
+#define CHUNK_SIZE 4096
+#define CELL_PER_CHUNK ((CHUNK_SIZE - 2 * sizeof(size_t) / sizeof (void *)))
typedef struct Parrot_Pointer_Array_Chunk {
size_t num_free;
@@ -76,6 +77,15 @@ void * Parrot_pa_insert(PARROT_INTERP,
__attribute__nonnull__(3);
PARROT_EXPORT
+int Parrot_pa_is_owned(PARROT_INTERP,
+ ARGIN(Parrot_Pointer_Array *self),
+ ARGIN(void *orig),
+ ARGIN_NULLOK(void *ref))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ __attribute__nonnull__(3);
+
+PARROT_EXPORT
PARROT_CANNOT_RETURN_NULL
Parrot_Pointer_Array * Parrot_pa_new(PARROT_INTERP)
__attribute__nonnull__(1);
@@ -95,6 +105,10 @@ void Parrot_pa_remove(PARROT_INTERP,
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(self) \
, PARROT_ASSERT_ARG(ptr))
+#define ASSERT_ARGS_Parrot_pa_is_owned __attribute__unused__ int _ASSERT_ARGS_C = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(self) \
+ , PARROT_ASSERT_ARG(orig))
#define ASSERT_ARGS_Parrot_pa_new __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_pa_remove __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
View
6 src/gc/gc_ms2.c
@@ -1242,7 +1242,11 @@ gc_ms2_is_ptr_owned(PARROT_INTERP, ARGIN_NULLOK(void *ptr),
if (PObj_is_live_or_free_TESTALL(obj))
return 0;
- return 1;
+ /* Pool.is_owned isn't precise enough (yet) */
+ if (Parrot_pa_is_owned(interp, self->objects, item, item->ptr))
+ return 1;
+
+ return 0;
}
View
36 src/pointer_array.c
@@ -147,6 +147,42 @@ Parrot_pa_remove(PARROT_INTERP, ARGIN(Parrot_Pointer_Array *self), ARGIN(void *p
/*
+=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++) {
+ Parrot_Pointer_Array_Chunk *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;
+}
+
+/*
+
=item C<static void allocate_more_chunks(PARROT_INTERP, Parrot_Pointer_Array
*self)>

0 comments on commit a34696c

Please sign in to comment.
Something went wrong with that request. Please try again.