#1872: t/pmc/fixedstringarray.t fails coretest 64 bit with g++-4.5
--------------------+-------------------------------------------------------
Reporter: mikehh | Owner: bacek
Type: bug | Status: new
Priority: normal | Milestone: 2.11
Component: core | Version: master
Severity: medium | Keywords: Segmentation Fault
Lang: | Patch:
Platform: linux |
--------------------+-------------------------------------------------------
Comment(by bacek):
Hello.
Fix for this bug (and #1871) is something like this:
{{{
diff --git a/include/parrot/pointer_array.h
b/include/parrot/pointer_array.h
index 7c0277f..35be87a 100644
--- a/include/parrot/pointer_array.h
+++ b/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_CHE
diff --git a/src/gc/gc_ms2.c b/src/gc/gc_ms2.c
index 90d7952..b651ee7 100644
--- a/src/gc/gc_ms2.c
+++ b/src/gc/gc_ms2.c
@@ -638,6 +638,7 @@ Parrot_gc_ms2_init(PARROT_INTERP)
self->fixed_size_allocator =
Parrot_gc_fixed_allocator_new(interp);
self->gc_threshold = Parrot_sysmem_amount(interp) / 8;
+ //self->gc_threshold = 1024 * 1024;
}
interp->gc_sys->gc_private = self;
@@ -1242,7 +1243,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;
}
diff --git a/src/pointer_array.c b/src/pointer_array.c
index 811ec97..2f5096f 100644
--- a/src/pointer_array.c
+++ b/src/pointer_array.c
@@ -147,6 +147,42 @@ Parrot_pa_remove(PARROT_INTERP,
ARGIN(Parrot_Pointer_Array
/*
+=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;
+
diff --git a/include/parrot/pointer_array.h
b/include/parrot/pointer_array.h
index 7c0277f..35be87a 100644
--- a/include/parrot/pointer_array.h
+++ b/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)
~/src/parrot (master)$ git diff > fix.patch
~/src/parrot (master)$ git diff
diff --git a/include/parrot/pointer_array.h
b/include/parrot/pointer_array.h
index 7c0277f..35be87a 100644
--- a/include/parrot/pointer_array.h
+++ b/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_CHE
diff --git a/src/gc/gc_ms2.c b/src/gc/gc_ms2.c
index 90d7952..b651ee7 100644
--- a/src/gc/gc_ms2.c
+++ b/src/gc/gc_ms2.c
@@ -638,6 +638,7 @@ Parrot_gc_ms2_init(PARROT_INTERP)
self->fixed_size_allocator =
Parrot_gc_fixed_allocator_new(interp);
self->gc_threshold = Parrot_sysmem_amount(interp) / 8;
+ //self->gc_threshold = 1024 * 1024;
}
interp->gc_sys->gc_private = self;
@@ -1242,7 +1243,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;
}
diff --git a/src/pointer_array.c b/src/pointer_array.c
index 811ec97..2f5096f 100644
--- a/src/pointer_array.c
+++ b/src/pointer_array.c
@@ -147,6 +147,42 @@ Parrot_pa_remove(PARROT_INTERP,
ARGIN(Parrot_Pointer_Array
/*
+=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)>
}}}
Unfortunatelly I will not have time to test and finish it till next week.
If someone can finish patch it will be very helpful.
--
Bacek
--
Ticket URL: <https://trac.parrot.org/parrot/ticket/1872#comment:8>
Parrot <https://trac.parrot.org/parrot/>
Parrot Development
_______________________________________________
parrot-tickets mailing list
[email protected]
http://lists.parrot.org/mailman/listinfo/parrot-tickets