[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Help-smalltalk] faster startup 10/n - why do we need F_FREE?
From: |
Paolo Bonzini |
Subject: |
[Help-smalltalk] faster startup 10/n - why do we need F_FREE? |
Date: |
Thu, 28 Dec 2006 17:16:12 +0100 |
User-agent: |
Thunderbird 1.5.0.9 (Macintosh/20061207) |
This is cute. We have plenty of flag bits to mark live objects, so we
don't need F_FREE! This frees up a flag bit in the OOP data structures,
and avoids walking the free OOPs at startup (no matter if image loading
or starting from scratch) just to set that bit, saving 5-6%.
Paolo
* looking for address@hidden/smalltalk--devo--2.2--patch-226 to compare with
* comparing to address@hidden/smalltalk--devo--2.2--patch-226
M libgst/gstpriv.h
M libgst/oop.c
M libgst/oop.h
M libgst/print.c
M libgst/save.c
M libgst/oop.inl
* modified files
--- orig/libgst/gstpriv.h
+++ mod/libgst/gstpriv.h
@@ -258,9 +258,6 @@ enum {
saves and loads. */
F_RUNTIME = 0xFF8000U,
- /* Set if the OOP is currently unused. */
- F_FREE = 0x10U,
-
/* Set if the references to the instance variables of the object
are weak. */
F_WEAK = 0x20U,
--- orig/libgst/oop.c
+++ mod/libgst/oop.c
@@ -488,14 +488,16 @@ alloc_oop_table (size_t size)
_gst_mem.num_free_oops = size;
+#if 0
/* mark the OOPs as available */
PREFETCH_START (_gst_mem.ot, PREF_WRITE | PREF_NTA);
for (oop = _gst_mem.ot;
oop < &_gst_mem.ot[_gst_mem.ot_size]; oop++)
{
PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
- oop->flags = F_FREE;
+ oop->flags = 0;
}
+#endif
_gst_mem.first_allocated_oop = _gst_mem.ot;
_gst_mem.last_allocated_oop = _gst_mem.last_swept_oop = _gst_mem.ot - 1;
@@ -520,14 +522,16 @@ _gst_realloc_oop_table (size_t newSize)
return (false);
}
+#if 0
/* mark the new OOPs as available */
PREFETCH_START (&_gst_mem.ot[_gst_mem.ot_size], PREF_WRITE | PREF_NTA);
for (oop = &_gst_mem.ot[_gst_mem.ot_size];
oop < &_gst_mem.ot[newSize]; oop++)
{
PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
- oop->flags = F_FREE;
+ oop->flags = 0;
}
+#endif
_gst_mem.num_free_oops += newSize - _gst_mem.ot_size;
_gst_mem.ot_size = newSize;
@@ -1438,7 +1442,7 @@ _gst_sweep_oop (OOP oop)
_gst_mem_free (_gst_mem.old, oop->object);
}
- oop->flags = F_FREE;
+ oop->flags = 0;
}
void
@@ -1981,20 +1985,13 @@ _gst_copy_an_oop (OOP oop)
printf ("Invalid size for OOP %p (%p)\n", oop, obj);
abort ();
}
-#endif
- if UNCOMMON (oop->flags & F_FREE)
+ if UNCOMMON (oop->flags == 0)
{
printf ("Free OOP %p was referenced\n", oop);
- /* If we're lucky, we can print some information on it...
- if we're not, we segfault: not that bad given that
- we'll abort pretty soon! */
- oop->flags &= ~F_FREE;
- _gst_display_oop (oop);
abort ();
}
-#if defined (GC_DEBUGGING)
if UNCOMMON ((oop->flags & F_OLD) ||
IS_SURVIVOR_ADDR(obj, _gst_mem.active_half == &_gst_mem.surv[1]))
{
--- orig/libgst/oop.h
+++ mod/libgst/oop.h
@@ -220,7 +220,7 @@ struct memory_space
/* The OOP flag corresponding to the active survivor space */
int active_flag;
- /* The OOP flag corresponding to the inactive survivor space, plus F_FREE */
+ /* The OOP flag corresponding to the inactive survivor space. */
int live_flags;
/* These hold onto the object incubator's state */
--- orig/libgst/oop.inl
+++ mod/libgst/oop.inl
@@ -106,7 +106,7 @@ static inline OOP alloc_oop (PTR obj, in
((oop)->flags & F_REACHABLE)
#define IS_OOP_FREE(oop) \
- ((oop)->flags & F_FREE)
+ ((oop)->flags == 0)
/* Checks to see if INDEX (a long index into the OOP table, 1 based
due to being called from Smalltalk via a primitive) represents a
--- orig/libgst/print.c
+++ mod/libgst/print.c
@@ -320,7 +320,7 @@ _gst_classify_addr (void *addr)
void
_gst_display_oop_short (OOP oop)
{
- if (oop->flags & F_FREE)
+ if (IS_OOP_FREE (oop))
printf ("%-10p Free\n", oop);
else
{
@@ -351,7 +351,7 @@ _gst_display_oop (OOP oop)
return;
}
- if (oop->flags & F_FREE)
+ if (IS_OOP_FREE (oop))
printf ("%-10p Free\n", oop);
else
{
--- orig/libgst/save.c
+++ mod/libgst/save.c
@@ -355,7 +355,7 @@ make_oop_table_to_be_saved (struct save_
}
else
{
- myOOPTable[i].flags = F_FREE;
+ myOOPTable[i].flags = 0;
header->num_free_oops++;
}
}
@@ -535,7 +535,7 @@ load_oop_table (int imageFd)
int i;
/* Load in the valid OOP slots from previous dump. The others are already
- initialized to F_FREE. */
+ initialized to free (0). */
buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops);
if UNCOMMON (wrong_endianness)
fixup_byte_order (_gst_mem.ot,
@@ -564,8 +564,7 @@ load_normal_oops (int imageFd)
PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
flags = oop->flags;
-
- if (flags & F_FREE)
+ if (IS_OOP_FREE (oop))
continue;
/* FIXME: a small amount of garbage is saved that is produced
@@ -598,7 +597,7 @@ load_normal_oops (int imageFd)
buffer_read (imageFd, object, size);
if UNCOMMON (wrong_endianness)
fixup_byte_order (object,
- (oop->flags & F_BYTE)
+ (flags & F_BYTE)
? OBJ_HEADER_SIZE_WORDS
: size / sizeof (PTR));
@@ -609,9 +608,7 @@ load_normal_oops (int imageFd)
abort ();
}
- /* Remove flags that are invalid after an image has been loaded. */
oop->object = object;
-
if (flags & F_WEAK)
_gst_make_oop_weak (oop);
}
- [Help-smalltalk] faster startup 10/n - why do we need F_FREE?,
Paolo Bonzini <=