summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbjj <bjj>2006-09-07 00:55:02 (GMT)
committerbjj <bjj>2006-09-07 00:55:02 (GMT)
commitcc1f9810f4e6e0aa8eb496a42f97656f1cd4fd70 (patch)
tree8f0a1c20abe5da4a1c131b22fc63cbe514ded77a
parent468c33fcc527c6b34d9201e906a2197439c07cab (diff)
downloadmoo-cc1f9810f4e6e0aa8eb496a42f97656f1cd4fd70.zip
moo-cc1f9810f4e6e0aa8eb496a42f97656f1cd4fd70.tar.gz
moo-cc1f9810f4e6e0aa8eb496a42f97656f1cd4fd70.tar.bz2
moo-cc1f9810f4e6e0aa8eb496a42f97656f1cd4fd70.tar.xz
Add new MEMO_STRLEN option which uses the refcounting mechanism to
store strlen with strings. This is basically free, since most string allocations are rounded up by malloc anyway. This saves lots of cycles computing strlen. (The change is originally from jitmoo, where I wanted inline range checks for string ops).
-rw-r--r--db_objects.c13
-rw-r--r--execute.c27
-rw-r--r--list.c25
-rw-r--r--options.h14
-rw-r--r--program.c9
-rw-r--r--storage.c31
-rw-r--r--storage.h20
-rw-r--r--str_intern.c2
-rw-r--r--tasks.c11
-rw-r--r--utils.c9
10 files changed, 126 insertions, 35 deletions
diff --git a/db_objects.c b/db_objects.c
index 26f658c..97fd7c9 100644
--- a/db_objects.c
+++ b/db_objects.c
@@ -289,18 +289,18 @@ db_object_bytes(Objid oid)
Verbdef *v;
count = sizeof(Object) + sizeof(Object *);
- count += strlen(o->name) + 1;
+ count += memo_strlen(o->name) + 1;
for (v = o->verbdefs; v; v = v->next) {
count += sizeof(Verbdef);
- count += strlen(v->name) + 1;
+ count += memo_strlen(v->name) + 1;
if (v->program)
count += program_bytes(v->program);
}
count += sizeof(Propdef) * o->propdefs.cur_length;
for (i = 0; i < o->propdefs.cur_length; i++)
- count += strlen(o->propdefs.l[i].name) + 1;
+ count += memo_strlen(o->propdefs.l[i].name) + 1;
len = dbpriv_count_properties(oid);
count += (sizeof(Pval) - sizeof(Var)) * len;
@@ -554,6 +554,13 @@ char rcsid_db_objects[] = "$Id$";
/*
* $Log$
+ * Revision 1.5 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.4 1998/12/14 13:17:36 nop
* Merge UNSAFE_OPTS (ref fixups); fix Log tag placement to fit CVS whims
*
diff --git a/execute.c b/execute.c
index 10cb52c..9a4cfcd 100644
--- a/execute.c
+++ b/execute.c
@@ -960,12 +960,13 @@ do { \
|| (list.type == TYPE_LIST
&& index.v.num > list.v.list[0].v.num /* size */ )
|| (list.type == TYPE_STR
- && index.v.num > (int) strlen(list.v.str))) {
+ && index.v.num > (int) memo_strlen(list.v.str))) {
free_var(value);
free_var(index);
free_var(list);
PUSH_ERROR(E_RANGE);
- } else if (list.type == TYPE_STR && strlen(value.v.str) != 1) {
+ } else if (list.type == TYPE_STR
+ && memo_strlen(value.v.str) != 1) {
free_var(value);
free_var(index);
free_var(list);
@@ -1178,10 +1179,11 @@ do { \
ans = do_add(lhs, rhs);
else if (lhs.type == TYPE_STR && rhs.type == TYPE_STR) {
char *str;
+ int llen = memo_strlen(lhs.v.str);
- str = mymalloc((strlen(rhs.v.str) + strlen(lhs.v.str) + 1)
- * sizeof(char), M_STRING);
- sprintf(str, "%s%s", lhs.v.str, rhs.v.str);
+ str = mymalloc(llen + memo_strlen(rhs.v.str) + 1, M_STRING);
+ strcpy(str, lhs.v.str);
+ strcpy(str + llen, rhs.v.str);
ans.type = TYPE_STR;
ans.v.str = str;
} else {
@@ -1271,7 +1273,7 @@ do { \
}
} else { /* list.type == TYPE_STR */
if (index.v.num <= 0
- || index.v.num > (int) strlen(list.v.str)) {
+ || index.v.num > (int) memo_strlen(list.v.str)) {
free_var(index);
free_var(list);
PUSH_ERROR(E_RANGE);
@@ -1315,7 +1317,7 @@ do { \
free_var(from);
PUSH_ERROR(E_TYPE);
} else {
- int len = (base.type == TYPE_STR ? strlen(base.v.str)
+ int len = (base.type == TYPE_STR ? memo_strlen(base.v.str)
: base.v.list[0].v.num);
if (from.v.num <= to.v.num
&& (from.v.num <= 0 || from.v.num > len
@@ -1681,7 +1683,7 @@ do { \
free_var(value);
PUSH_ERROR(E_TYPE);
} else if (rangeset_check(base.type == TYPE_STR
- ? strlen(base.v.str)
+ ? memo_strlen(base.v.str)
: base.v.list[0].v.num,
from.v.num, to.v.num)) {
free_var(base);
@@ -1704,7 +1706,7 @@ do { \
v.type = TYPE_INT;
item = RUN_ACTIV.base_rt_stack[i];
if (item.type == TYPE_STR) {
- v.v.num = strlen(item.v.str);
+ v.v.num = memo_strlen(item.v.str);
PUSH(v);
} else if (item.type == TYPE_LIST) {
v.v.num = item.v.list[0].v.num;
@@ -2872,6 +2874,13 @@ char rcsid_execute[] = "$Id$";
/*
* $Log$
+ * Revision 1.17 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.16 2004/05/22 01:25:43 wrog
* merging in WROGUE changes (W_SRCIP, W_STARTUP, W_OOB)
*
diff --git a/list.c b/list.c
index 094c28b..ee1f4ac 100644
--- a/list.c
+++ b/list.c
@@ -343,8 +343,8 @@ strrangeset(Var base, int from, int to, Var value)
{
/* base and value are free'd */
int index, offset = 0;
- int val_len = strlen(value.v.str);
- int base_len = strlen(base.v.str);
+ int val_len = memo_strlen(value.v.str);
+ int base_len = memo_strlen(base.v.str);
int lenleft = (from > 1) ? from - 1 : 0;
int lenmiddle = val_len;
int lenright = (base_len > to) ? base_len - to : 0;
@@ -416,7 +416,7 @@ bf_length(Var arglist, Byte next, void *vdata, Objid progr)
break;
case TYPE_STR:
r.type = TYPE_INT;
- r.v.num = strlen(arglist.v.list[1].v.str);
+ r.v.num = memo_strlen(arglist.v.list[1].v.str);
break;
default:
free_var(arglist);
@@ -565,7 +565,7 @@ bf_crypt(Var arglist, Byte next, void *vdata, Objid progr)
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
extern const char *crypt(const char *, const char *);
- if (arglist.v.list[0].v.num == 1 || strlen(arglist.v.list[2].v.str) < 2) {
+ if (arglist.v.list[0].v.num == 1 || memo_strlen(arglist.v.list[2].v.str) < 2) {
/* provide a random 2-letter salt, works with old and new crypts */
salt[0] = saltstuff[RANDOM() % (int) strlen(saltstuff)];
salt[1] = saltstuff[RANDOM() % (int) strlen(saltstuff)];
@@ -825,7 +825,7 @@ check_subs_list(Var subs)
|| subs.v.list[4].type != TYPE_STR)
return 1;
subj = subs.v.list[4].v.str;
- subj_length = strlen(subj);
+ subj_length = memo_strlen(subj);
if (invalid_pair(subs.v.list[1].v.num, subs.v.list[2].v.num,
subj_length))
return 1;
@@ -855,7 +855,7 @@ bf_substitute(Var arglist, Byte next, void *vdata, Objid progr)
char c = '\0';
template = arglist.v.list[1].v.str;
- template_length = strlen(template);
+ template_length = memo_strlen(template);
subs = arglist.v.list[2];
if (check_subs_list(subs)) {
@@ -863,7 +863,7 @@ bf_substitute(Var arglist, Byte next, void *vdata, Objid progr)
return make_error_pack(E_INVARG);
}
subject = subs.v.list[4].v.str;
- subject_length = strlen(subject);
+ subject_length = memo_strlen(subject);
s = new_stream(template_length);
ans.type = TYPE_STR;
@@ -964,7 +964,7 @@ bf_string_hash(Var arglist, Byte next, void *vdata, Objid progr)
const char *str = arglist.v.list[1].v.str;
r.type = TYPE_STR;
- r.v.str = hash_bytes(str, strlen(str));
+ r.v.str = hash_bytes(str, memo_strlen(str));
free_var(arglist);
return make_var_pack(r);
}
@@ -976,7 +976,7 @@ bf_value_hash(Var arglist, Byte next, void *vdata, Objid progr)
const char *lit = value_to_literal(arglist.v.list[1]);
r.type = TYPE_STR;
- r.v.str = hash_bytes(lit, strlen(lit));
+ r.v.str = hash_bytes(lit, memo_strlen(lit));
free_var(arglist);
return make_var_pack(r);
}
@@ -1143,6 +1143,13 @@ char rcsid_list[] = "$Id$";
/*
* $Log$
+ * Revision 1.7 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.6 2001/03/12 00:16:29 bjj
* bf_crypt now passes the entire second argument as the salt to
* the C crypt() routine. This works fine for traditional DES crypts
diff --git a/options.h b/options.h
index fc518d1..310e65b 100644
--- a/options.h
+++ b/options.h
@@ -274,6 +274,13 @@
#define STRING_INTERNING /* */
/******************************************************************************
+ * Store the length of the string WITH the string rather than recomputing
+ * it each time it is needed.
+ ******************************************************************************
+ */
+/* #define MEMO_STRLEN */
+
+/******************************************************************************
* This package comes with a copy of the implementation of malloc() from GNU
* Emacs. This is a very nice and reasonably portable implementation, but some
* systems, notably the NeXT machine, won't allow programs to provide their own
@@ -384,6 +391,13 @@
/*
* $Log$
+ * Revision 1.10 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.9 2004/05/22 01:25:44 wrog
* merging in WROGUE changes (W_SRCIP, W_STARTUP, W_OOB)
*
diff --git a/program.c b/program.c
index d3d752f..24ae610 100644
--- a/program.c
+++ b/program.c
@@ -78,7 +78,7 @@ program_bytes(Program * p)
count += sizeof(const char *) * p->num_var_names;
for (i = 0; i < p->num_var_names; i++)
- count += strlen(p->var_names[i]) + 1;
+ count += memo_strlen(p->var_names[i]) + 1;
return count;
}
@@ -116,6 +116,13 @@ char rcsid_program[] = "$Id$";
/*
* $Log$
+ * Revision 1.6 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.5 1998/12/14 13:18:48 nop
* Merge UNSAFE_OPTS (ref fixups); fix Log tag placement to fit CVS whims
*
diff --git a/storage.c b/storage.c
index 0e051f4..bf369d8 100644
--- a/storage.c
+++ b/storage.c
@@ -43,7 +43,11 @@ refcount_overhead(Memory_Type type)
/* for systems with picky double alignment */
return MAX(sizeof(int), sizeof(double));
case M_STRING:
+#ifdef MEMO_STRLEN
+ return sizeof(int) + sizeof(int);
+#else
return sizeof(int);
+#endif /* MEMO_STRLEN */
case M_LIST:
/* for systems with picky pointer alignment */
return MAX(sizeof(int), sizeof(Var *));
@@ -82,6 +86,10 @@ mymalloc(unsigned size, Memory_Type type)
if (offs) {
memptr += offs;
((int *) memptr)[-1] = 1;
+#ifdef MEMO_STRLEN
+ if (type == M_STRING)
+ ((int *) memptr)[-2] = size - 1;
+#endif /* MEMO_STRLEN */
}
return memptr;
}
@@ -108,7 +116,7 @@ str_dup(const char *s)
addref(emptystring);
return emptystring;
} else {
- r = (char *) mymalloc(strlen(s) + 1, M_STRING);
+ r = (char *) mymalloc(strlen(s) + 1, M_STRING); /* NO MEMO HERE */
strcpy(r, s);
}
return r;
@@ -129,19 +137,18 @@ myrealloc(void *ptr, unsigned size, Memory_Type type)
alloc_real_size[type] -= malloc_real_size(ptr);
#endif
- ptr = realloc((char *) ptr - offs, size + offs);
- if (!ptr) {
- sprintf(msg, "memory re-allocation (size %u) failed!", size);
- panic(msg);
- }
-
+ ptr = realloc((char *) ptr - offs, size + offs);
+ if (!ptr) {
+ sprintf(msg, "memory re-allocation (size %u) failed!", size);
+ panic(msg);
+ }
#ifdef USE_GNU_MALLOC
alloc_size[type] += malloc_size(ptr);
alloc_real_size[type] += malloc_real_size(ptr);
}
#endif
- return (char *)ptr + offs;
+ return (char *) ptr + offs;
}
void
@@ -179,6 +186,7 @@ free_str(const char *s)
if (delref(s) == 0)
myfree((void *) s, M_STRING);
}
+
#endif
Var
@@ -225,6 +233,13 @@ char rcsid_storage[] = "$Id$";
/*
* $Log$
+ * Revision 1.6 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.5 1998/12/14 13:18:59 nop
* Merge UNSAFE_OPTS (ref fixups); fix Log tag placement to fit CVS whims
*
diff --git a/storage.h b/storage.h
index 11ca34a..1bec770 100644
--- a/storage.h
+++ b/storage.h
@@ -47,17 +47,35 @@ extern void myfree(void *where, Memory_Type type);
extern void *mymalloc(unsigned size, Memory_Type type);
extern void *myrealloc(void *where, unsigned size, Memory_Type type);
-static inline void /* XXX was extern, fix for non-gcc compilers */
+static inline void /* XXX was extern, fix for non-gcc compilers */
free_str(const char *s)
{
if (delref(s) == 0)
myfree((void *) s, M_STRING);
}
+#ifdef MEMO_STRLEN
+/*
+ * Using the same mechanism as ref_count.h uses to hide Value ref counts,
+ * keep a memozied strlen in the storage with the string.
+ */
+#define memo_strlen(X) ((void)0, (((int *)(X))[-2]))
+#else
+#define memo_strlen(X) strlen(X)
+
+#endif /* MEMO_STRLEN */
+
#endif /* Storage_h */
/*
* $Log$
+ * Revision 1.6 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.5 1998/12/14 13:19:00 nop
* Merge UNSAFE_OPTS (ref fixups); fix Log tag placement to fit CVS whims
*
diff --git a/str_intern.c b/str_intern.c
index 421da70..78c6413 100644
--- a/str_intern.c
+++ b/str_intern.c
@@ -243,7 +243,7 @@ str_intern(const char *s)
if (e != NULL) {
intern_allocations_saved++;
- intern_bytes_saved += strlen(s);
+ intern_bytes_saved += memo_strlen(e->s);
return str_ref(e->s);
}
diff --git a/tasks.c b/tasks.c
index 0c46e0b..6414a55 100644
--- a/tasks.c
+++ b/tasks.c
@@ -1666,8 +1666,8 @@ activation_bytes(activation * ap)
}
/* XXX ignore bi_func_data, it's an opaque type. */
total += value_bytes(ap->temp) - sizeof(Var);
- total += strlen(ap->verb) + 1;
- total += strlen(ap->verbname) + 1;
+ total += memo_strlen(ap->verb) + 1;
+ total += memo_strlen(ap->verbname) + 1;
return total;
}
@@ -2237,6 +2237,13 @@ char rcsid_tasks[] = "$Id$";
/*
* $Log$
+ * Revision 1.14 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.13 2004/05/28 07:53:32 wrog
* added "intrinsic-commands" connection option
*
diff --git a/utils.c b/utils.c
index 98b90a8..2412a0d 100644
--- a/utils.c
+++ b/utils.c
@@ -364,7 +364,7 @@ value_bytes(Var v)
switch (v.type) {
case TYPE_STR:
- size += strlen(v.v.str) + 1;
+ size += memo_strlen(v.v.str) + 1;
break;
case TYPE_FLOAT:
size += sizeof(double);
@@ -443,6 +443,13 @@ char rcsid_utils[] = "$Id$";
/*
* $Log$
+ * Revision 1.8 2006/09/07 00:55:02 bjj
+ * Add new MEMO_STRLEN option which uses the refcounting mechanism to
+ * store strlen with strings. This is basically free, since most string
+ * allocations are rounded up by malloc anyway. This saves lots of cycles
+ * computing strlen. (The change is originally from jitmoo, where I wanted
+ * inline range checks for string ops).
+ *
* Revision 1.7 2002/08/18 09:47:26 bjj
* Finally made free_activation() take a pointer after noticing how !$%^&
* much time it was taking in a particular profiling run.