Several optimizations and speed improvements.

cstubs: Use Matrix type instead of float[4][4].
This commit is contained in:
Sjoerd Mullender 1993-10-22 12:04:32 +00:00
parent a75d306e2b
commit 3bb8a05947
10 changed files with 216 additions and 63 deletions

View File

@ -51,6 +51,9 @@ functions should be applied to nil objects.
typedef struct { typedef struct {
OB_VARHEAD OB_VARHEAD
#ifdef CACHE_HASH
long ob_shash;
#endif
char ob_sval[1]; char ob_sval[1];
} stringobject; } stringobject;

View File

@ -529,21 +529,21 @@ gl_getmatrix(self, args)
object *self; object *self;
object *args; object *args;
{ {
float arg1 [ 16 ] ; Matrix arg1;
object *v, *w; object *v, *w;
int i; int i, j;
getmatrix( arg1 ); getmatrix( arg1 );
v = newlistobject(16); v = newlistobject(16);
if (v == NULL) { if (v == NULL) {
return err_nomem(); return err_nomem();
} }
for (i = 0; i < 16; i++) { for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) {
w = mknewfloatobject(arg1[i]); w = mknewfloatobject(arg1[i][j]);
if (w == NULL) { if (w == NULL) {
DECREF(v); DECREF(v);
return NULL; return NULL;
} }
setlistitem(v, i, w); setlistitem(v, i*4+j, w);
} }
return v; return v;
} }
@ -559,7 +559,7 @@ gl_altgetmatrix(self, args)
object *self; object *self;
object *args; object *args;
{ {
float arg1 [ 4 ] [ 4 ] ; Matrix arg1;
object *v, *w; object *v, *w;
int i, j; int i, j;
getmatrix( arg1 ); getmatrix( arg1 );
@ -742,7 +742,7 @@ gl_packrect(self, args)
if (packed == NULL) if (packed == NULL)
return NULL; return NULL;
parray = (unsigned long *) getstringvalue(unpacked); parray = (unsigned long *) getstringvalue(unpacked);
p = getstringvalue(packed); p = (unsigned char *) getstringvalue(packed);
for (y = 0; y < height; y += packfactor, parray += packfactor*width) { for (y = 0; y < height; y += packfactor, parray += packfactor*width) {
for (x = 0; x < width; x += packfactor) { for (x = 0; x < width; x += packfactor) {
pixel = parray[x]; pixel = parray[x];

View File

@ -254,24 +254,26 @@ strop_lower(self, args)
object *self; /* Not used */ object *self; /* Not used */
object *args; object *args;
{ {
char *s; char *s, *s_new;
int i, n; int i, n;
object *new; object *new;
int changed; int changed;
if (!getargs(args, "s#", &s, &n)) if (!getargs(args, "s#", &s, &n))
return NULL; return NULL;
new = newsizedstringobject(s, n); new = newsizedstringobject(NULL, n);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
s = getstringvalue(new); s_new = getstringvalue(new);
changed = 0; changed = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
char c = s[i]; char c = *s++;
if (isupper(c)) { if (isupper(c)) {
changed = 1; changed = 1;
s[i] = tolower(c); *s_new = tolower(c);
} } else
*s_new = c;
s_new++;
} }
if (!changed) { if (!changed) {
DECREF(new); DECREF(new);
@ -287,24 +289,26 @@ strop_upper(self, args)
object *self; /* Not used */ object *self; /* Not used */
object *args; object *args;
{ {
char *s; char *s, *s_new;
int i, n; int i, n;
object *new; object *new;
int changed; int changed;
if (!getargs(args, "s#", &s, &n)) if (!getargs(args, "s#", &s, &n))
return NULL; return NULL;
new = newsizedstringobject(s, n); new = newsizedstringobject(NULL, n);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
s = getstringvalue(new); s_new = getstringvalue(new);
changed = 0; changed = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
char c = s[i]; char c = *s++;
if (islower(c)) { if (islower(c)) {
changed = 1; changed = 1;
s[i] = toupper(c); *s_new = toupper(c);
} } else
*s_new = c;
s_new++;
} }
if (!changed) { if (!changed) {
DECREF(new); DECREF(new);
@ -320,28 +324,31 @@ strop_swapcase(self, args)
object *self; /* Not used */ object *self; /* Not used */
object *args; object *args;
{ {
char *s; char *s, *s_new;
int i, n; int i, n;
object *new; object *new;
int changed; int changed;
if (!getargs(args, "s#", &s, &n)) if (!getargs(args, "s#", &s, &n))
return NULL; return NULL;
new = newsizedstringobject(s, n); new = newsizedstringobject(NULL, n);
if (new == NULL) if (new == NULL)
return NULL; return NULL;
s = getstringvalue(new); s_new = getstringvalue(new);
changed = 0; changed = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
char c = s[i]; char c = *s++;
if (islower(c)) { if (islower(c)) {
changed = 1; changed = 1;
s[i] = toupper(c); *s_new = toupper(c);
} }
else if (isupper(c)) { else if (isupper(c)) {
changed = 1; changed = 1;
s[i] = tolower(c); *s_new = tolower(c);
} }
else
*s_new = c;
s_new++;
} }
if (!changed) { if (!changed) {
DECREF(new); DECREF(new);

View File

@ -232,10 +232,11 @@ isprivileged(caller)
object *caller; object *caller;
{ {
object *g; object *g;
if (caller != NULL && hasattr(caller, "__privileged__")) static char privileged[] = "__privileged__";
if (caller != NULL && hasattr(caller, privileged))
return 1; return 1;
g = getglobals(); g = getglobals();
if (g != NULL && dictlookup(g, "__privileged__")) if (g != NULL && dictlookup(g, privileged))
return 1; return 1;
return 0; return 0;
} }

View File

@ -355,13 +355,15 @@ instance_getattr(inst, name)
{ {
register object *v; register object *v;
classobject *class; classobject *class;
if (strcmp(name, "__dict__") == 0) { if (name[0] == '_' && name[1] == '_') {
INCREF(inst->in_dict); if (strcmp(name, "__dict__") == 0) {
return inst->in_dict; INCREF(inst->in_dict);
} return inst->in_dict;
if (strcmp(name, "__class__") == 0) { }
INCREF(inst->in_class); if (strcmp(name, "__class__") == 0) {
return (object *)inst->in_class; INCREF(inst->in_class);
return (object *)inst->in_class;
}
} }
class = NULL; class = NULL;
v = dictlookup(inst->in_dict, name); v = dictlookup(inst->in_dict, name);

View File

@ -242,6 +242,9 @@ mappinglookup(op, key)
err_badcall(); err_badcall();
return NULL; return NULL;
} }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return NULL; return NULL;
@ -260,6 +263,9 @@ mappinginsert(op, key, value)
err_badcall(); err_badcall();
return -1; return -1;
} }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return -1; return -1;
@ -289,6 +295,9 @@ mappingremove(op, key)
err_badcall(); err_badcall();
return -1; return -1;
} }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return -1; return -1;
@ -447,7 +456,11 @@ mapping_subscript(mp, key)
register object *key; register object *key;
{ {
object *v; object *v;
long hash = hashobject(key); long hash;
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key);
if (hash == -1) if (hash == -1)
return NULL; return NULL;
v = lookmapping(mp, key, hash) -> me_value; v = lookmapping(mp, key, hash) -> me_value;
@ -628,9 +641,15 @@ mapping_compare(a, b)
res = cmpobject(akey, bkey); res = cmpobject(akey, bkey);
if (res != 0) if (res != 0)
break; break;
#ifdef CACHE_HASH
if (!is_stringobject(akey) || (ahash = ((stringobject *) akey)->ob_shash) == -1)
#endif
ahash = hashobject(akey); ahash = hashobject(akey);
if (ahash == -1) if (ahash == -1)
err_clear(); /* Don't want errors here */ err_clear(); /* Don't want errors here */
#ifdef CACHE_HASH
if (!is_stringobject(bkey) || (bhash = ((stringobject *) bkey)->ob_shash) == -1)
#endif
bhash = hashobject(bkey); bhash = hashobject(bkey);
if (bhash == -1) if (bhash == -1)
err_clear(); /* Don't want errors here */ err_clear(); /* Don't want errors here */
@ -661,6 +680,9 @@ mapping_has_key(mp, args)
register long ok; register long ok;
if (!getargs(args, "O", &key)) if (!getargs(args, "O", &key))
return NULL; return NULL;
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return NULL; return NULL;

View File

@ -242,6 +242,9 @@ mappinglookup(op, key)
err_badcall(); err_badcall();
return NULL; return NULL;
} }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return NULL; return NULL;
@ -260,6 +263,9 @@ mappinginsert(op, key, value)
err_badcall(); err_badcall();
return -1; return -1;
} }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return -1; return -1;
@ -289,6 +295,9 @@ mappingremove(op, key)
err_badcall(); err_badcall();
return -1; return -1;
} }
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return -1; return -1;
@ -447,7 +456,11 @@ mapping_subscript(mp, key)
register object *key; register object *key;
{ {
object *v; object *v;
long hash = hashobject(key); long hash;
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key);
if (hash == -1) if (hash == -1)
return NULL; return NULL;
v = lookmapping(mp, key, hash) -> me_value; v = lookmapping(mp, key, hash) -> me_value;
@ -628,9 +641,15 @@ mapping_compare(a, b)
res = cmpobject(akey, bkey); res = cmpobject(akey, bkey);
if (res != 0) if (res != 0)
break; break;
#ifdef CACHE_HASH
if (!is_stringobject(akey) || (ahash = ((stringobject *) akey)->ob_shash) == -1)
#endif
ahash = hashobject(akey); ahash = hashobject(akey);
if (ahash == -1) if (ahash == -1)
err_clear(); /* Don't want errors here */ err_clear(); /* Don't want errors here */
#ifdef CACHE_HASH
if (!is_stringobject(bkey) || (bhash = ((stringobject *) bkey)->ob_shash) == -1)
#endif
bhash = hashobject(bkey); bhash = hashobject(bkey);
if (bhash == -1) if (bhash == -1)
err_clear(); /* Don't want errors here */ err_clear(); /* Don't want errors here */
@ -661,6 +680,9 @@ mapping_has_key(mp, args)
register long ok; register long ok;
if (!getargs(args, "O", &key)) if (!getargs(args, "O", &key))
return NULL; return NULL;
#ifdef CACHE_HASH
if (!is_stringobject(key) || (hash = ((stringobject *) key)->ob_shash) == -1)
#endif
hash = hashobject(key); hash = hashobject(key);
if (hash == -1) if (hash == -1)
return NULL; return NULL;

View File

@ -38,6 +38,7 @@ long ref_total;
static typeobject *type_list; static typeobject *type_list;
extern int tuple_zero_allocs, fast_tuple_allocs; extern int tuple_zero_allocs, fast_tuple_allocs;
extern int quick_int_allocs, quick_neg_int_allocs; extern int quick_int_allocs, quick_neg_int_allocs;
extern int null_strings, one_strings;
void void
dump_counts() dump_counts()
{ {
@ -51,6 +52,7 @@ dump_counts()
tuple_zero_allocs); tuple_zero_allocs);
printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs, printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs,
quick_neg_int_allocs); quick_neg_int_allocs);
printf("null strings: %d, 1-strings: %d\n", null_strings, one_strings);
} }
void void

View File

@ -26,21 +26,76 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h" #include "allobjects.h"
#ifdef COUNT_ALLOCS
int null_strings, one_strings;
#endif
#ifdef __STDC__
#include <limits.h>
#else
#ifndef UCHAR_MAX
#define UCHAR_MAX 255
#endif
#endif
static stringobject *characters[UCHAR_MAX + 1];
static stringobject *nullstring;
/*
Newsizedstringobject() and newstringobject() try in certain cases
to share string objects. When the size of the string is zero,
these routines always return a pointer to the same string object;
when the size is one, they return a pointer to an already existing
object if the contents of the string is known. For
newstringobject() this is always the case, for
newsizedstringobject() this is the case when the first argument in
not NULL.
A common practice to allocate a string and then fill it in or
change it must be done carefully. It is only allowed to change the
contents of the string if the obect was gotten from
newsizedstringobject() with a NULL first argument, because in the
future these routines may try to do even more sharing of objects.
*/
object * object *
newsizedstringobject(str, size) newsizedstringobject(str, size)
char *str; char *str;
int size; int size;
{ {
register stringobject *op = (stringobject *) register stringobject *op;
if (size == 0 && (op = nullstring) != NULL) {
#ifdef COUNT_ALLOCS
null_strings++;
#endif
INCREF(op);
return op;
}
if (size == 1 && str != NULL && (op = characters[*str & UCHAR_MAX]) != NULL) {
#ifdef COUNT_ALLOCS
one_strings++;
#endif
INCREF(op);
return op;
}
op = (stringobject *)
malloc(sizeof(stringobject) + size * sizeof(char)); malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
NEWREF(op); NEWREF(op);
if (str != NULL) if (str != NULL)
memcpy(op->ob_sval, str, size); memcpy(op->ob_sval, str, size);
op->ob_sval[size] = '\0'; op->ob_sval[size] = '\0';
if (size == 0) {
nullstring = op;
INCREF(op);
} else if (size == 1 && str != NULL) {
characters[*str & UCHAR_MAX] = op;
INCREF(op);
}
return (object *) op; return (object *) op;
} }
@ -49,14 +104,39 @@ newstringobject(str)
char *str; char *str;
{ {
register unsigned int size = strlen(str); register unsigned int size = strlen(str);
register stringobject *op = (stringobject *) register stringobject *op;
if (size == 0 && (op = nullstring) != NULL) {
#ifdef COUNT_ALLOCS
null_strings++;
#endif
INCREF(op);
return op;
}
if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) {
#ifdef COUNT_ALLOCS
one_strings++;
#endif
INCREF(op);
return op;
}
op = (stringobject *)
malloc(sizeof(stringobject) + size * sizeof(char)); malloc(sizeof(stringobject) + size * sizeof(char));
if (op == NULL) if (op == NULL)
return err_nomem(); return err_nomem();
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
NEWREF(op); NEWREF(op);
strcpy(op->ob_sval, str); strcpy(op->ob_sval, str);
if (size == 0) {
nullstring = op;
INCREF(op);
} else if (size == 1) {
characters[*str & UCHAR_MAX] = op;
INCREF(op);
}
return (object *) op; return (object *) op;
} }
@ -189,6 +269,9 @@ string_concat(a, bb)
return err_nomem(); return err_nomem();
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
NEWREF(op); NEWREF(op);
memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); 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); memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size);
@ -218,6 +301,9 @@ string_repeat(a, n)
return err_nomem(); return err_nomem();
op->ob_type = &Stringtype; op->ob_type = &Stringtype;
op->ob_size = size; op->ob_size = size;
#ifdef CACHE_HASH
op->ob_shash = -1;
#endif
NEWREF(op); NEWREF(op);
for (i = 0; i < size; i += a->ob_size) for (i = 0; i < size; i += a->ob_size)
memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size);
@ -247,16 +333,6 @@ string_slice(a, i, j)
return newsizedstringobject(a->ob_sval + i, (int) (j-i)); return newsizedstringobject(a->ob_sval + i, (int) (j-i));
} }
#ifdef __STDC__
#include <limits.h>
#else
#ifndef UCHAR_MAX
#define UCHAR_MAX 255
#endif
#endif
static object *characters[UCHAR_MAX + 1];
static object * static object *
string_item(a, i) string_item(a, i)
stringobject *a; stringobject *a;
@ -269,12 +345,16 @@ string_item(a, i)
return NULL; return NULL;
} }
c = a->ob_sval[i] & UCHAR_MAX; c = a->ob_sval[i] & UCHAR_MAX;
v = characters[c]; v = (object *) characters[c];
#ifdef COUNT_ALLOCS
if (v != NULL)
one_strings++;
#endif
if (v == NULL) { if (v == NULL) {
v = newsizedstringobject((char *)NULL, 1); v = newsizedstringobject((char *)NULL, 1);
if (v == NULL) if (v == NULL)
return NULL; return NULL;
characters[c] = v; characters[c] = (stringobject *) v;
((stringobject *)v)->ob_sval[0] = c; ((stringobject *)v)->ob_sval[0] = c;
} }
INCREF(v); INCREF(v);
@ -287,9 +367,14 @@ string_compare(a, b)
{ {
int len_a = a->ob_size, len_b = b->ob_size; int len_a = a->ob_size, len_b = b->ob_size;
int min_len = (len_a < len_b) ? len_a : len_b; int min_len = (len_a < len_b) ? len_a : len_b;
int cmp = memcmp(a->ob_sval, b->ob_sval, min_len); int cmp;
if (cmp != 0) if (min_len > 0) {
return cmp; cmp = *a->ob_sval - *b->ob_sval;
if (cmp == 0)
cmp = memcmp(a->ob_sval, b->ob_sval, min_len);
if (cmp != 0)
return cmp;
}
return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
} }
@ -297,14 +382,25 @@ static long
string_hash(a) string_hash(a)
stringobject *a; stringobject *a;
{ {
register int len = a->ob_size; register int len;
register unsigned char *p = (unsigned char *) a->ob_sval; register unsigned char *p;
register long x = *p << 7; register long x;
#ifdef CACHE_HASH
if (a->ob_shash != -1)
return a->ob_shash;
#endif
len = a->ob_size;
p = (unsigned char *) a->ob_sval;
x = *p << 7;
while (--len >= 0) while (--len >= 0)
x = (x + x + x) ^ *p++; x = (x + x + x) ^ *p++;
x ^= a->ob_size; x ^= a->ob_size;
if (x == -1) if (x == -1)
x = -2; x = -2;
#ifdef CACHE_HASH
a->ob_shash = x;
#endif
return x; return x;
} }

View File

@ -821,7 +821,7 @@ eval_code(co, globals, locals, owner, arg)
break; break;
} }
if ((err = dict2remove(f->f_locals, w)) != 0) if ((err = dict2remove(f->f_locals, w)) != 0)
err_setstr(NameError, getstringvalue(w)); err_setval(NameError, w);
break; break;
#ifdef CASE_TOO_BIG #ifdef CASE_TOO_BIG
@ -1031,7 +1031,7 @@ eval_code(co, globals, locals, owner, arg)
break; break;
} }
if ((err = dict2remove(f->f_globals, w)) != 0) if ((err = dict2remove(f->f_globals, w)) != 0)
err_setstr(NameError, getstringvalue(w)); err_setval(NameError, w);
break; break;
case LOAD_CONST: case LOAD_CONST:
@ -1050,8 +1050,7 @@ eval_code(co, globals, locals, owner, arg)
err_clear(); err_clear();
x = getbuiltin(w); x = getbuiltin(w);
if (x == NULL) { if (x == NULL) {
err_setstr(NameError, err_setval(NameError, w);
getstringvalue(w));
break; break;
} }
} }
@ -1073,8 +1072,7 @@ eval_code(co, globals, locals, owner, arg)
err_clear(); err_clear();
x = getbuiltin(w); x = getbuiltin(w);
if (x == NULL) { if (x == NULL) {
err_setstr(NameError, err_setval(NameError, w);
getstringvalue(w));
break; break;
} }
} }
@ -1092,7 +1090,7 @@ eval_code(co, globals, locals, owner, arg)
w = GETNAMEV(oparg); w = GETNAMEV(oparg);
x = dict2lookup(f->f_locals, w); x = dict2lookup(f->f_locals, w);
if (x == NULL) { if (x == NULL) {
err_setstr(NameError, getstringvalue(w)); err_setval(NameError, w);
break; break;
} }
if (is_accessobject(x)) { if (is_accessobject(x)) {