aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.