Article 4949 of rec.games.mud:
Path: news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!WATNXT3.UCR.EDU!rearl
From: rearl@WATNXT3.UCR.EDU (Robert Earl)
Newsgroups: rec.games.mud
Subject: MUCK Lite
Summary: patch for tinymuck 2.2
Keywords: TINY* PATCH SMALLER FASTER LESS FILLING
Message-ID: <9106140320.AA07293@.watnxt3.ucr.edu.>
Date: 14 Jun 91 02:19:12 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Lines: 218
X-Unparsable-Date: Thu, 13 Jun 91 19:20:13 GMT-0800

Here's a set of patches for TinyMUCK 2.2 to fix a majorly hoggish behavior:
what the vanilla server does is compile all the MUF code when it loads the
database.  This accounted for about 2.2 megs (25%) of MbongoMUCK's memory
usage; when this patch was applied, it not only loaded up much faster, it used
that much less memory.

Programs are only compiled on demand (when someone wants to run them) and
remain in memory after that.  I'm convinced the tiny performance hits taken
running programs for the first time will be compensated by a smaller process
and a speedy load from disk.  You can turn this feature off with a `#define
COMPILE_ON_LOAD' in db.c.

I think this patch requires that the previous patches be applied first.


The enclosed patch will also be available at finer FTP sites near you, such as
watnxt2.ucr.edu (192.31.146.189).



--robert/chupchups(EVIL!)


P.S.  I now have an account and I plan to continue development on MUCK 3.0, so
if anyone has suggestions or ideas, let me know!

--
______________________________________________________________________
			\					
 robert earl		/	"Love is a many splintered thing"
 rearl@watnxt3.ucr.edu	\		--Sisters of Mercy
 rearl@gnu.ai.mit.edu	/



--------8<-----cut here--------8<-----------
*** compile.c.orig	Fri Sep 28 12:31:58 1990
--- compile.c	Thu Jun 13 00:10:40 1991
***************
*** 159,165 ****
  			   if (line_copy) { \
  			      free ((void *) line_copy); \
  			      line_copy = NULL; \
! 			   } if (FLAGS(player) & INTERACTIVE){ \
  				notify(player, _buf); }              \
  			     else { \
  			        log_muf("MUF compiler warning in program %d:\n%s\n", (int) program, _buf); } \
--- 159,165 ----
  			   if (line_copy) { \
  			      free ((void *) line_copy); \
  			      line_copy = NULL; \
! 			   } if (player != NOTHING){ \
  				notify(player, _buf); }              \
  			     else { \
  			        log_muf("MUF compiler warning in program %d:\n%s\n", (int) program, _buf); } \
***************
*** 175,181 ****
  			   if (line_copy) { \
  			      free ((void *) line_copy); \
  			      line_copy = NULL; \
! 			   } if (FLAGS(player) & INTERACTIVE){ \
  				notify(player, _buf); }              \
  			     else { \
  			        log_muf("MUF compiler warning in program %d:\n%s\n", (int) program, _buf); } \
--- 175,181 ----
  			   if (line_copy) { \
  			      free ((void *) line_copy); \
  			      line_copy = NULL; \
! 			   } if (player != NOTHING) { \
  				notify(player, _buf); }              \
  			     else { \
  			        log_muf("MUF compiler warning in program %d:\n%s\n", (int) program, _buf); } \
*** db.c.orig	Sat Oct  6 16:34:10 1990
--- db.c	Thu Jun 13 00:10:41 1991
***************
*** 1149,1160 ****
      OWNER(objno) = getref(f);
      FLAGS(objno) &= ~INTERNAL;
      o -> sp.program.curr_line = 0;
-     o -> sp.program.first = read_program(objno);
      o -> sp.program.code = 0;
      o -> sp.program.siz = 0;
      o -> sp.program.start = 0;
      do_compile(GOD, objno);
      free_prog_text(o -> sp.program.first);
      break;
  #ifdef RECYCLE
    case TYPE_GARBAGE:
--- 1149,1163 ----
      OWNER(objno) = getref(f);
      FLAGS(objno) &= ~INTERNAL;
      o -> sp.program.curr_line = 0;
      o -> sp.program.code = 0;
      o -> sp.program.siz = 0;
      o -> sp.program.start = 0;
+ #ifdef COMPILE_ON_LOAD
+     o -> sp.program.first = read_program(objno);
      do_compile(NOTHING, objno);
      free_prog_text(o -> sp.program.first);
+ #endif /* COMPILE_ON_LOAD */
+     o -> sp.program.first = 0;
      break;
  #ifdef RECYCLE
    case TYPE_GARBAGE:
*** interp.c.orig	Thu Jun 13 00:10:28 1991
--- interp.c	Thu Jun 13 00:10:42 1991
***************
*** 127,132 ****
--- 127,135 ----
  
  void dispatch(dbref player, dbref program, struct inst *pc, struct inst *arg, int *top, struct frame *fr);
  
+ extern struct line *read_program(dbref);
+ extern void free_prog_text(struct line *);
+ 
  int
    interp(dbref player, dbref program, dbref source)
  {
***************
*** 139,144 ****
--- 142,160 ----
      notify(player, "Program call: Permission denied.");
      return 0;
    }
+   if (DBFETCH(program)->sp.program.start == 0) {
+     /* try to compile it... */
+     DBSTORE(program, sp.program.first, read_program(program));
+     do_compile(player, program);
+     free_prog_text(DBFETCH(program)->sp.program.first);
+   }
+   if (DBFETCH(program)->sp.program.start == 0) {
+     /* compile failed... */
+     notify(player, "Program not compiled. Cannot run.");
+     free((void *) fr);
+     return 0;
+   }
+  
    fr -> system.top = 1;
    fr -> argument.top = 0;
    fr -> pc = DBFETCH(program)->sp.program.start;
***************
*** 216,221 ****
--- 232,238 ----
    register struct inst    *temp2;
    register struct inst    *sys;
    register int            stop;
+   register dbref	  obj;
    int                     tmp, writeonly;
    
    
***************
*** 230,236 ****
    
    if (!pc)
      {
!       notify(player, "Program not compiled. Cannot run.");
        return 0;
      }
    
--- 247,253 ----
    
    if (!pc)
      {
!       notify(player, "Program not compiled.");
        return 0;
      }
    
***************
*** 301,318 ****
  		abort_loop("CALL: Stack Underflow.");
  	      temp1 = arg + --atop;
  	      if (!valid_object(temp1)
! 		  || Typeof(temp1->data.objref) != TYPE_PROGRAM
! 		  || (!(DBFETCH(temp1->data.objref)->sp.program.code)))
! 		abort_loop("CALL: invalid object or program not compiled.");
! 	      if(OWNER(temp1->data.objref) !=
  		 (((FLAGS(program) & STICKY) != 0) ? OWNER(program) : player)
! 		 && !Linkable(temp1->data.objref))
  	        abort_loop("CALL: permission denied");
  	      if (stop >= STACK_SIZE)
  		abort_loop("CALL: Stack Overflow");
  	      sys[stop++].data.call = pc + 1;
! 	      pc = DBFETCH(temp1->data.objref)->sp.program.start;
! 	      program = temp1->data.objref;
  	      break;
  	    case IN_PROGRAM:
  	      if (atop < 1)
--- 318,347 ----
  		abort_loop("CALL: Stack Underflow.");
  	      temp1 = arg + --atop;
  	      if (!valid_object(temp1)
! 		  || Typeof(temp1->data.objref) != TYPE_PROGRAM)
! 		abort_loop("CALL: Invalid object.");
! 	      obj = temp1->data.objref;
! 	      if(OWNER(obj) !=
  		 (((FLAGS(program) & STICKY) != 0) ? OWNER(program) : player)
! 		 && !Linkable(obj))
  	        abort_loop("CALL: permission denied");
  	      if (stop >= STACK_SIZE)
  		abort_loop("CALL: Stack Overflow");
+ 	       	      
+  	      if (DBFETCH(obj)->sp.program.start == 0) {
+  		/* try to compile it... */
+  		DBSTORE(obj, sp.program.first, read_program(obj));
+  		do_compile(player, obj);
+  		free_prog_text(DBFETCH(obj)->sp.program.first);
+  	      }
+  	      if (DBFETCH(obj)->sp.program.start == 0) {
+  		/* compile failed... */
+  		abort_loop("Program not compiled.");
+  	      }
+  
  	      sys[stop++].data.call = pc + 1;
! 	      pc = DBFETCH(obj)->sp.program.start;
! 	      program = obj;
  	      break;
  	    case IN_PROGRAM:
  	      if (atop < 1)


