Commit d57210bc authored by Tim Peters's avatar Tim Peters

SF bug [#467145] Python 2.2a4 build problem on HPUX 11.0.

The platform requires 8-byte alignment for doubles, but the GC header
was 12 bytes and that threw off the natural alignment of the double
members of a subtype of complex.  The fix puts the GC header into a
union with a double as the other member, to force no-looser-than
double alignment of GC headers.  On boxes that require 8-byte alignment
for doubles, this may add pad bytes to the GC header accordingly; ditto
for platforms that *prefer* 8-byte alignment for doubles.  On platforms
that don't care, it shouldn't change the memory layout (because the
size of the old GC header is certainly greater than the size of a double
on all platforms, so unioning with a double shouldn't change size or
alignment on such boxes).
parent 580f6057
...@@ -266,10 +266,13 @@ extern DL_IMPORT(void) _PyObject_GC_UnTrack(PyObject *); ...@@ -266,10 +266,13 @@ extern DL_IMPORT(void) _PyObject_GC_UnTrack(PyObject *);
#ifdef WITH_CYCLE_GC #ifdef WITH_CYCLE_GC
/* GC information is stored BEFORE the object structure */ /* GC information is stored BEFORE the object structure */
typedef struct _gc_head { typedef union _gc_head {
struct _gc_head *gc_next; /* not NULL if object is tracked */ struct {
struct _gc_head *gc_prev; union _gc_head *gc_next; /* not NULL if object is tracked */
int gc_refs; union _gc_head *gc_prev;
int gc_refs;
} gc;
double dummy; /* force worst-case alignment */
} PyGC_Head; } PyGC_Head;
extern PyGC_Head _PyGC_generation0; extern PyGC_Head _PyGC_generation0;
...@@ -278,20 +281,20 @@ extern PyGC_Head _PyGC_generation0; ...@@ -278,20 +281,20 @@ extern PyGC_Head _PyGC_generation0;
* collector it must be safe to call the ob_traverse method. */ * collector it must be safe to call the ob_traverse method. */
#define _PyObject_GC_TRACK(o) do { \ #define _PyObject_GC_TRACK(o) do { \
PyGC_Head *g = (PyGC_Head *)(o)-1; \ PyGC_Head *g = (PyGC_Head *)(o)-1; \
if (g->gc_next != NULL) \ if (g->gc.gc_next != NULL) \
Py_FatalError("GC object already in linked list"); \ Py_FatalError("GC object already in linked list"); \
g->gc_next = &_PyGC_generation0; \ g->gc.gc_next = &_PyGC_generation0; \
g->gc_prev = _PyGC_generation0.gc_prev; \ g->gc.gc_prev = _PyGC_generation0.gc.gc_prev; \
g->gc_prev->gc_next = g; \ g->gc.gc_prev->gc.gc_next = g; \
_PyGC_generation0.gc_prev = g; \ _PyGC_generation0.gc.gc_prev = g; \
} while (0); } while (0);
/* Tell the GC to stop tracking this object. */ /* Tell the GC to stop tracking this object. */
#define _PyObject_GC_UNTRACK(o) do { \ #define _PyObject_GC_UNTRACK(o) do { \
PyGC_Head *g = (PyGC_Head *)(o)-1; \ PyGC_Head *g = (PyGC_Head *)(o)-1; \
g->gc_prev->gc_next = g->gc_next; \ g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \
g->gc_next->gc_prev = g->gc_prev; \ g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \
g->gc_next = NULL; \ g->gc.gc_next = NULL; \
} while (0); } while (0);
#define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op) #define PyObject_GC_Track(op) _PyObject_GC_Track((PyObject *)op)
......
...@@ -77,39 +77,39 @@ static PyObject *gc_str; ...@@ -77,39 +77,39 @@ static PyObject *gc_str;
static void static void
gc_list_init(PyGC_Head *list) gc_list_init(PyGC_Head *list)
{ {
list->gc_prev = list; list->gc.gc_prev = list;
list->gc_next = list; list->gc.gc_next = list;
} }
static void static void
gc_list_append(PyGC_Head *node, PyGC_Head *list) gc_list_append(PyGC_Head *node, PyGC_Head *list)
{ {
node->gc_next = list; node->gc.gc_next = list;
node->gc_prev = list->gc_prev; node->gc.gc_prev = list->gc.gc_prev;
node->gc_prev->gc_next = node; node->gc.gc_prev->gc.gc_next = node;
list->gc_prev = node; list->gc.gc_prev = node;
} }
static void static void
gc_list_remove(PyGC_Head *node) gc_list_remove(PyGC_Head *node)
{ {
node->gc_prev->gc_next = node->gc_next; node->gc.gc_prev->gc.gc_next = node->gc.gc_next;
node->gc_next->gc_prev = node->gc_prev; node->gc.gc_next->gc.gc_prev = node->gc.gc_prev;
node->gc_next = NULL; /* object is not currently tracked */ node->gc.gc_next = NULL; /* object is not currently tracked */
} }
static void static void
gc_list_move(PyGC_Head *from, PyGC_Head *to) gc_list_move(PyGC_Head *from, PyGC_Head *to)
{ {
if (from->gc_next == from) { if (from->gc.gc_next == from) {
/* empty from list */ /* empty from list */
gc_list_init(to); gc_list_init(to);
} }
else { else {
to->gc_next = from->gc_next; to->gc.gc_next = from->gc.gc_next;
to->gc_next->gc_prev = to; to->gc.gc_next->gc.gc_prev = to;
to->gc_prev = from->gc_prev; to->gc.gc_prev = from->gc.gc_prev;
to->gc_prev->gc_next = to; to->gc.gc_prev->gc.gc_next = to;
} }
gc_list_init(from); gc_list_init(from);
} }
...@@ -119,12 +119,12 @@ static void ...@@ -119,12 +119,12 @@ static void
gc_list_merge(PyGC_Head *from, PyGC_Head *to) gc_list_merge(PyGC_Head *from, PyGC_Head *to)
{ {
PyGC_Head *tail; PyGC_Head *tail;
if (from->gc_next != from) { if (from->gc.gc_next != from) {
tail = to->gc_prev; tail = to->gc.gc_prev;
tail->gc_next = from->gc_next; tail->gc.gc_next = from->gc.gc_next;
tail->gc_next->gc_prev = tail; tail->gc.gc_next->gc.gc_prev = tail;
to->gc_prev = from->gc_prev; to->gc.gc_prev = from->gc.gc_prev;
to->gc_prev->gc_next = to; to->gc.gc_prev->gc.gc_next = to;
} }
gc_list_init(from); gc_list_init(from);
} }
...@@ -134,7 +134,7 @@ gc_list_size(PyGC_Head *list) ...@@ -134,7 +134,7 @@ gc_list_size(PyGC_Head *list)
{ {
PyGC_Head *gc; PyGC_Head *gc;
long n = 0; long n = 0;
for (gc = list->gc_next; gc != list; gc = gc->gc_next) { for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
n++; n++;
} }
return n; return n;
...@@ -148,9 +148,9 @@ gc_list_size(PyGC_Head *list) ...@@ -148,9 +148,9 @@ gc_list_size(PyGC_Head *list)
static void static void
update_refs(PyGC_Head *containers) update_refs(PyGC_Head *containers)
{ {
PyGC_Head *gc = containers->gc_next; PyGC_Head *gc = containers->gc.gc_next;
for (; gc != containers; gc=gc->gc_next) { for (; gc != containers; gc=gc->gc.gc_next) {
gc->gc_refs = FROM_GC(gc)->ob_refcnt; gc->gc.gc_refs = FROM_GC(gc)->ob_refcnt;
} }
} }
...@@ -159,8 +159,8 @@ visit_decref(PyObject *op, void *data) ...@@ -159,8 +159,8 @@ visit_decref(PyObject *op, void *data)
{ {
if (op && PyObject_IS_GC(op)) { if (op && PyObject_IS_GC(op)) {
PyGC_Head *gc = AS_GC(op); PyGC_Head *gc = AS_GC(op);
if (gc->gc_next != NULL) if (gc->gc.gc_next != NULL)
AS_GC(op)->gc_refs--; AS_GC(op)->gc.gc_refs--;
} }
return 0; return 0;
} }
...@@ -170,8 +170,8 @@ static void ...@@ -170,8 +170,8 @@ static void
subtract_refs(PyGC_Head *containers) subtract_refs(PyGC_Head *containers)
{ {
traverseproc traverse; traverseproc traverse;
PyGC_Head *gc = containers->gc_next; PyGC_Head *gc = containers->gc.gc_next;
for (; gc != containers; gc=gc->gc_next) { for (; gc != containers; gc=gc->gc.gc_next) {
traverse = FROM_GC(gc)->ob_type->tp_traverse; traverse = FROM_GC(gc)->ob_type->tp_traverse;
(void) traverse(FROM_GC(gc), (void) traverse(FROM_GC(gc),
(visitproc)visit_decref, (visitproc)visit_decref,
...@@ -184,13 +184,13 @@ static void ...@@ -184,13 +184,13 @@ static void
move_roots(PyGC_Head *containers, PyGC_Head *roots) move_roots(PyGC_Head *containers, PyGC_Head *roots)
{ {
PyGC_Head *next; PyGC_Head *next;
PyGC_Head *gc = containers->gc_next; PyGC_Head *gc = containers->gc.gc_next;
while (gc != containers) { while (gc != containers) {
next = gc->gc_next; next = gc->gc.gc_next;
if (gc->gc_refs > 0) { if (gc->gc.gc_refs > 0) {
gc_list_remove(gc); gc_list_remove(gc);
gc_list_append(gc, roots); gc_list_append(gc, roots);
gc->gc_refs = GC_MOVED; gc->gc.gc_refs = GC_MOVED;
} }
gc = next; gc = next;
} }
...@@ -201,10 +201,10 @@ visit_move(PyObject *op, PyGC_Head *tolist) ...@@ -201,10 +201,10 @@ visit_move(PyObject *op, PyGC_Head *tolist)
{ {
if (PyObject_IS_GC(op)) { if (PyObject_IS_GC(op)) {
PyGC_Head *gc = AS_GC(op); PyGC_Head *gc = AS_GC(op);
if (gc->gc_next != NULL && gc->gc_refs != GC_MOVED) { if (gc->gc.gc_next != NULL && gc->gc.gc_refs != GC_MOVED) {
gc_list_remove(gc); gc_list_remove(gc);
gc_list_append(gc, tolist); gc_list_append(gc, tolist);
gc->gc_refs = GC_MOVED; gc->gc.gc_refs = GC_MOVED;
} }
} }
return 0; return 0;
...@@ -215,8 +215,8 @@ static void ...@@ -215,8 +215,8 @@ static void
move_root_reachable(PyGC_Head *reachable) move_root_reachable(PyGC_Head *reachable)
{ {
traverseproc traverse; traverseproc traverse;
PyGC_Head *gc = reachable->gc_next; PyGC_Head *gc = reachable->gc.gc_next;
for (; gc != reachable; gc=gc->gc_next) { for (; gc != reachable; gc=gc->gc.gc_next) {
/* careful, reachable list is growing here */ /* careful, reachable list is growing here */
PyObject *op = FROM_GC(gc); PyObject *op = FROM_GC(gc);
traverse = op->ob_type->tp_traverse; traverse = op->ob_type->tp_traverse;
...@@ -231,7 +231,7 @@ static void ...@@ -231,7 +231,7 @@ static void
move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
{ {
PyGC_Head *next; PyGC_Head *next;
PyGC_Head *gc = unreachable->gc_next; PyGC_Head *gc = unreachable->gc.gc_next;
static PyObject *delstr = NULL; static PyObject *delstr = NULL;
if (delstr == NULL) { if (delstr == NULL) {
delstr = PyString_InternFromString("__del__"); delstr = PyString_InternFromString("__del__");
...@@ -240,7 +240,7 @@ move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) ...@@ -240,7 +240,7 @@ move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
} }
for (; gc != unreachable; gc=next) { for (; gc != unreachable; gc=next) {
PyObject *op = FROM_GC(gc); PyObject *op = FROM_GC(gc);
next = gc->gc_next; next = gc->gc.gc_next;
if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) { if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) {
gc_list_remove(gc); gc_list_remove(gc);
gc_list_append(gc, finalizers); gc_list_append(gc, finalizers);
...@@ -253,8 +253,8 @@ static void ...@@ -253,8 +253,8 @@ static void
move_finalizer_reachable(PyGC_Head *finalizers) move_finalizer_reachable(PyGC_Head *finalizers)
{ {
traverseproc traverse; traverseproc traverse;
PyGC_Head *gc = finalizers->gc_next; PyGC_Head *gc = finalizers->gc.gc_next;
for (; gc != finalizers; gc=gc->gc_next) { for (; gc != finalizers; gc=gc->gc.gc_next) {
/* careful, finalizers list is growing here */ /* careful, finalizers list is growing here */
traverse = FROM_GC(gc)->ob_type->tp_traverse; traverse = FROM_GC(gc)->ob_type->tp_traverse;
(void) traverse(FROM_GC(gc), (void) traverse(FROM_GC(gc),
...@@ -297,8 +297,8 @@ handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old) ...@@ -297,8 +297,8 @@ handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
if (garbage == NULL) { if (garbage == NULL) {
garbage = PyList_New(0); garbage = PyList_New(0);
} }
for (gc = finalizers->gc_next; gc != finalizers; for (gc = finalizers->gc.gc_next; gc != finalizers;
gc = finalizers->gc_next) { gc = finalizers->gc.gc_next) {
PyObject *op = FROM_GC(gc); PyObject *op = FROM_GC(gc);
if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) { if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) {
/* If SAVEALL is not set then just append /* If SAVEALL is not set then just append
...@@ -321,8 +321,8 @@ delete_garbage(PyGC_Head *unreachable, PyGC_Head *old) ...@@ -321,8 +321,8 @@ delete_garbage(PyGC_Head *unreachable, PyGC_Head *old)
{ {
inquiry clear; inquiry clear;
while (unreachable->gc_next != unreachable) { while (unreachable->gc.gc_next != unreachable) {
PyGC_Head *gc = unreachable->gc_next; PyGC_Head *gc = unreachable->gc.gc_next;
PyObject *op = FROM_GC(gc); PyObject *op = FROM_GC(gc);
if (debug & DEBUG_SAVEALL) { if (debug & DEBUG_SAVEALL) {
PyList_Append(garbage, op); PyList_Append(garbage, op);
...@@ -334,7 +334,7 @@ delete_garbage(PyGC_Head *unreachable, PyGC_Head *old) ...@@ -334,7 +334,7 @@ delete_garbage(PyGC_Head *unreachable, PyGC_Head *old)
Py_DECREF(op); Py_DECREF(op);
} }
} }
if (unreachable->gc_next == gc) { if (unreachable->gc.gc_next == gc) {
/* object is still alive, move it, it may die later */ /* object is still alive, move it, it may die later */
gc_list_remove(gc); gc_list_remove(gc);
gc_list_append(gc, old); gc_list_append(gc, old);
...@@ -396,8 +396,8 @@ collect(PyGC_Head *young, PyGC_Head *old) ...@@ -396,8 +396,8 @@ collect(PyGC_Head *young, PyGC_Head *old)
/* Collect statistics on collectable objects found and print /* Collect statistics on collectable objects found and print
* debugging information. */ * debugging information. */
for (gc = unreachable.gc_next; gc != &unreachable; for (gc = unreachable.gc.gc_next; gc != &unreachable;
gc = gc->gc_next) { gc = gc->gc.gc_next) {
m++; m++;
if (debug & DEBUG_COLLECTABLE) { if (debug & DEBUG_COLLECTABLE) {
debug_cycle("collectable", FROM_GC(gc)); debug_cycle("collectable", FROM_GC(gc));
...@@ -410,8 +410,8 @@ collect(PyGC_Head *young, PyGC_Head *old) ...@@ -410,8 +410,8 @@ collect(PyGC_Head *young, PyGC_Head *old)
/* Collect statistics on uncollectable objects found and print /* Collect statistics on uncollectable objects found and print
* debugging information. */ * debugging information. */
for (gc = finalizers.gc_next; gc != &finalizers; for (gc = finalizers.gc.gc_next; gc != &finalizers;
gc = gc->gc_next) { gc = gc->gc.gc_next) {
n++; n++;
if (debug & DEBUG_UNCOLLECTABLE) { if (debug & DEBUG_UNCOLLECTABLE) {
debug_cycle("uncollectable", FROM_GC(gc)); debug_cycle("uncollectable", FROM_GC(gc));
...@@ -456,7 +456,7 @@ collect_generations(void) ...@@ -456,7 +456,7 @@ collect_generations(void)
generation = 2; generation = 2;
gc_list_merge(&_PyGC_generation0, &generation2); gc_list_merge(&_PyGC_generation0, &generation2);
gc_list_merge(&generation1, &generation2); gc_list_merge(&generation1, &generation2);
if (generation2.gc_next != &generation2) { if (generation2.gc.gc_next != &generation2) {
n = collect(&generation2, &generation2); n = collect(&generation2, &generation2);
} }
collections1 = 0; collections1 = 0;
...@@ -465,7 +465,7 @@ collect_generations(void) ...@@ -465,7 +465,7 @@ collect_generations(void)
generation = 1; generation = 1;
collections1++; collections1++;
gc_list_merge(&_PyGC_generation0, &generation1); gc_list_merge(&_PyGC_generation0, &generation1);
if (generation1.gc_next != &generation1) { if (generation1.gc.gc_next != &generation1) {
n = collect(&generation1, &generation2); n = collect(&generation1, &generation2);
} }
collections0 = 0; collections0 = 0;
...@@ -473,7 +473,7 @@ collect_generations(void) ...@@ -473,7 +473,7 @@ collect_generations(void)
else { else {
generation = 0; generation = 0;
collections0++; collections0++;
if (_PyGC_generation0.gc_next != &_PyGC_generation0) { if (_PyGC_generation0.gc.gc_next != &_PyGC_generation0) {
n = collect(&_PyGC_generation0, &generation1); n = collect(&_PyGC_generation0, &generation1);
} }
} }
...@@ -646,7 +646,7 @@ gc_referents_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist) ...@@ -646,7 +646,7 @@ gc_referents_for(PyObject *objs, PyGC_Head *list, PyObject *resultlist)
PyGC_Head *gc; PyGC_Head *gc;
PyObject *obj; PyObject *obj;
traverseproc traverse; traverseproc traverse;
for (gc = list->gc_next; gc != list; gc = gc->gc_next) { for (gc = list->gc.gc_next; gc != list; gc = gc->gc.gc_next) {
obj = FROM_GC(gc); obj = FROM_GC(gc);
traverse = obj->ob_type->tp_traverse; traverse = obj->ob_type->tp_traverse;
if (obj == objs || obj == resultlist) if (obj == objs || obj == resultlist)
...@@ -688,7 +688,7 @@ static void ...@@ -688,7 +688,7 @@ static void
append_objects(PyObject *py_list, PyGC_Head *gc_list) append_objects(PyObject *py_list, PyGC_Head *gc_list)
{ {
PyGC_Head *gc; PyGC_Head *gc;
for (gc = gc_list->gc_next; gc != gc_list; gc = gc->gc_next) { for (gc = gc_list->gc.gc_next; gc != gc_list; gc = gc->gc.gc_next) {
PyObject *op = FROM_GC(gc); PyObject *op = FROM_GC(gc);
if (op != py_list) { if (op != py_list) {
Py_INCREF(op); Py_INCREF(op);
...@@ -807,7 +807,7 @@ _PyObject_GC_Malloc(PyTypeObject *tp, int nitems) ...@@ -807,7 +807,7 @@ _PyObject_GC_Malloc(PyTypeObject *tp, int nitems)
PyGC_Head *g = PyObject_MALLOC(nbytes); PyGC_Head *g = PyObject_MALLOC(nbytes);
if (g == NULL) if (g == NULL)
return (PyObject *)PyErr_NoMemory(); return (PyObject *)PyErr_NoMemory();
g->gc_next = NULL; g->gc.gc_next = NULL;
allocated++; allocated++;
if (allocated > threshold0 && if (allocated > threshold0 &&
enabled && enabled &&
...@@ -866,7 +866,7 @@ _PyObject_GC_Del(PyObject *op) ...@@ -866,7 +866,7 @@ _PyObject_GC_Del(PyObject *op)
{ {
#ifdef WITH_CYCLE_GC #ifdef WITH_CYCLE_GC
PyGC_Head *g = AS_GC(op); PyGC_Head *g = AS_GC(op);
if (g->gc_next != NULL) if (g->gc.gc_next != NULL)
gc_list_remove(g); gc_list_remove(g);
if (allocated > 0) { if (allocated > 0) {
allocated--; allocated--;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment