diff --git a/Include/object.h b/Include/object.h index 2a6b1703dc6..ab270f861d4 100644 --- a/Include/object.h +++ b/Include/object.h @@ -198,6 +198,13 @@ typedef struct _typeobject { /* More standard operations (at end for binary compatibility) */ long (*tp_hash) FPROTO((object *)); +#ifdef COUNT_ALLOCS + /* these must be last */ + int tp_alloc; + int tp_free; + int tp_maxalloc; + struct _typeobject *tp_next; +#endif } typeobject; extern typeobject Typetype; /* The type of type objects */ @@ -253,15 +260,27 @@ environment the global variable trick is not safe.) #endif #ifndef TRACE_REFS +#ifdef COUNT_ALLOCS +#define DELREF(op) ((op)->ob_type->tp_free++, (*(op)->ob_type->tp_dealloc)((object *)(op))) +#else #define DELREF(op) (*(op)->ob_type->tp_dealloc)((object *)(op)) +#endif #define UNREF(op) /*empty*/ #endif +#ifdef COUNT_ALLOCS +extern void inc_count PROTO((typeobject *)); +#endif + #ifdef REF_DEBUG extern long ref_total; #ifndef TRACE_REFS +#ifdef COUNT_ALLOCS +#define NEWREF(op) (inc_count((op)->ob_type), ref_total++, (op)->ob_refcnt = 1) +#else #define NEWREF(op) (ref_total++, (op)->ob_refcnt = 1) #endif +#endif #define INCREF(op) (ref_total++, (op)->ob_refcnt++) #define DECREF(op) \ if (--ref_total, --(op)->ob_refcnt > 0) \ @@ -269,7 +288,11 @@ extern long ref_total; else \ DELREF(op) #else +#ifdef COUNT_ALLOCS +#define NEWREF(op) (inc_count((op)->ob_type), (op)->ob_refcnt = 1) +#else #define NEWREF(op) ((op)->ob_refcnt = 1) +#endif #define INCREF(op) ((op)->ob_refcnt++) #define DECREF(op) \ if (--(op)->ob_refcnt > 0) \ diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index b5a2cfa0b4f..93c0735a653 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -252,10 +252,10 @@ newarrayobject(size, descr) return err_nomem(); } } - NEWREF(op); op->ob_type = &Arraytype; op->ob_size = size; op->ob_descr = descr; + NEWREF(op); return (object *) op; } diff --git a/Modules/config.c.in b/Modules/config.c.in index 484381ec4ea..f19655f73f5 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -310,6 +310,9 @@ extern void initGlx(); #ifdef USE_HTML extern void initHTML(); #endif +#ifdef USE_XLIB +extern void initXlib(); +#endif /* -- ADDMODULE MARKER 1 -- */ struct { @@ -485,6 +488,10 @@ struct { {"HTML", initHTML}, #endif +#ifdef USE_XLIB + {"Xlib", initXlib}, +#endif + /* -- ADDMODULE MARKER 2 -- */ {0, 0} /* Sentinel */ diff --git a/Modules/imageop.c b/Modules/imageop.c index 40940cb7f95..841ec1b2b48 100644 --- a/Modules/imageop.c +++ b/Modules/imageop.c @@ -542,9 +542,15 @@ imageop_rgb2rgb8(self, args) for ( i=0; i < nlen; i++ ) { /* Bits in source: aaaaaaaa BBbbbbbb GGGggggg RRRrrrrr */ value = *cp++; +#if 0 r = (value >> 5) & 7; g = (value >> 13) & 7; b = (value >> 22) & 3; +#else + r = (int) ((value & 0xff) / 255. * 7. + .5); + g = (int) (((value >> 8) & 0xff) / 255. * 7. + .5); + b = (int) (((value >> 16) & 0xff) / 255. * 3. + .5); +#endif nvalue = (r<<5) | (b<<3) | g; *ncp++ = nvalue; } diff --git a/Modules/imgfile.c b/Modules/imgfile.c index 93f5ef3cfd2..e57d6c40524 100644 --- a/Modules/imgfile.c +++ b/Modules/imgfile.c @@ -43,6 +43,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. static object * ImgfileError; /* Exception we raise for various trouble */ +static int top_to_bottom; /* True if we want top-to-bottom images */ /* The image library does not always call the error hander :-(, therefore we have a global variable indicating that it was called. @@ -86,6 +87,20 @@ imgfile_open(fname) return image; } +static object * +imgfile_ttob(self, args) + object *self; + object *args; +{ + int newval; + object *rv; + + if (!getargs(args, "i", &newval)) + return NULL; + rv = newintobject(top_to_bottom); + top_to_bottom = newval; + return rv; +} static object * imgfile_read(self, args) @@ -100,7 +115,8 @@ imgfile_read(self, args) static short rs[8192], gs[8192], bs[8192]; int x, y; IMAGE *image; - + int yfirst, ylast, ystep; + if ( !getargs(args, "s", &fname) ) return NULL; @@ -139,7 +155,17 @@ imgfile_read(self, args) } cdatap = getstringvalue(rv); idatap = (long *)cdatap; - for ( y=0; y < ysize && !error_called; y++ ) { + + if (top_to_bottom) { + yfirst = ysize-1; + ylast = -1; + ystep = -1; + } else { + yfirst = 0; + ylast = ysize; + ystep = 1; + } + for ( y=yfirst; y != ylast && !error_called; y += ystep ) { if ( zsize == 1 ) { getrow(image, rs, y, 0); for(x=0; xob_type = &Floattype; op->ob_fval = fval; + NEWREF(op); return (object *) op; } diff --git a/Objects/intobject.c b/Objects/intobject.c index 3021873acde..816a4112a2e 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -87,9 +87,9 @@ newintobject(ival) } v = free_list; free_list = *(intobject **)free_list; - NEWREF(v); v->ob_type = &Inttype; v->ob_ival = ival; + NEWREF(v); return (object *) v; } diff --git a/Objects/listobject.c b/Objects/listobject.c index 38829e2d3f1..67a61853a63 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -58,11 +58,11 @@ newlistobject(size) return err_nomem(); } } - NEWREF(op); op->ob_type = &Listtype; op->ob_size = size; for (i = 0; i < size; i++) op->ob_item[i] = NULL; + NEWREF(op); return (object *) op; } @@ -520,7 +520,7 @@ cmp(v, w) return cmpobject(* (object **) v, * (object **) w); /* Call the user-supplied comparison function */ - t = mkvalue("OO", v, w); + t = mkvalue("OO", * (object **) v, * (object **) w); if (t == NULL) return 0; res = call_object(cmpfunc, t); diff --git a/Objects/object.c b/Objects/object.c index a469797f583..a20b24d958f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -34,6 +34,36 @@ long ref_total; These are used by the individual routines for object creation. Do not call them otherwise, they do not initialize the object! */ +#ifdef COUNT_ALLOCS +static typeobject *type_list; + +void +dump_counts() +{ + typeobject *tp; + + for (tp = type_list; tp; tp = tp->tp_next) + printf("%s %d %d %d\n", tp->tp_name, tp->tp_alloc, tp->tp_free, + tp->tp_maxalloc); +} + +void +inc_count(tp) + typeobject *tp; +{ + if (tp->tp_alloc == 0) { + /* first time; hang in linked list */ + if (tp->tp_next != NULL) /* sanity check */ + abort(); + tp->tp_next = type_list; + type_list = tp; + } + tp->tp_alloc++; + if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc) + tp->tp_maxalloc = tp->tp_alloc - tp->tp_free; +} +#endif + object * newobject(tp) typeobject *tp; @@ -41,8 +71,8 @@ newobject(tp) object *op = (object *) malloc(tp->tp_basicsize); if (op == NULL) return err_nomem(); - NEWREF(op); op->ob_type = tp; + NEWREF(op); return op; } @@ -55,9 +85,9 @@ newvarobject(tp, size) malloc(tp->tp_basicsize + size * tp->tp_itemsize); if (op == NULL) return (varobject *)err_nomem(); - NEWREF(op); op->ob_type = tp; op->ob_size = size; + NEWREF(op); return op; } @@ -301,6 +331,9 @@ NEWREF(op) op->_ob_prev = &refchain; refchain._ob_next->_ob_prev = op; refchain._ob_next = op; +#ifdef COUNT_ALLOCS + inc_count(op->ob_type); +#endif } UNREF(op) @@ -335,6 +368,9 @@ DELREF(op) object *op; { UNREF(op); +#ifdef COUNT_ALLOCS + op->ob_type->tp_free++; +#endif (*(op)->ob_type->tp_dealloc)(op); op->ob_type = NULL; } diff --git a/Objects/stringobject.c b/Objects/stringobject.c index cba8c920db1..a3043d49f43 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -35,9 +35,9 @@ newsizedstringobject(str, size) malloc(sizeof(stringobject) + size * sizeof(char)); if (op == NULL) return err_nomem(); - NEWREF(op); op->ob_type = &Stringtype; op->ob_size = size; + NEWREF(op); if (str != NULL) memcpy(op->ob_sval, str, size); op->ob_sval[size] = '\0'; @@ -53,9 +53,9 @@ newstringobject(str) malloc(sizeof(stringobject) + size * sizeof(char)); if (op == NULL) return err_nomem(); - NEWREF(op); op->ob_type = &Stringtype; op->ob_size = size; + NEWREF(op); strcpy(op->ob_sval, str); return (object *) op; } @@ -187,9 +187,9 @@ string_concat(a, bb) malloc(sizeof(stringobject) + size * sizeof(char)); if (op == NULL) return err_nomem(); - NEWREF(op); op->ob_type = &Stringtype; op->ob_size = size; + NEWREF(op); memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); op->ob_sval[size] = '\0'; @@ -216,9 +216,9 @@ string_repeat(a, n) malloc(sizeof(stringobject) + size * sizeof(char)); if (op == NULL) return err_nomem(); - NEWREF(op); op->ob_type = &Stringtype; op->ob_size = size; + NEWREF(op); for (i = 0; i < size; i += a->ob_size) memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); op->ob_sval[size] = '\0'; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index faf46d52cc6..fae9386968e 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -40,11 +40,11 @@ newtupleobject(size) malloc(sizeof(tupleobject) + size * sizeof(object *)); if (op == NULL) return err_nomem(); - NEWREF(op); op->ob_type = &Tupletype; op->ob_size = size; for (i = 0; i < size; i++) op->ob_item[i] = NULL; + NEWREF(op); return (object *) op; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index d518f24f560..6661a19297d 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -417,12 +417,20 @@ cleanup() flushline(); } +#ifdef COUNT_ALLOCS +extern void dump_counts PROTO((void)); +#endif + void goaway(sts) int sts; { cleanup(); +#ifdef COUNT_ALLOCS + dump_counts(); +#endif + #ifdef USE_THREAD /* Other threads may still be active, so skip most of the