Short: Large shared string refcounts
From: Lars
Date: 2001-02-08
Type: Feature
State: Done - implemented in 3.2.9-dev.260, activated in 3.2.10
Increases the string refcounter from ushort to ulong.
----------------------------------------
Index: 0.67/src/stralloc.h
--- 0.67/src/stralloc.h Tue, 22 Aug 2000 14:14:00 -0600 lduening (lddev/b/27_stralloc.h 1.2 644)
+++ 0.67(w)/src/stralloc.h Tue, 06 Feb 2001 11:54:20 -0700 lduening (lddev/b/27_stralloc.h 1.2 644)
@@ -12,26 +12,26 @@
/* --- Macros --- */
-#define SHSTR_OVERHEAD (sizeof(unsigned short) + sizeof(char *))
+#define SHSTR_OVERHEAD (sizeof(unsigned long) + sizeof(char *))
/* Overhead of a shared string, used in interpret:apply_low()
* for a heuristic.
*/
#define SHSTR_NEXT(str) \
- (*(char **)((char *) (str) - sizeof(unsigned short) - sizeof(char *)))
+ (*(char **)((char *) (str) - sizeof(unsigned long) - sizeof(char *)))
/* char* SHSTR_NEXT(char*): return the pointer to the next string
* in the same hash chain.
*/
#define SHSTR_REFS(str) \
- (*(unsigned short *)((char *) (str) - sizeof(unsigned short)))
+ (*(unsigned long *)((char *) (str) - sizeof(unsigned long)))
- /* ushort SHSTR_REFS(char*): return the number of refs to this string.
+ /* ulong SHSTR_REFS(char*): return the number of refs to this string.
*/
#define SHSTR_BLOCK(str) \
- ((char *)(str) - sizeof(unsigned short) - sizeof(char *))
+ ((char *)(str) - sizeof(unsigned long) - sizeof(char *))
/* char* SHSTR_BLOCK(char*): return a pointer to the first byte
* of the memory area of this string.
@@ -40,14 +40,14 @@
#ifdef MALLOC_smalloc
#define shstr_malloced_length(str) ( *( \
- (p_uint *)(str-sizeof(char*)-sizeof(unsigned short))\
+ (p_uint *)(str-sizeof(char*)-sizeof(unsigned long))\
- SMALLOC_OVERHEAD) - SMALLOC_OVERHEAD )
#else
#define malloc_size_mask() (~0)
#define shstr_malloced_length(str) (\
- (sizeof(char*) + sizeof(char *) + sizeof(short) +\
+ (sizeof(char*) + sizeof(char *) + sizeof(unsigned long) +\
strlen(str) + 1 + sizeof(char *) - 1) / sizeof(char *) - 1)
#endif
Index: 0.67/src/stralloc.c
--- 0.67/src/stralloc.c Tue, 22 Aug 2000 14:14:00 -0600 lduening (lddev/b/28_stralloc.c 1.3 644)
+++ 0.67(w)/src/stralloc.c Tue, 06 Feb 2001 11:31:43 -0700 lduening (lddev/b/28_stralloc.c 1.3 644)
@@ -8,7 +8,7 @@
* safely be deallocated again.
*
* To convert non-shared strings into shared strings quickly, the shared
- * strings are hashed over their first 20 characters and arranged in
+ * strings are hashed over their first 100 characters and arranged in
* a hash table with HTABLE_SIZE entries. Every entry points to the head
* of a chain of strings with equal hash. To make access even faster,
* the chains are rearranged after every search so that the recently found
@@ -22,7 +22,7 @@
* struct shared_string
* {
* char * next;
- * ushort refs;
+ * ulong refs;
* char str[];
* }
*
@@ -145,7 +145,7 @@
struct str_shadow_s {
str_shadow_t *next; /* Next shadow in hash chain */
char *str; /* The shadowed string */
- unsigned short ref; /* The shadowed refcount */
+ unsigned long ref; /* The shadowed refcount */
char *snext; /* The "next" pointer of the shadowed string */
};
@@ -173,19 +173,19 @@
fatal("check_string: String %p vs shadow %p\n", s, sh);
if (!s && sh)
- fatal("check_string: String %p vs shadow %p (s %p, r%hu, n %p)\n"
+ fatal("check_string: String %p vs shadow %p (s %p, r%lu, n %p)\n"
, s, sh, sh->str, sh->ref, sh->snext);
#ifdef VERBOSE_CS
- printf("DEBUG: compare sh %p (s %p, r %hu, n %p)\n", sh, sh->str, sh->ref, sh->snext);
- printf("DEBUG: with s %p (r %hu, n %p)\n", s, REFS(s), NEXT(s));
+ printf("DEBUG: compare sh %p (s %p, r %lu, n %p)\n", sh, sh->str, sh->ref, sh->snext);
+ printf("DEBUG: with s %p (r %lu, n %p)\n", s, REFS(s), NEXT(s));
#endif
if (sh->str != s)
fatal("check_string: String %p '%s', shadow expected string %p '%s'\n"
, s, s, sh->str, sh->str);
if (sh->ref != REFS(s))
- fatal("check_string: String %p '%s' has %hu refs, shadow expected %hu refs\n", s, s, REFS(s), sh->ref);
+ fatal("check_string: String %p '%s' has %lu refs, shadow expected %lu refs\n", s, s, REFS(s), sh->ref);
if (sh->snext != NEXT(s))
fatal("check_string: String %p '%s's next is %p, shadow expected %p\n", s, s, NEXT(s), sh->snext);
@@ -280,7 +280,7 @@
sh->ref++;
check_string(s, sh);
#ifdef VERBOSE_CS
- printf("DEBUG: ref'd s %p (%hu, %p) and sh %p (%p, %hu, %p)\n", s, REFS(s), NEXT(s), sh, sh->str, sh->ref, sh->snext);
+ printf("DEBUG: ref'd s %p (%lu, %p) and sh %p (%p, %lu, %p)\n", s, REFS(s), NEXT(s), sh, sh->str, sh->ref, sh->snext);
#endif
} /* ref_shadow_string() */
@@ -443,7 +443,7 @@
#endif
}
#ifdef VERBOSE_CS
- printf("DEBUG: found s %p (%hu, %p) and sh %p (%p, %hu, %p)\n", curr, REFS(curr), NEXT(curr), scurr, scurr->str, scurr->ref, scurr->snext);
+ printf("DEBUG: found s %p (%lu, %p) and sh %p (%p, %lu, %p)\n", curr, REFS(curr), NEXT(curr), scurr, scurr->str, scurr->ref, scurr->snext);
#endif
return curr;
}
@@ -672,7 +672,7 @@
sh = find_shadow(str);
check_string(str, sh);
#ifdef VERBOSE_CS
- printf("DEBUG: free s %p (%hu-1, %p) and sh %p (%p, %hu, %p)\n", str, REFS(str), NEXT(str), sh, sh->str, sh->ref, sh->snext);
+ printf("DEBUG: free s %p (%lu-1, %p) and sh %p (%p, %lu, %p)\n", str, REFS(str), NEXT(str), sh, sh->str, sh->ref, sh->snext);
#endif
}
#endif
Index: 0.67/src/smalloc.h
--- 0.67/src/smalloc.h Mon, 29 Jan 2001 10:05:27 -0700 lduening (lddev/b/31_smalloc.h 1.1.1.3 644)
+++ 0.67(w)/src/smalloc.h Tue, 06 Feb 2001 11:52:14 -0700 lduening (lddev/b/31_smalloc.h 1.1.1.3 644)
@@ -77,9 +77,9 @@
{
i = (long)
((*(p_uint*)
- (p - sizeof(short) - (SMALLOC_OVERHEAD+1) * SIZEOF_CHAR_P) &
+ (p - sizeof(unsigned long) - (SMALLOC_OVERHEAD+1) * SIZEOF_CHAR_P) &
MASK) * SIZEOF_CHAR_P -
- sizeof(short) -
+ sizeof(unsigned long) -
(SMALLOC_OVERHEAD+2) * SIZEOF_CHAR_P
);
if (i >= 0)
Index: 0.67/src/interpret.c
--- 0.67/src/interpret.c Thu, 01 Feb 2001 13:40:13 -0700 lduening (lddev/c/41_interpret. 1.4.1.18 644)
+++ 0.67(w)/src/interpret.c Tue, 06 Feb 2001 11:37:26 -0700 lduening (lddev/c/41_interpret. 1.4.1.18 644)
@@ -19146,22 +19146,17 @@
);
#endif
- if ( ((p_int)fun & 2) != ((p_int)SHSTR_OVERHEAD & 2) )
- {
- /* Heuristic to find out if fun is an unshared string,
- * building on the six-byte-overhead of shared strings.
- * This means that every shared string has a set bit 1,
- * whereas other strings have no overhead and thus bit 1
- * cleared. Function names are always shared, so if there
- * is no shared string twin for fun, the called function does
- * not exist anywhere. As a side effect, we get the shared
- * string for fun which makes the cache-lookup much faster.
- */
- fun = findstring(fun);
- if (!fun)
- goto failure2;
- }
- /* *fun is now (more or less) guaranteed to be a shared string */
+ /* Lookup the shared string for <fun>. Function names are always
+ * shared, so if there is no shared string twin for <fun>, the
+ * called function does not exist anywhere. As a side effect,
+ * we get the shared string for <fun> which makes the cache-lookup
+ * much faster.
+ */
+ fun = findstring(fun);
+ if (!fun)
+ goto failure2;
+
+ /* *fun is now guaranteed to be a shared string */
/* Get the hashed index into the cache */
ix =
@@ -19240,11 +19235,12 @@
#ifdef APPLY_CACHE_STAT
apply_cache_miss++;
#endif
+
/* This call to findstring() is not really necessary, but serves
* as safeguard should a non-shared string escape the attention
* of the 'heuristic' filter before.
*/
- shared_name = (cache[ix].name == fun) ? fun : findstring(fun);
+ shared_name = fun;
if ( NULL != shared_name)
{
int fx;
Index: 0.67/src/gcollect.c
--- 0.67/src/gcollect.c Mon, 29 Jan 2001 10:05:27 -0700 lduening (lddev/e/51_gcollect.c 1.1.1.5 644)
+++ 0.67(w)/src/gcollect.c Tue, 06 Feb 2001 11:39:29 -0700 lduening (lddev/e/51_gcollect.c 1.1.1.5 644)
@@ -171,8 +171,8 @@
* Return TRUE if the marker was not set, FALSE else.
*/
-#define STRING_REFS(str) (*(unsigned short *)((char *) (str)\
- - sizeof(unsigned short)))
+#define STRING_REFS(str) (*(unsigned long *)((char *) (str)\
+ - sizeof(unsigned long)))
/* Return the refcount of shared string <str>
*/
@@ -180,7 +180,7 @@
#define MARK_STRING_REF(str) ((void)(\
STRING_REFS(str)++ || (\
- CHECK_REF( (str)-sizeof(short)-sizeof(char *) ) ||\
+ CHECK_REF( (str)-sizeof(unsigned long)-sizeof(char *) ) ||\
/* reached max ref count, which is given as 0... */ \
STRING_REFS(str)--\
))\
@@ -195,7 +195,7 @@
static void MARK_STRING_REF (char * str)
{
- if (CHECK_REF( (str)-sizeof(short)-sizeof(char *) ) )
+ if (CHECK_REF( (str)-sizeof(unsigned long)-sizeof(char *) ) )
{
/* First visit to this block */
STRING_REFS(str)++;
@@ -1468,12 +1468,12 @@
}
if (svp->x.string_type == STRING_SHARED &&
is_freed(SHSTR_BLOCK(svp->u.string),
- sizeof(char *) + sizeof(short) + 1) )
+ sizeof(char *) + sizeof(unsigned long) + 1) )
{
WRITES(d, "Shared string in freed block 0x");
write_x(d, (p_uint)(
- (unsigned *)(block-sizeof(char *)-sizeof(short))
+ (unsigned *)(block-sizeof(char *)-sizeof(unsigned long))
- SMALLOC_OVERHEAD
));
WRITES(d, "\n");
Index: 0.67/CHANGELOG
--- 0.67/CHANGELOG Tue, 06 Feb 2001 11:01:01 -0700 lduening (lddev/E/25_CHANGELOG 1.16.1.46 644)
+++ 0.67(w)/CHANGELOG Tue, 06 Feb 2001 12:03:55 -0700 lduening (lddev/E/25_CHANGELOG 1.16.1.46 644)
@@ -5,6 +5,8 @@
- (strfuns.c) When (re)allocating the strbuf buffer, the length was
accidentally casted down to unsigned short, causing the program
to write outside the allocated memory (reported by Sebastian).
+ - (gcollect.c, stralloc, smalloc.h) Changed the shared string refcounter
+ from unsigned short to unsigned long.
05-Feb-2001 (Lars Duening)
- (smalloc.c) Using the time_stamp() from within the allocation routines
----------------------------------------