Hi,
At Tue, 26 Oct 2004 11:27:59 +0900,
Hal Fulton wrote in [ruby-talk:117698]:
OK, I never knew that.
The file is 11,756 lines (down from 22,000).
Well, 2,097,151 lines are enough?
Index: gc.c
===================================================================
RCS file: /cvs/ruby/src/ruby/gc.c,v
retrieving revision 1.188
diff -U2 -p -d -r1.188 gc.c
--- gc.c 6 Oct 2004 07:40:04 -0000 1.188
+++ gc.c 26 Oct 2004 15:16:41 -0000
@@ -509,7 +509,69 @@ init_mark_stack()
#define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack)
-
+
static st_table *source_filenames;
+#ifdef NODE_SEGMENTED_LINENO
+
+static int
+srcfile_cmp(s1, s2)
+ const char *s1, *s2;
+{
+ int ret = strcmp(s1, s2);
+ if (ret == 0) return 0;
+ return s1[srcfile_lineno - srcfile_offset]
+ - s2[srcfile_lineno - srcfile_offset];
+}
+
+int strhash _((const char *));
+
+static int
+srcfile_hash(s)
+ const char *s;
+{
+ return strhash(s) ^ s[srcfile_lineno - srcfile_offset];
+}
+
+static struct st_hash_type type_srchash = {
+ srcfile_cmp,
+ srcfile_hash,
+};
+
+#define init_srcfile_table() st_init_table(&type_srchash)
+
+char *
+rb_source_filenameline(f, n)
+ const char *f;
+ unsigned int n;
+{
+ char *name, *ptr;
+ long len = strlen(f) + 1;
+
+ ptr = ALLOC_N(char, len + srcfile_offset);
+ MEMCPY(ptr + srcfile_offset, f, char, len);
+ f = ptr + srcfile_offset;
+ ptr[srcfile_lineno] = (char)(n >> (sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT));
+
+ if (!st_lookup(source_filenames, (st_data_t)f, (st_data_t *)&name)) {
+ name = ptr;
+ ptr[srcfile_gcmark] = 0;
+ ptr += srcfile_offset;
+ st_add_direct(source_filenames, (st_data_t)ptr, (st_data_t)name);
+ return ptr;
+ }
+ xfree(ptr);
+ return name + srcfile_offset;
+}
+
+char *
+rb_source_filename(f)
+ const char *f;
+{
+ return rb_source_filenameline(f, 0);
+}
+
+#else
+#define init_srcfile_table() st_init_strtable()
+
char *
rb_source_filename(f)
@@ -520,12 +582,15 @@ rb_source_filename(f)
if (!st_lookup(source_filenames, (st_data_t)f, (st_data_t *)&name)) {
long len = strlen(f) + 1;
- char *ptr = name = ALLOC_N(char, len + 1);
- *ptr++ = 0;
+ char *ptr = name = ALLOC_N(char, len + srcfile_offset);
+ ptr[srcfile_gcmark] = 0;
+ ptr += srcfile_offset;
MEMCPY(ptr, f, char, len);
st_add_direct(source_filenames, (st_data_t)ptr, (st_data_t)name);
return ptr;
}
- return name + 1;
+ return name + srcfile_offset;
}
+#endif
+
static void
@@ -534,5 +599,5 @@ mark_source_filename(f)
{
if (f) {
- f[-1] = 1;
+ f[srcfile_gcmark - srcfile_offset] = 1;
}
}
@@ -542,10 +607,10 @@ sweep_source_filename(key, value)
char *key, *value;
{
- if (*value) {
- *value = 0;
+ if (value[srcfile_gcmark]) {
+ value[srcfile_gcmark] = 0;
return ST_CONTINUE;
}
else {
- free(value);
+ xfree(value);
return ST_DELETE;
}
@@ -1922,5 +1987,5 @@ Init_GC()
finalizers = rb_ary_new();
- source_filenames = st_init_strtable();
+ source_filenames = init_srcfile_table();
nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.156
diff -U2 -p -d -r1.156 intern.h
--- intern.h 6 Oct 2004 07:40:04 -0000 1.156
+++ intern.h 26 Oct 2004 15:21:45 -0000
@@ -239,4 +239,5 @@ NORETURN(void rb_memerror __((void)));
int ruby_stack_check _((void));
int ruby_stack_length _((VALUE**));
+char *rb_source_filenameline _((const char*, unsigned int));
char *rb_source_filename _((const char*));
void rb_gc_mark_locations _((VALUE*, VALUE*));
Index: node.h
===================================================================
RCS file: /cvs/ruby/src/ruby/node.h,v
retrieving revision 1.57
diff -U2 -p -d -r1.57 node.h
--- node.h 2 Oct 2004 11:34:13 -0000 1.57
+++ node.h 26 Oct 2004 15:17:03 -0000
@@ -164,8 +164,26 @@ typedef struct RNode {
#define NODE_LSHIFT (FL_USHIFT+8)
-#define NODE_LMASK (((long)1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)
-#define nd_line(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))
-#define nd_set_line(n,l) \
+#define NODE_LBITS (SIZEOF_VOIDP*CHAR_BIT-NODE_LSHIFT)
+#define NODE_LMASK (((long)1<<NODE_LBITS)-1)
+#define NODE_SEGMENTED_LINENO (NODE_LBITS > 20)
+
+enum {
+ srcfile_gcmark,
+#ifdef NODE_SEGMENTED_LINENO
+ srcfile_lineno,
+#endif
+ srcfile_offset
+};
+
+#define nd_line_low(n) ((unsigned int)(((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK))
+#define nd_set_line_low(n,l) \
RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))
+#ifdef NODE_SEGMENTED_LINENO
+#define nd_line(n) rb_node_line(n)
+#define nd_set_line(n,l) rb_node_set_line(n,l)
+#else
+#define nd_line(n) nd_line_low(n)
+#define nd_set_line(n,l) nd_set_line_low(n,l)
+#endif
#define nd_head u1.node
@@ -355,4 +373,6 @@ NODE *rb_compile_file _((const char*, VA
void rb_add_method _((VALUE, ID, NODE *, int));
NODE *rb_node_newnode _((enum node_type,VALUE,VALUE,VALUE));
+unsigned int rb_node_line _((NODE *));
+void rb_node_set_line _((NODE *, unsigned int));
NODE* rb_method_node _((VALUE klass, ID id));
Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.353
diff -U2 -p -d -r1.353 parse.y
--- parse.y 20 Oct 2004 15:44:05 -0000 1.353
+++ parse.y 26 Oct 2004 15:32:09 -0000
@@ -6456,4 +6456,30 @@ yylex(p)
#ifndef RIPPER
+#ifdef NODE_SEGMENTED_LINENO
+unsigned int
+rb_node_line(node)
+ NODE *node;
+{
+ unsigned int l = nd_line_low(node);
+ const char *file = node->nd_file;
+ if (file) {
+ l |= (unsigned char)file[srcfile_lineno-srcfile_offset] << NODE_LBITS;
+ }
+ return l;
+}
+
+void
+rb_node_set_line(node, line)
+ NODE *node;
+ unsigned int line;
+{
+ const char *file = node->nd_file;
+ if (file) {
+ node->nd_file = rb_source_filenameline(file, line);
+ }
+ nd_set_line_low(node, line);
+}
+#endif
+
NODE*
rb_node_newnode(type, a0, a1, a2)
@@ -6465,6 +6491,6 @@ rb_node_newnode(type, a0, a1, a2)
n->flags |= T_NODE;
nd_set_type(n, type);
- nd_set_line(n, ruby_sourceline);
n->nd_file = ruby_sourcefile;
+ nd_set_line(n, ruby_sourceline);
n->u1.value = a0;
Index: st.c
===================================================================
RCS file: /cvs/ruby/src/ruby/st.c,v
retrieving revision 1.30
diff -U2 -p -d -r1.30 st.c
--- st.c 23 Sep 2004 00:51:31 -0000 1.30
+++ st.c 26 Oct 2004 15:31:15 -0000
@@ -42,5 +42,5 @@ static struct st_hash_type type_numhash
/* extern int strcmp(const char *, const char *); */
-static int strhash(const char *);
+int strhash(const char *);
static struct st_hash_type type_strhash = {
strcmp,
@@ -530,5 +530,5 @@ st_foreach(table, func, arg)
}
-static int
+int
strhash(string)
register const char *string;