[comp.sys.amiga.programmer] Self modifying code

dvljrt@cs.umu.se (Joakim Rosqvist) (05/28/91)

Ok, I have heard before that you should not use self modifying code.
Can anybody give a good reason for this, besides it being bad programming
pratice. 
I just got the RKM manuals and they only stated "for compatibilty with
010/020/030 etc. don't use selfmodifying code"
Could it be that data written to an address that is also in cachememory
will update the memory, but not the cache?

Consider for instance that I would like to write a fast completely
unwinded linedrawing routine and wrote code for drawing one pixel.
Then when the program start, I would allocate memory for 320 such routines
and putting 320 copies of my routine there. Would this be considered as
selfmodifying code, and therefore forbidden?

If so, compare it to when the OS is loading a program that contains
non-PC relative references to itself which will have to be rewritten
depending on the address the code was loaded to.



/$DR.HEX$

--------------------------------------------
Email to:  dvljrt@cs.umu.se
2 Windows on the screen?  Oh no, not me.  I just Logout & Go.

markv@kuhub.cc.ukans.edu (05/29/91)

In article <1991May28.120630.10150@cs.umu.se>, dvljrt@cs.umu.se (Joakim Rosqvist) writes:
> Ok, I have heard before that you should not use self modifying code.
> Can anybody give a good reason for this, besides it being bad programming
> pratice. 
> I just got the RKM manuals and they only stated "for compatibilty with
> 010/020/030 etc. don't use selfmodifying code"
> Could it be that data written to an address that is also in cachememory
> will update the memory, but not the cache?

Well, sort of.  The Motorola family has *seperate* code and data
spaces, and in fact may have drastically different memory used for
each (if you had a machine that used the FC pins for this purpose).

When you fetch an opcode, it goes in the code cache.  When you write
out self modifying code, it goes in the data cache and memory.  So the
entry in the code cache is still thought of as valid.  You can play
some games by only writing code, but then you could get tripped up on
data caches that don't do an immediate write through to memory (quite
possible on an 040).  The only thing that should be writing code to memory is
the OS loader ;-).

> Consider for instance that I would like to write a fast completely
> unwinded linedrawing routine and wrote code for drawing one pixel.
> Then when the program start, I would allocate memory for 320 such routines
> and putting 320 copies of my routine there. Would this be considered as
> selfmodifying code, and therefore forbidden?

Yes, for two reasons.  In practice on the current Amiga it would
probably work assuming you wrote the code before any was executed.
However, in future OSs, where the MMU has pages flagged as CODE or
DATA, or future hardware that plays cache control games with a large
external cache (using the FCx and CIN lines), you could still barf.
Under 2.0 the legal way to do this is write you routines and then call
CacheFlush(). (Not very friendly to the OS to do it too often, but
okay for a one shot deal).  Future OSes that use the MMU actively will
likely have the calls to play with the attributes of memory, whether
its a code page or data page, whether its cachable or not, etc.

Second, in this case I think your idea is dumb, unless I misunderstand
your plan.  If you have a routine for Each pixel, then you have to
loop and read and write a value for each pixel, with a BSR or JSR and a RET.
This isn't fast.  On the otherhand, if you loop, or special case
things, use are moves, then you only have one write for 16 or 32
pixels a lot of times.  Finally, the blitter is great for fast lines,
and faster than the CPU unless your on a 3000 and optimize you code
just right.

> If so, compare it to when the OS is loading a program that contains
> non-PC relative references to itself which will have to be rewritten
> depending on the address the code was loaded to.

The OS is special.  The "loader" will always have the hooks to make
sure the OS and cache is happy.  With simple stuff you can work around
it, but as I said, with fancy stuff like uncomitted writes and bus
snooping and the use of the FCx lines, you not guarenteed to be safe
for long.  The 040 is here and can do all of these things right now
with the right implementation.

> /$DR.HEX$
> 
> --------------------------------------------
> Email to:  dvljrt@cs.umu.se
> 2 Windows on the screen?  Oh no, not me.  I just Logout & Go.
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Gooderum			Only...		\    Good Cheer !!!
Academic Computing Services	       ///	  \___________________________
University of Kansas		     ///  /|         __    _
Bix:	  mgooderum	      \\\  ///  /__| |\/| | | _   /_\  makes it
Bitnet:   MARKV@UKANVAX		\/\/  /    | |  | | |__| /   \ possible...
Internet: markv@kuhub.cc.ukans.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ins760z@monu4.cc.monash.edu.au (mr c.r. hames) (05/29/91)

In article <1991May28.120630.10150@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
>Ok, I have heard before that you should not use self modifying code.
>Can anybody give a good reason for this, besides it being bad programming
>pratice. 

The main reason is that if you use self modifying code it might not work
on a 68010 or 68020 or 68030 or 68040 or future processor.  Because for one
reason or another the instructions that you are modifying could already be
in the pc-cache of the processor and hence the change will not be made in
the pc-cache and your code will stuff up. 

>I just got the RKM manuals and they only stated "for compatibilty with
>010/020/030 etc. don't use selfmodifying code"
>Could it be that data written to an address that is also in cachememory
>will update the memory, but not the cache?

Yep.

>
>Consider for instance that I would like to write a fast completely
>unwinded linedrawing routine and wrote code for drawing one pixel.
>Then when the program start, I would allocate memory for 320 such routines
>and putting 320 copies of my routine there. Would this be considered as
>selfmodifying code, and therefore forbidden?
>

That's self modifing code.  Sure it sounds safe enough but take a look at
this little baby that wouldn't work on my A3000 (sometimes). 

         lea     Jump+2,a0
         lea     Routine,a1
         move.l  a1,(a0)
Jump:    jmp     $12345678

Routine: ..........

Now the above routine seems fine but with burst mode of the instruction
cache on and the correct alignment the jmp instruction can be prefetched
before the move.l a1,(a0) and hence a jump to $12345678 is made instead
of to Routine.  A similar example to this was given to me last week.

In 2.0 there is system routines to clear the cache, but with 1.2/1.3 look
at the code of SetCPU V1.6 to make sure you do not write one of the many
programs which do not work on some systems.

 
>If so, compare it to when the OS is loading a program that contains
>non-PC relative references to itself which will have to be rewritten
>depending on the address the code was loaded to.
>

Although I beleive 1.2/1.3 did not, 2.0 flushes the cache.

>
>
>/$DR.HEX$
>
>--------------------------------------------
>Email to:  dvljrt@cs.umu.se
>2 Windows on the screen?  Oh no, not me.  I just Logout & Go.
-
Chris Hames         Person to blame for DirWork(1.3 RSN), VMK, FSDirs, etc
                    And soon for PC-Task?
ins760z@monu4.cc.monash.edu.au

jesup@cbmvax.commodore.com (Randell Jesup) (05/29/91)

In article <1991May28.171342.31105@kuhub.cc.ukans.edu> markv@kuhub.cc.ukans.edu writes:
>> Consider for instance that I would like to write a fast completely
>> unwinded linedrawing routine and wrote code for drawing one pixel.
>> Then when the program start, I would allocate memory for 320 such routines
>> and putting 320 copies of my routine there. Would this be considered as
>> selfmodifying code, and therefore forbidden?
>
>Yes, for two reasons.  In practice on the current Amiga it would
>probably work assuming you wrote the code before any was executed.

	In most cases you'll get lucky on an '030 since the internal cache
is small (256 bytes).  Note that is NOT the last ~128 instructions - caches
aren't like fifo's.  So you can execute thousands of cycles across several
hundred instructions and still get unlucky, at least theoretically.

>However, in future OSs, where the MMU has pages flagged as CODE or
>DATA, or future hardware that plays cache control games with a large
>external cache (using the FCx and CIN lines), you could still barf.

	Yup.  The A3000 has provision on the 200-pin connector for large
external caches, and in addition CPUs in that (or other) CPU-slots could
have external caches.  And of course the '040 has a monster internal cache,
and can bite you far easier than you think, particularily in copy-back
mode.

>Under 2.0 the legal way to do this is write you routines and then call
>CacheFlush(). (Not very friendly to the OS to do it too often, but
>okay for a one shot deal).  Future OSes that use the MMU actively will
>likely have the calls to play with the attributes of memory, whether
>its a code page or data page, whether its cachable or not, etc.

	Actually, some of the calls exist already.  CacheClearU and
CacheClearE, CacheControl, CachePreDMA and CachePostDMA.  Under 2.0,
for example, Dos uses CacheClearE in LoadSeg and Create{New}Proc, and the
A3000 scsi driver uses the Cache{Pre,Post}DMA calls.

	Some parts of these are hooks for the future, as well - for example,
CachePreDMA is designed so it could handle memory translation and locking in
a mapped system.

-- 
Randell Jesup, Jack-of-quite-a-few-trades, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com  BIX: rjesup  
Disclaimer: Nothing I say is anything other than my personal opinion.
"No matter where you go, there you are."  - Buckaroo Banzai

sschaem@starnet.uucp (Stephan Schaem) (05/29/91)

 Turn the cache OFF is you want to be sure... If you do code creation
 you memory is not 'defined' as READ or READ/WRITE so you dont even
 have to do that.
 I alway consider code section has being read only, and if I have
 read/write data I create a data section (But keep my READ only
 structure/data in the code section, ho well :-)

 Self modifying code or running code is something else! Flush the cache
 if you really need to do it, dont think your instruction is not
 'preloaded' in case you dont turn the cache off!

 Relocable code is not done on a running task, and done by the DOS.Thats
 the diference...

 To make the story long, you dont have to do anything in your case...


							Stephan.

m0154@tnc.UUCP (GUY GARNETT) (05/29/91)

[Good discussion of why self-modifying code is a bad idea on the
Amiga; thank you, Mark Gooderum!]

I'd like to add a comment, though, which may help clarify things a
little bit.  The 680x0 family of processors has become (with the
caches on the 68030 and 68040) what is known as a "Modified Harvard
Architecture" machine.  This means that, logically speaking, code
memory and data memory are completely separate.  Any given address in
code memory is, from the point of view of the machine architecture, a
different memory loation from the same address in data memory.

Every real implementation I know of uses the same physical memory for
both purposes, but that's just an implementation detail, and doesn't
change the nature of the machine architecture.  That is why the code
cache doesn't attempt to find out what the data cache is doing; they
are completely separate systems.

Of course, for the machine to be useful, the operating system must
provide some way of getting code into code memory, and data into and
out of data memory.  Getting code into code memory is the loader's
job, and it knows what to do to make everything work right (and will,
I presume, be updated to reflect new developments in the 680x0
family).

Wildstar

 .signature: syntax error in line 1: "(" unexpected.

bombadil@diku.dk (Kristian Nielsen) (05/29/91)

dvljrt@cs.umu.se (Joakim Rosqvist) writes:

>Ok, I have heard before that you should not use self modifying code.
>Can anybody give a good reason for this, besides it being bad programming
>pratice. 
>I just got the RKM manuals and they only stated "for compatibilty with
>010/020/030 etc. don't use selfmodifying code"
>Could it be that data written to an address that is also in cachememory
>will update the memory, but not the cache?

  Yes, this is the problem - I believe on the '040 its even worse, since a
write might only go to the (data) cache and not be written to memory until
later.

>Consider for instance that I would like to write a fast completely
>unwinded linedrawing routine and wrote code for drawing one pixel.
>Then when the program start, I would allocate memory for 320 such routines
>and putting 320 copies of my routine there. Would this be considered as
>selfmodifying code, and therefore forbidden?

  Yes, this, too will break on 680x0 with cache.

>If so, compare it to when the OS is loading a program that contains
>non-PC relative references to itself which will have to be rewritten
>depending on the address the code was loaded to.

  Yes, the OS has to do this, so it has to know how to flush the cache -
actually the loading of the code itself could be termed selfmodifying. I
think 2.0 includes a function like LoadSeg() that 'loads' code from a
SegList already in memory. And before asking about being 1.3-compatible:
don't bother (at least when 2.0 becomes avaiable). Hopefully (IMHO), in 6
months it will be impossible to buy an 1.3 Amiga.

>/$DR.HEX$

>--------------------------------------------
>Email to:  dvljrt@cs.umu.se
>2 Windows on the screen?  Oh no, not me.  I just Logout & Go.

peic@core.north.de (Peter Eichler) (05/30/91)

In article <1991May28.120630.10150@cs.umu.se>, Joakim Rosqvist writes:

>Ok, I have heard before that you should not use self modifying code.
>Can anybody give a good reason for this, besides it being bad programming
>pratice. 
>I just got the RKM manuals and they only stated "for compatibilty with
>010/020/030 etc. don't use selfmodifying code"

>/$DR.HEX$

Self modifying code is in no way reentrent and therefore cannot be made
pure. For OS procedures, handlers, devices, etc. this methode is DEADLY.
Imagine a self modifing compiler and you use the "Resident" command...

Also there is a non-determenistic behavour. If you do not reset the code
you mostly are not able to produce the same results. Maybe you will get
side effects.
Programs with self modifying code are ugly to handle during debugging
time and hard to keep it "clean".

*Sometimes* self-modifyng code is a little faster than other equivalent
code, but this advantage is very little so no one should use this in
common applications!!!

Peter
(a lonesome guy with a lonesome amiga at the armpit of the universe,
called Germany...)

daveh@cbmvax.commodore.com (Dave Haynie) (05/30/91)

In article <1991May28.120630.10150@cs.umu.se> dvljrt@cs.umu.se (Joakim Rosqvist) writes:
>Ok, I have heard before that you should not use self modifying code.
>Can anybody give a good reason for this, besides it being bad programming
>pratice. 

Because it goes against the basic design of the 680x0 processor family.  In
the 680x0 family, you have code and data spaces.  Very often these are the
same memory, sometimes they aren't.  If they aren't, modifications to data
space are not reflected in code space.

>Could it be that data written to an address that is also in cachememory
>will update the memory, but not the cache?

Exactly.  Consider a chunk of code that gets modified to do a two things, 
Thing-A and Thing-B.  You run it through on your A500, it does Thing-A,
hits the modification routine, then it does Thing-B.  Great.  Only, once its
released on the market, I buy it and run it on my A3000.  The code romps
along, does Thing-A, gets to the modification routine, then, whoops, it
does Thing-A again, because while the code in main memory now does Thing-B,
the code in the 68030's I-Cache still does Thing-A.

>Consider for instance that I would like to write a fast completely
>unwinded linedrawing routine and wrote code for drawing one pixel.
>Then when the program start, I would allocate memory for 320 such routines
>and putting 320 copies of my routine there. Would this be considered as
>selfmodifying code, and therefore forbidden?

In a sense, though it's not the worst offender.  The main problem is changing
data space into code space.  LoadSeg() knows how to do this.  You don't, unless
you explicitly clear caches after any such transform (which you can only do
in 2.0, by the way).  If you do something like my example, you're certain to
fail with a large enough cache, since you cache code, immediately change it,
then execute it again.  Another problem may be stale caches.  If you allocate 
a chunk of memory and build some code in it, you have to explicitly clear the
system cache before executing code, otherwise you may find you are executing
code that used to be in that there from another task, since to the CPU, that
memory is in data space when you act on it.

>If so, compare it to when the OS is loading a program that contains
>non-PC relative references to itself which will have to be rewritten
>depending on the address the code was loaded to.

The OS knows the proper steps to take to do the various code space transforms
and cache clears properly (in reality, since main memory is unified I and D
memory, the only thing that's really done is cache update).  There are 
apparently 2.0 calls that allow a program to Do The Right Thing.  The software
folks could cover this in greater detail.

-- 
Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: hazy     BIX: hazy
      "That's me in the corner, that's me in the spotlight" -R.E.M.

jesup@cbmvax.commodore.com (Randell Jesup) (05/30/91)

In article <1991May29.134419.4980@odin.diku.dk> bombadil@diku.dk (Kristian Nielsen) writes:
>  Yes, this is the problem - I believe on the '040 its even worse, since a
>write might only go to the (data) cache and not be written to memory until
>later.

	Most certainly.  For example, even if you were lucky on a 68030/68020
and the memory you wrote the code into wasn't in the cache, on an '040 in
copyback made (which is a BIG win) the code you wrote will be sitting in the
data cache but not in ram.  When you try to execute them it fetches from
memory.  Poof.

-- 
Randell Jesup, Jack-of-quite-a-few-trades, Commodore Engineering.
{uunet|rutgers}!cbmvax!jesup, jesup@cbmvax.cbm.commodore.com  BIX: rjesup  
Disclaimer: Nothing I say is anything other than my personal opinion.
"No matter where you go, there you are."  - Buckaroo Banzai

dvljrt@cs.umu.se (Joakim Rosqvist) (05/30/91)

>
>> Consider for instance that I would like to write a fast completely
>> unwinded linedrawing routine and wrote code for drawing one pixel.
>> Then when the program start, I would allocate memory for 320 such routines
>> and putting 320 copies of my routine there. Would this be considered as
>> selfmodifying code, and therefore forbidden?
>
>Yes, for two reasons.  In practice on the current Amiga it would
>probably work assuming you wrote the code before any was executed.
>However, in future OSs, where the MMU has pages flagged as CODE or
>DATA, or future hardware that plays cache control games with a large
>external cache (using the FCx and CIN lines), you could still barf.
>Under 2.0 the legal way to do this is write you routines and then call
>CacheFlush(). (Not very friendly to the OS to do it too often, but
>okay for a one shot deal).  Future OSes that use the MMU actively will
>likely have the calls to play with the attributes of memory, whether
>its a code page or data page, whether its cachable or not, etc.

I guess that version of the OS will not work on a 68000 anyway.
On a 040 there would be no reason to have the code duplicated several times
since a dbra loop from will be just as fast (valid even on '020, 30 ?)

On the 68000, I could unwind with no problems, since there is no cache,
right?

>
>Second, in this case I think your idea is dumb, unless I misunderstand
>your plan.  If you have a routine for Each pixel, then you have to
>loop and read and write a value for each pixel, with a BSR or JSR and a RET.
>pixels a lot of times.  Finally, the blitter is great for fast lines,
>and faster than the CPU unless your on a 3000 and optimize you code
>just right.

It was intended as an example of code that has to be rewritten once before
it can run, much like if the code was crunched. And of course I would have
320 copies of _the_routine_that_draws_a_pixel_ rather than 320 copies of
a call to that routine.


 /$DR.HEX$
 
 --------------------------------------------
 Email to:  dvljrt@cs.umu.se
 2 Windows on the screen?  Oh no, not me.  I just Logout & Go.

<LEEK@QUCDN.QueensU.CA> (05/30/91)

In article <1991May28.120630.10150@cs.umu.se>, dvljrt@cs.umu.se (Joakim
Rosqvist) says:
>
>Ok, I have heard before that you should not use self modifying code.
>Can anybody give a good reason for this, besides it being bad programming
>pratice.

It is because these processors have separate data & instruction caches.

Question:
So like if I turned off the cache, would it work then ?

Answer:
Sure... but turning off the cache means large drop in performance. Much
greater than you would get for just saving a few instruction cycles.
Flushing the cache is a big speed penality (worst if it is big) if you do it
often enough.

(Motorola does not support use of self-modifying code.  Look at what
Intel have to do (an unified cache for code & instruction vs Motorola's
separate caches that allows parallel fetch (reads FASTER) to I&D).  Among
other things, the use of bad programming practices might cause limits on future
hardware designs due to compatiblity issues. (as witnessed in PC.))

>I just got the RKM manuals and they only stated "for compatibilty with
>010/020/030 etc. don't use selfmodifying code"
>Could it be that data written to an address that is also in cachememory
>will update the memory, but not the cache?

>
>Consider for instance that I would like to write a fast completely
>unwinded linedrawing routine and wrote code for drawing one pixel.
>Then when the program start, I would allocate memory for 320 such routines
>and putting 320 copies of my routine there. Would this be considered as
>selfmodifying code, and therefore forbidden?

It might fly on a 68000, but barely move on 020/030/040 etc if the user
have to turn off their caches to make this thing run at all or worst
have to fall back on 68000 mode (if one exists and most likely without
16-bit ram) because someone used some illegal move sr instructions to
save an OS call.

>
>If so, compare it to when the OS is loading a program that contains
>non-PC relative references to itself which will have to be rewritten
>depending on the address the code was loaded to.

Yes, but the OS should be the only place where this should be happening.
There might be some OS routine that your program can call to load in
these routines for you and make sure everything works.

>
>/$DR.HEX$
>
>--------------------------------------------
>Email to:  dvljrt@cs.umu.se
>2 Windows on the screen?  Oh no, not me.  I just Logout & Go.

K. C. Lee
"Be careful of what you wish for.  You might get it."-Master Splinter. T.M.N.T

ttobler@unislc.uucp (Trent Tobler) (06/02/91)

>
>Second, in this case I think your idea is dumb, unless I misunderstand
>your plan.  If you have a routine for Each pixel, then you have to
>loop and read and write a value for each pixel, with a BSR or JSR and a RET.
>pixels a lot of times.  Finally, the blitter is great for fast lines,
>and faster than the CPU unless your on a 3000 and optimize you code
>just right.

But that was just an example.  Suppose I want to write an interactive
language that compiles directly to machine language which I may choose
to then execute  (I believe JForth does this?)

Coding time can be reduce by leaps and bounds if after I type the
definition of a command, I can test immediately without doing the
compile-link-run sequence from the operating system.

So, what is a good way to implement this type of thing?
--
   Trent Tobler - ttobler@csulx.weber.edu

mwm@pa.dec.com (Mike (My Watch Has Windows) Meyer) (06/03/91)

In article <1991Jun2.091922.13501@unislc.uucp> ttobler@unislc.uucp (Trent Tobler) writes:
   But that was just an example.  Suppose I want to write an interactive
   language that compiles directly to machine language which I may choose
   to then execute  (I believe JForth does this?)

Picking a nit, that's not self-modifying code, but just generating
code. Unfortunately, the problem being discussedd isn't really
self-modifying code, but data/code confusion. Self-modifying code is
just one of the most common examples of that technic. LISP macros are
another common example.

   Coding time can be reduce by leaps and bounds if after I type the
   definition of a command, I can test immediately without doing the
   compile-link-run sequence from the operating system.

   So, what is a good way to implement this type of thing?

Well, in the face of an architechture that doesn't allow you to
directly turn data into code, you have to use the tools provided for
doing so, and follow the protocols. For testing the interpreter, I'd
probably generate code to a scratch file on ram:, and loadseg that.
This has the advantage of leaving the code where it can be readily
examined and fooled with. For production, I'd probably gen code to
memory and play the game "right", and investigate gen'ing code into
the resident list (that might make things easier; or it might be a
total lose. Finding out is why I'd investigate it).

	<mike
--
ICUROK2C, ICUROK2.					Mike Meyer
ICUROK2C, ICWR2.					mwm@pa.dec.com
URAQT, I WANT U2.					decwrl!mwm
OO2EZ, I WANT U2.

mykes@amiga0.SF-Bay.ORG (Mike Schwartz) (06/04/91)

In article <1991Jun2.091922.13501@unislc.uucp> ttobler@unislc.uucp (Trent Tobler) writes:
>>
>>Second, in this case I think your idea is dumb, unless I misunderstand
>>your plan.  If you have a routine for Each pixel, then you have to
>>loop and read and write a value for each pixel, with a BSR or JSR and a RET.
>>pixels a lot of times.  Finally, the blitter is great for fast lines,
>>and faster than the CPU unless your on a 3000 and optimize you code
>>just right.
>
>But that was just an example.  Suppose I want to write an interactive
>language that compiles directly to machine language which I may choose
>to then execute  (I believe JForth does this?)
>
>Coding time can be reduce by leaps and bounds if after I type the
>definition of a command, I can test immediately without doing the
>compile-link-run sequence from the operating system.
>
>So, what is a good way to implement this type of thing?
>--
>   Trent Tobler - ttobler@csulx.weber.edu

JForth works fine on my 030 with Caches on.

--
****************************************************
* I want games that look like Shadow of the Beast  *
* but play like Leisure Suit Larry.                *
****************************************************

mks@cbmvax.commodore.com (Michael Sinz) (06/04/91)

In article <MWM.91Jun3102821@raven.pa.dec.com> mwm@pa.dec.com (Mike (My Watch Has Windows) Meyer) writes:
>In article <1991Jun2.091922.13501@unislc.uucp> ttobler@unislc.uucp (Trent Tobler) writes:
>   But that was just an example.  Suppose I want to write an interactive
>   language that compiles directly to machine language which I may choose
>   to then execute  (I believe JForth does this?)
>
>Picking a nit, that's not self-modifying code, but just generating
>code. Unfortunately, the problem being discussedd isn't really
>self-modifying code, but data/code confusion. Self-modifying code is
>just one of the most common examples of that technic. LISP macros are
>another common example.

Well, in LISP (as in REXX), the macros are not compiled and thus
they are not really changing data into code.  (Unless you have a LISP
compiler...)

>   Coding time can be reduce by leaps and bounds if after I type the
>   definition of a command, I can test immediately without doing the
>   compile-link-run sequence from the operating system.
>
>   So, what is a good way to implement this type of thing?

You can generate the code into memory.  You just need to make a
call to the system's cache coherency routines to make sure it is
all there before you try to execute the code.  In the Amiga, this
routine is in EXEC and is called CacheClearU()  (CacheClearE() is
the enhanced version where you can give it a more exact definition
of what needs to be cleared)

/----------------------------------------------------------------------\
|      /// Michael Sinz  -  Amiga Software Engineer                    |
|     ///                   Operating System Development Group         |
|    ///   BIX:  msinz      UUNET:  rutgers!cbmvax!mks                 |
|\\\///                                                                |
| \XX/     "I don't think so" said Ren'e Descartes, then he vanished.  |
\----------------------------------------------------------------------/