Re: Event handling (was Re: [CVS ci] exceptions-6: signals, catch a SIGFPE (generic platform)

2003-07-15 Thread Jason Gloudon
On Tue, Jul 15, 2003 at 10:15:57AM +0200, Leopold Toetsch wrote:

How is the described scheme supposed to work with JIT generated code ?

-- 
Jason


Re: [PATCH] vtable_1 - accessor macros

2003-03-23 Thread Jason Gloudon
On Sun, Mar 23, 2003 at 03:54:21PM +0100, Leopold Toetsch wrote:
 Not really, but I don't see, how this set of macros would influence 
 debugging negatively.

You can't step through the expanded code for a macro in the debugger.

-- 
Jason


Re: [perl #21508] [PATCH] more sun4 jit changes

2003-03-07 Thread Jason Gloudon
On Fri, Mar 07, 2003 at 11:38:41PM +, Jason Gloudon wrote:
 # New Ticket Created by  Jason Gloudon 
 # Please include the string:  [perl #21508]
 # in the subject line of all future correspondence about this issue. 
 # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=21508 
 
 
 
 This adds still more ops and re-organizes register use to avoid potential
 conflicts in register use between the main .jit code and the helper routines.
 More registers are available for allocation.
 
 Some of the new ops are commented out. They really need a constant pool to
 implement them correctly. It would be nice if the constant pool was more
 generic, but I will probably want to work on the vtable functions before that.

The missing patch file.

-- 
Jason
Index: jit/sun4/core.jit
===
RCS file: /cvs/public/parrot/jit/sun4/core.jit,v
retrieving revision 1.3
diff -u -r1.3 core.jit
--- jit/sun4/core.jit   4 Mar 2003 15:58:11 -   1.3
+++ jit/sun4/core.jit   7 Mar 2003 23:34:05 -
@@ -45,22 +45,24 @@
 Parrot_set_x_x s/_N/_n/ s/ISR/FSR/
 }
 
-TEMPLATE Parrot_set_x_xc {
+Parrot_set_i_ic {
+Parrot_set_x_x s/_N/_i/
+}
+
+Parrot_set_n_ic {
 if(MAP[1]){
-   jit_emit_load_N(jit_info, interpreter, 2, MAP[1]);
+   jit_emit_load_n(jit_info, interpreter, 2, MAP[1]);
+emitm_fitod(NATIVECODE, MAP[1], MAP[1]);
 }
 else {
-   jit_emit_load_N(jit_info, interpreter, 2, ISR1);
-   jit_emit_store_N(jit_info, interpreter, 1, ISR1);
+   jit_emit_load_n(jit_info, interpreter, 2, FSR1);
+emitm_fitod(NATIVECODE, FSR1, FSR1);
+   jit_emit_store_n(jit_info, interpreter, 1, FSR1);
 }
 }
 
-Parrot_set_i_ic {
-Parrot_set_x_xc s/_N/_i/
-}
-
 Parrot_set_n_nc {
-Parrot_set_x_xc s/_N/_n/ s/ISR/FSR/
+Parrot_set_x_x s/_N/_n/ s/ISR/FSR/
 }
 
 Parrot_set_n_i {
@@ -132,13 +134,13 @@
 }
 else {
 arg2 = ISR2;
-jit_emit_load_N(jit_info, interpreter, 2, ISR2);
+jit_emit_load_N(jit_info, interpreter, 2, arg2);
 }
 
 emitm_op(NATIVECODE, arg1, arg2, arg1);
 
 if(!MAP[1]){
-jit_emit_store_N(jit_info, interpreter, 1, ISR1);
+jit_emit_store_N(jit_info, interpreter, 1, arg1);
 }
 }
 
@@ -178,7 +180,354 @@
 Parrot_binop_x_x s/op/fdivd/ s/_N/_n/
 }
 
-Parrot_if_i_ic {
+TEMPLATE Parrot_binop_i_xc {
+int arg1;
+
+if(MAP[1]){
+arg1 = MAP[1];
+}
+else {
+arg1 = ISR1;
+jit_emit_load_i(jit_info, interpreter, 1, arg1);
+}
+
+if(emitm_simm13_const(*INT_CONST[2])){
+emitm_op_i(NATIVECODE, arg1, *INT_CONST[2], arg1);
+}
+else {
+jit_emit_load_i(jit_info, interpreter, 2, ISR1);
+emitm_op_r(NATIVECODE, arg1, ISR1, arg1);
+}
+
+if(!MAP[1]){
+jit_emit_store_i(jit_info, interpreter, 1, arg1);
+}
+}
+
+Parrot_add_i_ic {
+Parrot_binop_i_xc s/op/add/
+}
+
+Parrot_sub_i_ic {
+Parrot_binop_i_xc s/op/sub/
+}
+
+Parrot_bor_i_ic {
+Parrot_binop_i_xc s/op/or/
+}
+
+Parrot_band_i_ic {
+Parrot_binop_i_xc s/op/and/
+}
+
+Parrot_bxor_i_ic {
+Parrot_binop_i_xc s/op/xor/
+}
+
+Parrot_sub_n_nc {
+Parrot_binop_x_x s/op/faddd/ s/ISR/FSR/ s/_N/_n/
+}
+
+Parrot_sub_n_nc {
+Parrot_binop_x_x s/op/fsubd/ s/ISR/FSR/ s/_N/_n/
+}
+
+Parrot_mul_n_nc {
+Parrot_binop_x_x s/op/fmuld/ s/ISR/FSR/ s/_N/_n/
+}
+
+Parrot_div_n_nc {
+Parrot_binop_x_x s/op/fdivd/ s/ISR/FSR/ s/_N/_n/
+}
+
+TEMPLATE Parrot_binop_x_x_x {
+int arg2, arg3;
+
+/* Generate load if needed */
+if(MAP[2]){
+arg2 = MAP[2];
+}
+else {
+arg2 = ISR1;
+jit_emit_load_N(jit_info, interpreter, 2, arg2);
+}
+
+/* Generate load if needed */
+if (MAP[3]) {
+arg3 = MAP[3];
+}
+else {
+arg3 = ISR2;
+jit_emit_load_N(jit_info, interpreter, 3, arg3);
+}
+
+/* Destination is a register */
+if (MAP[1]) {
+emitm_op(NATIVECODE, arg2, arg3, MAP[1]);
+}
+/* Destination is memory */
+else {
+emitm_op(NATIVECODE, arg2, arg3, ISR1);
+jit_emit_store_N(jit_info, interpreter, 1, ISR1);
+}
+}
+
+Parrot_add_i_ic_ic {
+Parrot_binop_x_x_x s/op/add_r/ s/_N/_i/
+}
+
+Parrot_sub_i_ic_ic {
+Parrot_binop_x_x_x s/op/sub_r/ s/_N/_i/
+}
+
+Parrot_band_i_ic_ic {
+Parrot_binop_x_x_x s/op/and_r/ s/_N/_i/
+}
+
+Parrot_bor_i_ic_ic {
+Parrot_binop_x_x_x s/op/or_r/ s/_N/_i/
+}
+
+Parrot_bxor_i_ic_ic {
+Parrot_binop_x_x_x s/op/xor_r/ s/_N/_i/
+}
+
+Parrot_shl_i_ic_ic {
+Parrot_binop_x_x_x s/op/sll_r/ s/_N/_i/
+}
+
+Parrot_shr_i_ic_ic {
+Parrot_binop_x_x_x s/op/sra_r/ s/_N/_i/
+}
+
+Parrot_lsr_i_ic_ic {
+Parrot_binop_x_x_x s/op/srl_r/ s/_N/_i/
+}
+
+Parrot_add_n_nc_nc {
+Parrot_binop_x_x_x s/op/faddd/ s/_N/_n/ s/ISR/FSR/
+}
+
+Parrot_sub_n_nc_nc {
+Parrot_binop_x_x_x s/op/fsubd/ s/_N/_n/ s/ISR/FSR/
+}
+
+Parrot_mul_n_nc_nc {
+Parrot_binop_x_x_x s/op/fmuld/ s/_N/_n

Re: [RFC] imcc calling conventions

2003-03-03 Thread Jason Gloudon
On Mon, Mar 03, 2003 at 01:07:36PM +, Piers Cawley wrote:

  I think you're overlooking the restoreall done just before the
  jump-no-save-returnaddress operation...  I see two savealls and
  two restorealls.
 
 But with proper tail call optimization you'd only need *one*
 saveall. That's why it's an optimization. 

Tail call optimization is a space (stack size) optimization. The scheme
definition only requires space efficiency. The time optimization is important
but a secondary consideration for the functional language folks.

-- 
Jason


Re: This week's Perl 6 Summary

2003-02-26 Thread Jason Gloudon
On Wed, Feb 26, 2003 at 09:31:39AM -0800, Sean O'Rourke wrote:

 Dan -- you might be interested in
 http://www.usenix.org/events/javavm02/chen_m.html (if you have a USENIX

Research wants to be free:

http://www-hydra.stanford.edu/publications/JVM02.pdf

-- 
Jason


Re: Using imcc as JIT optimizer

2003-02-25 Thread Jason Gloudon
On Tue, Feb 25, 2003 at 07:18:11PM +0100, Angel Faus wrote:
 I believe it would be smarter if we instructed IMCC to generate code 
 that only uses N parrot registers (where N is the number of machine 
 register available). This way we avoid the risk of having to copy 
 twice the data.

It's not going to be very good if I compile code to pbc on an x86 where there
are about 3 usable registers and try to run it on any other CPU with a lot more
registers.

-- 
Jason


Re: YARL - yet another run loop: CSwitch

2003-02-08 Thread Jason Gloudon
On Fri, Feb 07, 2003 at 05:49:35PM +0100, Leopold Toetsch wrote:

 I don't know yet, how multi threading will be done. But when multiple 
 interpreters share the -code data member (as newinterp/runinterp) do, 
 then they will use the same JIT/prederef or whatever data.

You can't do that for prederef in a multi-threaded process because prederef
stores the address of the registers in the interpreter structure in the
prederef data.

case PARROT_ARG_I:
pc_prederef[i] = (void *)interpreter-ctx.int_reg.registers[pc[i]];

-- 
Jason



Re: [CVS ci] CGP - CGoto Prederefed runloop

2003-02-08 Thread Jason Gloudon
On Sat, Feb 08, 2003 at 03:10:58PM +, Nicholas Clark wrote:

 The bytecode is compiled by the JIT (at some point) - if there are a run
 of consecutive JIT-able ops, then issue a section (an isolated section) of
 machine code for those ops, and replace those ops in the bytecode with an op
 that calls that section. If there isn't a run of JIT-able ops, then just
 leave the ops as ops, and use the regular computed goto core dispatch.

Yep. That's the sort of use I created the enternative op for. Right now it's
used by the compiled C code generator. Basically the entry points to basic
blocks are replaced with enternative calls so that the transition to compiled
basic blocks of ops code happens transparently to the interpreter.

-- 
Jason



Re: YARL - yet another run loop: CSwitch

2003-02-07 Thread Jason Gloudon
On Fri, Feb 07, 2003 at 09:49:29AM +0100, Leopold Toetsch wrote:

 Yesterday night I hacked together a switched prederefed run loop. It's 
 running ~50% faster then fast_core but a lot slower then the CGoto based 
 loops.

The speedups are great. The next question is how do you do use this in a
multi-threaded program without wasting a lot of memory and losing the speedup
becase of the extra memory bloat of having to prederef the same code for every
thread ?

The x86 jit had the same problem (I don't know if anyone has changed that), the
code it generates is only good for a single interpreter.

-- 
Jason



Re: [RfD] parrot run loops

2003-02-01 Thread Jason Gloudon
On Thu, Jan 30, 2003 at 10:07:26AM +0100, Leopold Toetsch wrote:

  code_start = interpreter-code-base.data; // new syntax
  while (offs)
   offs = interp-func_table[*(code_start+offs)](offs, ..)

It's unclear to me whether you are saying the opcode functions would still be
passed the PC or offs(et) ? If you pass the offset, the opcode functions will
have to re-calculate the PC in order to access opcode arguments.

 Changing the addressing scheme to opcode offsets relative to code
 start would simplify all kinds of (non local) control flow changes. As
 real world programs mostly consists of such subroutine calls, these
 would be simplified a lot (and would then not need leaving the runloop
 - probably ;-)

How would non local control flow be simplified ? You would still have to leave
the runloop because the bytecode base has changed and code_start would no
longer be correct.

-- 
Jason



Re: [RfD] parrot run loops

2003-02-01 Thread Jason Gloudon
On Sun, Feb 02, 2003 at 12:46:50AM +0100, Leopold Toetsch wrote:

 #define IREG(i) interpreter-ctx.int_reg.registers[code_start[offs+i]]

Where does the value of code_start coming from ?
code_start in an opcode function is not a constant, so the above is really:

interpreter-ctx.int_reg.registers[interpreter-code-base.data[offs+i]]

following the names you've used in previous mail.

Intersegment jumps may not work readily for all runloops, but I don't believe
that requires as big a change as you're suggesting.

-- 
Jason



Re: Bytecode metadata

2003-01-25 Thread Jason Gloudon
On Thu, Jan 23, 2003 at 08:39:21PM +, Dave Mitchell wrote:

 This means that a Perl server that relies on a lot of modules, and which
 forks for each connection (imagine a Perl-based web server), doesn't
 consume acres of swap space just to have an in-memory image per Perl
 process, of all the modules.

Are you sure the swap space allocation isn't mostly attributable to the poor
locality in the Perl process's data structures ?

-- 
Jason



Re: Transferring control between code segments, eval, and suchlike things

2003-01-23 Thread Jason Gloudon
On Wed, Jan 22, 2003 at 03:00:37PM -0500, Dan Sugalski wrote:

 Destinations. These are a pain, since if we can go anywhere then the 
 JIT has to do all sorts of nasty and unpleasant things to compensate, 
 and to make every op a valid destination. Yuck.

Arbitrary jumps are not that difficult to deal with in the JIT.  The JIT
compiler can handle jumps to arbitrary addresses by falling back into the
interpreter if the destination does not coincide with a previously known entry
point, reentering the JIT code later at a safe point. pbc2c generated code does
this. This way the JIT does not have to support making every instruction a safe
branch destination.

-- 
Jason



Re: [perl #20315] [PATCH] eval - inter code segment branches

2003-01-21 Thread Jason Gloudon
On Tue, Jan 21, 2003 at 12:08:29AM +0100, Leopold Toetsch wrote:

 Here is a proposal for inter code segment jumps:
 
 The assembler (imcc) can recognize when a branch ins goes to a different
 code segment.
 
 For such a branch, imcc generates this opcode seqence:
 
inter_cs
if i, ic # or whatever

Why do we need branches to go to different code segments ?  I think the
expectation has been that control transfers between segments would have their
own op, because separate code segments would generally coincide with subs,
closures or at least blocks, that have specific entry points.

Maybe Dan could give us a hint about the closure/block/byte code segment
relationship.

-- 
Jason



Re: [perl #20315] [PATCH] eval - inter code segment branches

2003-01-21 Thread Jason Gloudon
On Tue, Jan 21, 2003 at 08:21:42PM +0100, Leopold Toetsch wrote:

 For such a branch, imcc generates this opcode seqence:
 
   inter_cs
   if i, ic # or whatever
 
 Why do we need branches to go to different code segments ?  
 
 
 Because of this nasty piece of little code:
 t/syn/eval_3.imc:
 
 # #!/usr/bin/perl -w
 # my $i= 5;
 # LAB:
 #$i++;
 #eval(goto LAB if ($i==6));

Ok. Having inter_cs call DO_OP just seems more involved than it has to be.
How about a single self-contained inter-segment jump instruction.

Since the compiler knows when a branch is non-local it can always break a
non-local conditional branch into a conditional local branch to a non-local
branch instruction.

For example

if i, nonlocal

... not taken

can be expressed as

if i, TAKEN

... not taken
...

TAKEN: inter_jump nonlocal

-- 
Jason



Re: Thoughts on infant mortality...

2003-01-13 Thread Jason Gloudon
On Fri, Jan 10, 2003 at 01:05:05PM +0100, Leopold Toetsch wrote:

 While I'd like no stack walking, as it's pricey, I'm not sure it's 
 tenable. 
 
 As the current clone changes does show, it's possible.
 
 BTW current tests do succed w/o stackwalking - its disabled.
 
 ... Skipping it makes things rather more fragile, as it means that 
 any code that may potentially trigger a DOD run while holding an 
 unrooted object needs to root it temporarily, and that's a lot of code. 
 
Without the stack/register examination the following can occur (though nothing
does this yet)

1) A PMC is accessible from the root set when a vtable is called. Either via a
reference or being a member of an aggregate.

2) A vtable function obtains a PMC* to that PMC.

3) The vtable calls some code deletes the reference to the PMC, which is now
no longer accessible from the root set. The vtable then attempts to allocate
some memory.

The vtable function will now contain the only remaining reference to the PMC,
but unless the vtable function has added that PMC to the root set somehow it
will be collected prematurely.

This means that even some would that are already rooted need to be treated
specially. From this example, any object in an aggregate.

On a related note, I have been looking at implementation techniques for
incremental/generational garbage collectors. A critical aspect of a
generational garbage collector is a write barrier, which records any pointer
writes that create references to a generation from an older generation.

In the context of parrot this means identifying every place that a PMC pointer
is updated. The only portable way to do this is by explicit checks in the
interpreter and code produced by the JIT. The current flexibility in parrot
allows C code to freely update PMC pointers, so such checks would have to be
manually inserted in so many places as to become untenable.

The non-portable techniques for implementing write barriers include marking
pages read-only and trapping SIGSEGV's on any write or using the hardware dirty
bits to find pages that have been written. Besides portability, these
techniques are not really well supported by the operating system and have their
own inefficiencies.

I believe the above considerations present some basic choices:

1) Create new conventions for manipulating the interpreter state from C code
that that make all PMC pointers immediately accesible to the garbage collector.
(The infant mortality issue has started movement in this direction)

This will make parrot slower in general (The C compiler will be unable to
perform register allocation of many PMC pointers in addition to the additional
overhead), but makes a stop the world collector faster and allows an
incremental collector which can shorten the pauses due to collector runs.  It
also makes for more rules for core programmers or extension writers to follow.

2) Rework the implementation so that the vtables or any other opcodes that may
callback into parrot are entirely/mostly implemented in parrot ops that can be
JIT compiled. This way we can still get optimized vtable code that allows an
incremental collector.

3) Give up on a portable incremental collector and stick with the current stop
the world collector. Parrot's basic execution speed will be unchanged. By
trading heap size against frequency of collector runs, one could amortize the
cost of running the collector. Extension and core code programmers would never
have to think about the garbage collector in order to write correct code.

-- 
Jason



Re: Thoughts on infant mortality...

2003-01-13 Thread Jason Gloudon
On Mon, Jan 13, 2003 at 09:51:13AM -0800, Steve Fink wrote:

  reference or being a member of an aggregate.
  
  2) A vtable function obtains a PMC* to that PMC.
  
  3) The vtable calls some code deletes the reference to the PMC, which is now
  no longer accessible from the root set. The vtable then attempts to allocate
  some memory.

 Nope, that example is just a plain ol' use-of-freed-memory bug. If you
 delete something, don't look at it again. However, if you change the

The point here is that the PMC's reference may be deleted because you don't
know the side-effects of code that you're calling, so you would always have to
make sure it is anchored, and incur the overheads etc.

-- 
Jason



Re: Infant mortality

2003-01-02 Thread Jason Gloudon
On Wed, Jan 01, 2003 at 08:09:05PM -0800, Steve Fink wrote:

 To anyone out there who is thinking of a Grand Unified Infant
 Mortality Solution, here's another thing that vastly complicates
 things, and that we don't yet have a workable solution for yet: prompt
 finalization.

Timely finalization has no perfect solution even under the best conditions
(compiler support. etc.), this is why Java and .NET offer no promises about
timely finalization.

.
.

 The connection to the infant mortality problem is just that some
 solutions might make this easier. Or harder. For example, the current
 conservative stackwalk breaks even the painfully slow solution: there

As long as you're using a tracing collector, you cannot provide a general
guarantee of timely finalization without running a full sweep of the 'heap'.
Even if you do not have to walk the hardware stack that's too costly to be
practical.

The best partial solution to early finalization is compile-time tracing of
possible references by the compiler which can explicitly generate the
appropriate DESTROY calls.

-- 
Jason



Re: [perl #19334] [PATCH] PARROT_GC_DEBUG=1 failures

2002-12-21 Thread Jason Gloudon

This patch should also be applied, or initialize_core_pmcs will fault with
PARROT_GC_DEBUG set.

diff -u -r1.52 embed.c
--- embed.c 21 Dec 2002 10:07:34 -  1.52
+++ embed.c 21 Dec 2002 21:34:32 -
@@ -32,6 +32,8 @@
 we set up our own in embed.c:Parrot_runcode()?
 */
 {
+if (stacktop)
+interpreter-lo_var_ptr = stacktop;
 static INTVAL world_inited = 0;
 if (!world_inited) {
 /* global_setup.c:init_world sets up some vtable stuff.
@@ -43,8 +45,6 @@
 }
 else
 Parrot_initialize_core_pmcs(interpreter);
-if (stacktop)
-interpreter-lo_var_ptr = stacktop;
 }

 void


-- 
Jason



Re: Register scanning

2002-12-18 Thread Jason Gloudon

We have indeed gone through this before. The last time the dominant argument
was that these types of mark/unmark operations can be mis-used just as readily
as malloc/free, because the programmer has to know when and where to call them.
I'm just repeating this for everyone's benefit, not giving an opinion.

Another approach to to register the address of the PMC * variables instead of
registering the pointers themselves. This way you let the collector know where
the automatic variables that may hold PMC pointers are and before that function
returns a single call is made to unregister all of those variables. This makes
for simple programming rules, but makes for more overhead everwhere it is used.
This is one way of achieving accurate garbage collection without compiler
support.

Using register and stack walking means the garbage collector must be
conservative in considering data unreachable, as random bytes on the stack or
in registers that look like valid PMC pointers must be treated as such. A
single such value can cause the collector to retain an unbounded amount of data
that is genuinely unreachable (and possibly delaying destruction). This is the
main problem with conservative garbage collection. The additional CPU
overhead now shows up when the collector runs because it has to do more work to
decide what is a PMC pointer and what is not.

I personally prefer the accurate collector approach for parrot, because it
makes for more predictable performance with zero platform dependent code. Sun
moved to an accurate collector in their production JVM when they introducted
HotSpot.

In any case, I've sent about 2 iterations of a patch to handle SPARC register
windows.  To deal with IA-64 and that one platform with non-contiguous stack
frames, we would have to refactor the trace_system_stack function to trace
contiguous chunks of memory. The platform dependent code for IA-64 et al will
want something like this.

BTW... IA-64 seems like such a non-starter of platform, that some might argue
it's not worth making it a core platform for parrot at this time.

-- 
Jason



Re: [CVS ci] JIT cleanup, core.jit templates, i386: more jitted ops

2002-11-22 Thread Jason Gloudon
On Fri, Nov 22, 2002 at 02:04:20PM +0100, Leopold Toetsch wrote:

 Parrot_sub_i_i {
 Parrot_binop_x_x s/op/sub/ s/_N//
 }

The only question I have is .. How am I supposed to read/translate the above ?

-- 
Jason



Re: Tinderbox

2002-11-21 Thread Jason Gloudon
On Thu, Nov 21, 2002 at 08:34:04AM +0100, Leopold Toetsch wrote:

My patch in 16237 has the code to flush register windows on v8 and older and v9
(64-bit) SPARC systems, which is what one is really trying to achieve via
setjmp.

-- 
Jason



Re: Tinderbox

2002-11-21 Thread Jason Gloudon

On Thu, Nov 21, 2002 at 10:28:42AM -0500, Andy Dougherty wrote:
  +#ifdef HAS_HEADER_SETJMP
  +jmp_buf env;
  +
  +/* this should put registers in env, which then get marked in
  + * trace_system_stack below
  + */
  +setjmp(env);
  +#endif
 
 Alas, no, though it seems to me you may be on the right track.  What
 appears to be happening is that sub.c is getting lex-names from list_new,
 but (when compiled with optimization) list_new is returning a list that is
 not on the stack.  Indeed, if I try to use the debugger and print list
 while in list_new, I simply get

After a bit of research on google I found that setjmp on SPARC only saves the
stack pointer, the frame pointer and the program counter, which is why the
setjmp technique does not work. longjmp() on the other hand does do a window
flush in order to unroll stack frames.

-- 
Jason



Re: Tinderbox

2002-11-21 Thread Jason Gloudon
On Thu, Nov 21, 2002 at 11:59:36AM -0500, Andy Dougherty wrote:

 While compiling, I did get the warnings:
 
 cpu_dep.c, line 24: warning: initializer does not fit or is out of
 range: 0x91d02003
 cpu_dep.c, line 26: warning: initializer does not fit or is out of
 range: 0x81c3e008

That in itself shouldn't have mattered (signed/unsigned) but this version does
fix the lexicals.t test failures.

-- 
Jason

/* cpu_dep.c
 *  Copyright: (When this is determined...it will go here)
 *  CVS Info
 * $Id$
 *  Overview:
 * CPU dependent functions
 *  Data Structure and Algorithms:
 *  History:
 *  Notes:
 *  References:
 */

#include parrot/parrot.h

void flush_register_windows(void){

#ifdef __sparc

static union {
int insns[4];
double align_hack[2];
} u = { {
#ifdef __sparcv9
0x8158, /* flushw */
#else
0x91d02003, /* ta ST_FLUSH_WINDOWS */
#endif
0x81c3e008, /* retl */ 
0x0100  /* nop */
} };

static void (*fn_ptr)(void) = (void (*)(void))u.align_hack[0];
fn_ptr();

#else

return;

#endif
}

? cpu_dep.c
Index: MANIFEST
===
RCS file: /cvs/public/parrot/MANIFEST,v
retrieving revision 1.256
diff -u -r1.256 MANIFEST
--- MANIFEST21 Nov 2002 04:30:56 -  1.256
+++ MANIFEST21 Nov 2002 22:55:03 -
@@ -1657,3 +1657,4 @@
 vtable.tbl
 vtable_h.pl
 warnings.c
+cpu_dep.c
Index: dod.c
===
RCS file: /cvs/public/parrot/dod.c,v
retrieving revision 1.32
diff -u -r1.32 dod.c
--- dod.c   6 Nov 2002 08:52:07 -   1.32
+++ dod.c   21 Nov 2002 22:55:03 -
@@ -20,6 +20,7 @@
 int CONSERVATIVE_POINTER_CHASING = 0;
 #endif
 
+extern flush_register_windows(void);
 static size_t find_common_mask(size_t val1, size_t val2);
 
 PMC *
@@ -494,6 +495,9 @@
 
 size_t mask = find_common_mask(buffer_min  pmc_min ? buffer_min : pmc_min,
 buffer_max  pmc_max ? buffer_max : pmc_max);
+
+/* Flush register windows if needed */
+flush_register_windows();
 
 if (!lo_var_ptr)
 return last;
Index: config/gen/makefiles/root.in
===
RCS file: /cvs/public/parrot/config/gen/makefiles/root.in,v
retrieving revision 1.58
diff -u -r1.58 root.in
--- config/gen/makefiles/root.in20 Nov 2002 17:46:47 -  1.58
+++ config/gen/makefiles/root.in21 Nov 2002 22:55:03 -
@@ -106,7 +106,7 @@
packout$(O) byteorder$(O) debug$(O) smallobject$(O) \
headers$(O) dod$(O) method_util$(O) exit$(O) \
misc$(O) spf_render$(O) spf_vtable$(O) datatypes$(O) fingerprint$(O) \
-   nci$(O)
+   nci$(O) cpu_dep$(O)
 
 O_FILES = $(INTERP_O_FILES) $(IO_O_FILES) $(CLASS_O_FILES) \
$(ENCODING_O_FILES) $(CHARTYPE_O_FILES)
@@ -424,6 +424,8 @@
 exit$(O) : $(GENERAL_H_FILES) exit.c
 
 nci$(O) : $(GENERAL_H_FILES) exit.c
+
+cpu_dep$(O) : $(GENERAL_H_FILES)
 
 #core_ops depends upon config.h so that it gets updated along with updates to 
config.h's version numbers
 core_ops.c $(INC)/oplib/core_ops.h : $(OPS_FILES) ops2c.pl lib/Parrot/OpsFile.pm 
lib/Parrot/Op.pm $(INC)/config.h



Re: Quick note on JIT bits

2002-11-14 Thread Jason Gloudon
On Thu, Nov 14, 2002 at 04:28:00PM +0100, Leopold Toetsch wrote:

 - Normal runloops don't have a problem with longjmp
 
 - JIT could have it's own low level exception handler:
 * gets jumped to, so registers are still ok

I am not clear how this works if the exception is triggered in a C function
called from JIT code. 

 * saves processor registers to parrots
 * then longjmps to parrot handler
 
 As we already seem to need to restore processor registers on resume, we 
 could do the reverse thing on exception too.
 
 
 Nicholas Clark
 
 leo

-- 
Jason



Re: Quick note on JIT bits

2002-11-14 Thread Jason Gloudon
On Thu, Nov 14, 2002 at 04:28:00PM +0100, Leopold Toetsch wrote:

 But I have a proposal:
 
 - Normal runloops don't have a problem with longjmp
 
 - JIT could have it's own low level exception handler:

What happens when C code called from the JIT generated code generates an
exception ?

 * gets jumped to, so registers are still ok
 * saves processor registers to parrots
 * then longjmps to parrot handler

-- 
Jason



Re: Quick note on JIT bits

2002-11-14 Thread Jason Gloudon
On Thu, Nov 14, 2002 at 05:55:21PM +0100, Leopold Toetsch wrote:

 But above is only needed, if there are callee saved registers around 
 which hold parrot register values not already saved. So currently not, 
 because there are no unsaved registers, when calling external code and 
 jitted OPs currently don't throw exceptions.

If the JIT allocates any parrot register contents to caller-save registers,
those registers must be saved to backing store-somewhere. On IA-32 the only
place those registers can be spilled is RAM, either on the stack or on the
heap. In this case, you basically have the scheme I described.

If the JIT allocates any parrot register contents to callee-save registers
(which we use strictly as such), and calls an external function that raises an
exception, you cannot restore the contents of those registers to Parrot
registers after the external function raises an exception because you do not
know where or how the compiler has saved the registers.

-- 
Jason



Re: Quick note on JIT bits

2002-11-14 Thread Jason Gloudon
On Thu, Nov 14, 2002 at 04:28:00PM +0100, Leopold Toetsch wrote:

 - JIT could have it's own low level exception handler:
 * gets jumped to, so registers are still ok
 * saves processor registers to parrots
 * then longjmps to parrot handler

I didn't finish my response...

The way I have thought this would be done (given C opcode functions raising
exceptions) is to spill parrot registers back into the interpreter structure
from hardware registers before calling opcode functions that might raise
exceptions using longjmp.  Spill here means we update the interpreter structure
registers, but consider the CPU register values still valid if the opcode does
not raise an exception. 

JIT code that needs to raise an exception can do the same thing as C code, call
the exception raising function that does a longjmp.

The runops loop would use setjmp to catch the exception and will do one of at
least two things:

Determine that the exception resumes control at an op that can be safely
jumped to in JIT generated code. In other words the op is not in the middle of
a section of code for which the JIT code assumes a certain register allocation.

Or

Find that the execution resumes control somewhere that is not safe to jump to
in the JIT code (or has not been JIT compiled), and passes control to the
interpreter runops loop.

The remaining issue is then determining when it is again safe to resume jit
execution so that control can be passed back to the JIT code. I have a few
ideas on doing this, but I'd like to hear what folks have to suggest. As has
been pointed out a few times before, exceptions and the restart ops present the
same problem.

The fact is that the above complication will be necessary once we start dealing
with multiple non-contiguous bytecode segments, as I do not expect one will JIT
compile every piece of code because of the inefficiency of doing that (unless
we make the JIT code less specialized than it is on at least IA-32/x86, where
addresses of registers and the interpreter pointer are embedded in the
generated code).

-- 
Jason



Re: [CVS ci] JIT t/op/interp_2 - i386

2002-11-12 Thread Jason Gloudon
On Tue, Nov 12, 2002 at 04:03:35PM +0100, Leopold Toetsch wrote:

 Some notes WRT implementation in i386:
 The first code in JIT is emitted by Parrot_jit_begin, the last 5 bytes
 of this code are 5 nop's now.
 When JIT is called again with a pc != code_start, i.e. for restart at
 pc, then a jump instruction to the native offset to this pc is patched
 into the JIT code.

Instead of patching the code, we can pass pc to the native code and have the
preamble jump to the corresponding native code address. This avoids the need to
flush the instruction cache since we don't modify any code that the CPU has
already executed.

This works for now, but the way I was going to fix this was to call longjmp
(through a wrapper function) from the native code in order to exit the native
code and get back to the runops loop. Once multiple bytecode segments become a
reality, this will be necessary as the native code will need to transfer
control to an interpreter loop in order to execute code that has not been
compiled.

-- 
Jason



Re: Need for fingerprinting? [was: Re: What to do if Digest::MD5 is unavailable?]

2002-11-04 Thread Jason Gloudon
On Sun, Nov 03, 2002 at 04:59:22PM -0500, [EMAIL PROTECTED] wrote:

 What I advocate is having possibly only one (maybe too extreme, but 
 doable) built-in op pre-loaded
 at opcode zero. This op's name is useop, and its arguments give an 
 opcode (optable index), and
 sufficent information for the interpreter to chase down the opinfo (and 
 opfunc). In the best scenario, this

One question this raises is where does this initialization occur ?

I think the information that would be encoded in these instructions should
normally go into a metadata section of the bytecode stored on disk. Having to
pseudo-execute the bytecode in order to disassemble seems unnecessary. I think
keeping this information separete from the executable section will make the
code generators simpler as well.

-- 
Jason



Re: [perl #18127] [PATCH] Implicit stack direction probe

2002-10-29 Thread Jason Gloudon
On Tue, Oct 29, 2002 at 02:40:14PM +0100, Leopold Toetsch wrote:

 +cur_var_ptr = (size_t)((ptrdiff_t)cur_var_ptr + 
 PARROT_PTR_ALIGNMENT)
 
 When PARROT_PTR_ALIGNMENT is not 1, that much pointers -1 are skipped 
 during stack scanning by incrementing cur_var_ptr by sizeof(size_t) * 
 PARROT_PTR_ALIGNMENT bytes.

ptrdiff_t is not a pointer type, so cur_var_ptr + PARROT_PTR_ALIGNMENT skips
exactly PARROT_PTR_ALIGNMENT bytes. You may not be matching ( )'s quite right.

 As a side note: applying your patch slows down e.g. life.pasm by ~2%.
 (I really don't see why).

Are you compiling with optimization enabled ? Is the difference consistent ?
If the answer to both questions is yes, it is probably a cache effect related
to the new variable on the function stack. I doubt the slowdown is universal.
I will try to check on SPARC sometime today.

-- 
Jason



Re: [perl #18127] [PATCH] Implicit stack direction probe

2002-10-29 Thread Jason Gloudon
On Tue, Oct 29, 2002 at 12:17:55PM -0600, Garrett Goebel wrote:
 Dan Sugalski wrote:
  Leopold Toetsch wrote:
  
   Can we really have e.g. odd aligned PMCs on stack?
 
  the specs are available *somewhere*, and we should see
  about digging them up and getting a final answer one way
  or another.

The system V ABI for IA-32(32-bit x86) does not specify how a compiler should
align local variables on the stack. There are ABI rules for aligning structure
members, and variables passed between functions, but both Visual C++ and gcc
allow the programmer to request packing of structures which ignores these
rules. By default both compilers align stack variables at their natural
alignment, so PMC pointers would normally fall on 4 byte boundaries.

However, it is also possible that someone might save a PMC pointer to an
unaligned address on the stack (I can't imagine why). We could always say
don't do that! for performance reasons.

-- 
Jason



[PATCH] Implicit stack direction probe

2002-10-25 Thread Jason Gloudon
On Fri, Oct 25, 2002 at 01:01:16PM +0100, Nicholas Clark wrote:

 What is wrong with any of
 
 1: Duplicating the above loop (which isn't large), one for upwards stack,
the other for downwards stack, and switching (outside) between the two
based on an if statement on a global stack direction variable.

Here is what I suggested in a previous email. Always walk the stack in the same
direction, regardless of the direction in which it grows. PARROT_STACK_DIR is
not used.

Non-contiguous stack systems will have to use an entirely different version of
the stack walking function. This is left as an exercise for the reader.

-- 
Jason

Index: dod.c
===
RCS file: /cvs/public/parrot/dod.c,v
retrieving revision 1.24
diff -u -r1.24 dod.c
--- dod.c   23 Oct 2002 05:27:01 -  1.24
+++ dod.c   25 Oct 2002 21:55:24 -
 -460,7 +460,7 
 {
 size_t lo_var_ptr = (size_t)interpreter-lo_var_ptr;
 size_t hi_var_ptr = (size_t)lo_var_ptr;
-size_t prefix;
+size_t prefix, tmp_ptr;
 ptrdiff_t cur_var_ptr;
 
 size_t buffer_min = get_min_buffer_address(interpreter);
 -471,6 +471,12 
 size_t mask = find_common_mask(buffer_min  pmc_min ? buffer_min: pmc_min,
 buffer_max  pmc_max ? buffer_max : pmc_max);
 
+if(lo_var_ptr  hi_var_ptr){
+tmp_ptr = hi_var_ptr;
+hi_var_ptr = lo_var_ptr;
+lo_var_ptr = tmp_ptr;
+}
+
 /* Get the expected prefix */
 prefix = mask  buffer_min;
 
 -478,10 +484,8 
 return last;
 
 for (cur_var_ptr = lo_var_ptr;
-(ptrdiff_t)(cur_var_ptr * PARROT_STACK_DIR)  
-(ptrdiff_t)(hi_var_ptr * PARROT_STACK_DIR);
-cur_var_ptr = (size_t)( (ptrdiff_t)cur_var_ptr + 
-PARROT_STACK_DIR * PARROT_PTR_ALIGNMENT )
+cur_var_ptr  hi_var_ptr;
+cur_var_ptr = (size_t)((ptrdiff_t)cur_var_ptr + PARROT_PTR_ALIGNMENT)
  ) {
 size_t ptr = *(size_t *)cur_var_ptr;
 



Re: [PATCH] Probe stack direction at run-time (was Re: Configuring and DOD problems)

2002-10-24 Thread Jason Gloudon
On Wed, Oct 23, 2002 at 11:23:26PM -0400, Josh Wilmes wrote:

 I've got a patch which switches this detection to happen at run-time 
 instead of at build-time.   This is going to be necessary for miniparrot 
 (which has no Configure step) anyway.

Have you checked how much this affects the performance of stack walking ?

The current stack direction tests make the stack direction a compile time
constant, so that the compiler can optimize away the multiplications in the
stack walking loop which can be pretty expensive.

The original stack direction tests were run-time, and I changed them to be done
at configure time to simplify doing them in a more correct way while also
making the code faster.

One way of simplifying things here is to always walk the stack in the same
direction (lowest address to higher address), and swap the lo and high pointer
as the start and end points of the loop. This eliminates the need for an
explicit stack growth direction test.

One thing that will still remain is that the garbage collector must know the
CPU instruction set so it can use the appropriate means to locate pointers in
registers. I'm not sure if this can be done by testing for preprocessor symbols
alone.

-- 
Jason



Re: [PATCH] Probe stack direction at run-time (was Re: Configuring and DOD problems)

2002-10-24 Thread Jason Gloudon
On Thu, Oct 24, 2002 at 04:47:05PM -0400, Josh Wilmes wrote:

   I've got a patch which switches this detection to happen at run-time 
   instead of at build-time.   This is going to be necessary for miniparrot 
   (which has no Configure step) anyway.
  
  Have you checked how much this affects the performance of stack walking ?
 
 It shouldn't at all.  It does the check once, when parrot starts up.

It will. If you read the following paragraph I explained why it will be slower,
and it has nothing to do with how often the check is performed.

STACK_DIR is a compile time constant, so the multiplies in the following code
are eliminated by the compiler if it does any optimization.  By making
STACK_DIR a variable, the compiler is no longer able to do this and has to
generate code to do multiplies.

for (cur_var_ptr = lo_var_ptr;
(ptrdiff_t)(cur_var_ptr * PARROT_STACK_DIR) 
(ptrdiff_t)(hi_var_ptr * PARROT_STACK_DIR);
cur_var_ptr = (size_t)( (ptrdiff_t)cur_var_ptr +
PARROT_STACK_DIR * PARROT_PTR_ALIGNMENT )

-- 
Jason



Re: Two problems groping around in PerlHashes

2002-10-20 Thread Jason Gloudon
On Sun, Oct 20, 2002 at 12:32:24PM +0200, Leopold Toetsch wrote:

 PDD02 specifies the needed methods
 
   exists_keyed
   type_keyed

The vtable PDD refers to type_keyed returning the type of the *PMC*.  This
isn't accurate given the question. Should we change the PDD ?

 perlhash/array have exists_keyed (but no type_keyed), though the opcodes 
 are missing.

On a tangent:

Shouldn't a Perl Hash be a homogenous data structure, ie. it should contain
just PMCs ?

-- 
Jason



Re: [perl #17931] [PATCH] DOD/GC related

2002-10-14 Thread Jason Gloudon

On Mon, Oct 14, 2002 at 08:31:16PM +, Leopold Toetsch wrote:

 headers.c:
 - set PMCs and Buffers initially to live. This helps somwhat, that 
 initially created objects are not killed immediately by a DOD run e.g. 
 in midst of string_make

But what happens where there is more than one DOD run ?

The problem sounds like that the collector is not looking in all the
appropriate places for these PMCs and Buffers. I have not looked in a while but
has anyone added the necessary code to examine CPU registers for PMC and Buffer
pointers ?

-- 
Jason



Re: [INFO] news about Lea allocator

2002-10-02 Thread Jason Gloudon

On Wed, Oct 02, 2002 at 02:01:48PM +0200, Leopold Toetsch wrote:
 As already posted I incorparated the allocator from 
 http://gee.cs.oswego.edu/dl/html/malloc.html
 in parrot.

Whatever source you are using cannot be the original Lea malloc, since it does
not do garbage collection. There are many comments indicating that the GNU C
library uses a derived version of Lea malloc.

You must be using one of the derived works that implements a conservative
non-copying garbage collector. The Boehm-Demers-Weiser collector is a similar
system but I do not believe it is based on the Lea malloc code.

 The latter seems to indicate, that current copying GC has problems with 
 massive live data, where significant amounts of memory must be copied 
 around, i.e. bigger real life apps ;-)

This is a well understood problem with copying collectors, and is the reason
that the current state of the art is generational garbage collection, which
scans/copies longer lived data less frequently as it is more likely to remain
live.

-- 
Jason



Re: Of PMCs Buffers and memory management

2002-09-27 Thread Jason Gloudon

On Fri, Sep 27, 2002 at 09:28:41AM +0200, Leopold Toetsch wrote:

 First and foremost, is there any compelling reason, to have totally
 different structures for PMCs and Buffers?

The reasons stopped being compelling about a month or two ago, when it was
decided to unify the two. No one has had the time and knowledge to do it.

-- 
Jason



Re: PMC assignment stuff

2002-08-27 Thread Jason Gloudon

Dan Sugalski wrote:

 First, for simple X = Y cases, we need a new assignment opcode. We 
 have SET to copy pointers, CLONE to make full clones, but we don't 
 have a method to stuff a value from one PMC to another.
 
 So, what we need to do is add ASSIGN Px, Py, which takes Px and calls 
 set_pmc with Py as a parameter. At that point, it's up to Px's vtable 
 to decide what to do with the incoming data.
 
 For assignment in general, it's up to the assignee to decide what to 
 do with the incoming data. In most cases it'll either be a morph 
 (which the destination will take care of), a value copy (if the 
 destination type is fixed), or some sort of Weird Magic (for tied 
 variables). We may want to implement multimethod dispatch for 
 assignment.
 
 This includes all forms of assignment, not just the ASSIGN op kind. 
 When we do an ADD Px, Py, Pz, we're calling Px's set_pmc vtable entry 
 with a PMC that represents the addition of Y and Z. Whether X changes 
 its type is entirely up to it, as that's what it's supposed to 
 determine.

So this means that ADD will have to create a temporary PMC to hold the result
which it then passes to set_pmc ? What does set_pmc then do, in the case of a
normal assignment with no magic or fixed type in order to perform the
assignment ?

-- 
Jason



Re: Stack Walk Speedups?

2002-08-17 Thread Jason Gloudon

On Sat, Aug 17, 2002 at 10:23:32PM +0200, Peter Gibbs wrote:

 If you want to get some improvement at the cost of some duplicated
 code, you can remove the * direction logic, and write two copies of the 
 loop. (patch attached, but not fully tested)

 I'm sure there is more that can be done, but that may help for now.

The configure-time-stack-growth-direction patch makes these #define'd constants,
so you get the same speedup.

-- 
Jason



Re: [perl #16278] [PATCH] Quicker pointer checking for stack walking

2002-08-17 Thread Jason Gloudon

On Sun, Aug 18, 2002 at 02:51:34AM +, Jason Gloudon wrote:
 # New Ticket Created by  Jason Gloudon 
 # Please include the string:  [perl #16278]
 # in the subject line of all future correspondence about this issue. 
 # URL: http://rt.perl.org/rt2/Ticket/Display.html?id=16278 

Moved the static prototype to dod.c

-- 
Jason


Index: dod.c
===
RCS file: /cvs/public/parrot/dod.c,v
retrieving revision 1.13
diff -u -r1.13 dod.c
--- dod.c   17 Aug 2002 01:11:08 -  1.13
+++ dod.c   18 Aug 2002 03:20:43 -
 -1,7 +1,7 
 /* dod.c 
  *  Copyright: (When this is determined...it will go here)
  *  CVS Info
- * $Id: dod.c,v 1.13 2002/08/17 01:11:08 sfink Exp $
+ * $Id: dod.c,v 1.12 2002/08/14 00:10:48 grunblatt Exp $
  *  Overview:
  * Handles dead object destruction of the various headers
  *  Data Structure and Algorithms:
 -14,6 +14,8 
 
 #include parrot/parrot.h
 
+static size_t find_common_mask(size_t val1, size_t val2);
+
 PMC *
 mark_used(PMC *used_pmc, PMC *current_end_of_list)
 {
 -329,11 +331,32 
 }
 
 #ifndef PLATFORM_STACK_WALK
+
+/* Find a mask covering the longest common bit-prefix of val1 and val2 */
+static size_t
+find_common_mask(size_t val1, size_t val2){
+int i, count;
+int bound = sizeof(size_t) * 8;
+
+for(i = 0; i  bound; i++){
+if(val1 == val2){
+return ~(size_t)0  i;
+}
+val1 = 1;
+val2 = 1;
+}
+
+internal_exception(INTERP_ERROR,
+   Unexpected condition in find_common_prefix()!\n);
+return 0;
+}
+
 PMC*
 trace_system_stack(struct Parrot_Interp *interpreter, PMC *last)
 {
 size_t lo_var_ptr = (size_t)interpreter-lo_var_ptr;
 size_t hi_var_ptr = (size_t)lo_var_ptr;
+size_t prefix;
 ptrdiff_t cur_var_ptr;
 ptrdiff_t direction = (hi_var_ptr  lo_var_ptr) ? 1 : -1;
 
 -342,6 +365,12 
 size_t pmc_min = get_min_pmc_address(interpreter);
 size_t pmc_max = get_max_pmc_address(interpreter);
 
+size_t mask = find_common_mask(buffer_min  pmc_min ? buffer_min: pmc_min,
+buffer_max  pmc_max ? buffer_max : pmc_max);
+
+/* Get the expected prefix */
+prefix = mask  buffer_min;
+
 if (!lo_var_ptr)
 return last;
 
 -350,10 +379,14 
  cur_var_ptr = (size_t)( (ptrdiff_t)cur_var_ptr + direction * 
PARROT_PTR_ALIGNMENT )
  ) {
 size_t ptr = *(size_t *)cur_var_ptr;
-if (pmc_min = ptr  ptr  pmc_max  is_pmc_ptr(interpreter,(void *)ptr)) {
-last = mark_used((PMC *)ptr, last);
-} else if (buffer_min = ptr  ptr  buffer_max  
is_buffer_ptr(interpreter,(void *)ptr)) {
-buffer_lives((Buffer *)ptr);
+
+/* Do a quick approximate range check by bit-masking */
+if((ptr  mask) == prefix){
+if (pmc_min  ptr  ptr  pmc_max  is_pmc_ptr(interpreter,(void 
+*)ptr)) {
+last = mark_used((PMC *)ptr, last);
+} else if (buffer_min  ptr  ptr  buffer_max  
+is_buffer_ptr(interpreter,(void *)ptr)) {
+buffer_lives((Buffer *)ptr);
+}
 }
 }
 return last;



Re: [COMMIT] GC_DEBUG, Some GC Fixes, and Remaining GC Bugs

2002-08-12 Thread Jason Gloudon

On Mon, Aug 12, 2002 at 03:56:27AM -0400, Mike Lambert wrote:

Here is a workaround for one hash related GC bug.

-- 
Jason


Index: hash.c
===
RCS file: /cvs/public/parrot/hash.c,v
retrieving revision 1.19
diff -u -r1.19 hash.c
--- hash.c  7 Aug 2002 20:27:53 -   1.19
+++ hash.c  12 Aug 2002 20:00:16 -
 -285,6 +285,7 
 new_hash(Interp *interpreter)
 {
 HASH *hash = (HASH *)new_bufferlike_header(interpreter, sizeof(*hash));
+   volatile Buffer *for_gc;
 /*  hash-buffer.flags |= BUFFER_report_FLAG; */
 
 /* We rely on the fact that expand_hash() will be called before
 -295,7 +296,12 
 hash-max_chain = (HashIndex) -1;
 
 hash-entries = 0;
-hash-bucket_pool = new_buffer_header(interpreter);
+
+/* In order to keep the bucket_pool header from being
+ * collected from expand_hash(), a pointer to it is put on
+ * the system stack where the stack walking code can find it */
+for_gc = hash-bucket_pool = new_buffer_header(interpreter);
+
 /*  hash-bucket_pool-flags |= BUFFER_report_FLAG; */
 hash-free_list = NULLBucketIndex;
 expand_hash(interpreter, hash);




Re: [COMMIT] GC_DEBUG, Some GC Fixes, and Remaining GC Bugs

2002-08-12 Thread Jason Gloudon

On Mon, Aug 12, 2002 at 09:48:56PM +0100, Nicholas Clark wrote:

 This is a case of a temporary allocated value being only in a CPU register?

Not in this case. The link to the hash structure from the PMC is not
established, which prevents the custom mark routine in the PMC from identifying
the buffer in question. Another way of fixing this is to change new_hash to
accept a pointer to the PMC's -data pointer so it can initialize this before
doing any further allocation. 

 But I believe that we still need to check for pointers in the CPU registers,
 because on a register rich CPU is is not impossible that something has the
 only pointer to an in use value still only in a CPU register.

Yes. This is definitely necessary. We also need to flush register windows on
platforms like SPARC, IA-64.

-- 
Jason



[PATCH] hash init Was [COMMIT] GC_DEBUG, Some GC Fixes, and Remaining GC Bugs

2002-08-12 Thread Jason Gloudon


Here is another way of resolving this, as I mentioned in the last message.
Having new_hash() initialize the PMC's data pointer so that the hash is
immediately visible to the collector.

-- 
Jason


Index: parrot/hash.c
===
RCS file: /cvs/public/parrot/hash.c,v
retrieving revision 1.19
diff -u -r1.19 hash.c
--- parrot/hash.c   7 Aug 2002 20:27:53 -   1.19
+++ parrot/hash.c   12 Aug 2002 23:10:04 -
 -281,10 +281,12 
 return NULL;
 }
 
-HASH *
-new_hash(Interp *interpreter)
+void
+new_hash(Interp *interpreter, HASH **hash_ptr)
 {
 HASH *hash = (HASH *)new_bufferlike_header(interpreter, sizeof(*hash));
+*hash_ptr = hash;
+
 /*  hash-buffer.flags |= BUFFER_report_FLAG; */
 
 /* We rely on the fact that expand_hash() will be called before
 -299,7 +301,6 
 /*  hash-bucket_pool-flags |= BUFFER_report_FLAG; */
 hash-free_list = NULLBucketIndex;
 expand_hash(interpreter, hash);
-return hash;
 }
 
 /*=for api key hash_size
 -412,9 +413,10 
 
 HASH *
 hash_clone(struct Parrot_Interp * interp, HASH * hash) {
-HASH * ret = new_hash(interp);
+HASH *ret;
 BucketIndex* table = (BucketIndex*) hash-buffer.bufstart;
 BucketIndex i;
+new_hash(interp, ret);
 for (i = 0; i = hash-max_chain; i++) {
 HASHBUCKET * b = lookupBucket(hash, i);
 while (b) {
Index: parrot/classes/perlhash.pmc
===
RCS file: /cvs/public/parrot/classes/perlhash.pmc,v
retrieving revision 1.25
diff -u -r1.25 perlhash.pmc
--- parrot/classes/perlhash.pmc 12 Aug 2002 07:47:06 -  1.25
+++ parrot/classes/perlhash.pmc 12 Aug 2002 23:10:04 -
 -61,7 +61,7 
 undef-flags |= PMC_constant_FLAG;
 }
 SELF-flags |= PMC_custom_mark_FLAG;
-SELF-data = new_hash(INTERP);
+new_hash(INTERP, (HASH **)SELF-data);
 }
 
 /* The end of used parameter is passed into the mark_used function of
Index: parrot/include/parrot/hash.h
===
RCS file: /cvs/public/parrot/include/parrot/hash.h,v
retrieving revision 1.6
diff -u -r1.6 hash.h
--- parrot/include/parrot/hash.h7 Aug 2002 19:02:06 -   1.6
+++ parrot/include/parrot/hash.h12 Aug 2002 23:10:05 -
 -20,7 +20,7 
 /* HASH is really a hashtable, but 'hash' is standard perl nomenclature. */
 typedef struct _hash HASH;
 
-HASH *new_hash(Interp * interpreter);
+void new_hash(Interp * interpreter, HASH **hash_ptr);
 HASH *hash_clone(Interp * interpreter, HASH * hash);
 INTVAL hash_size(Interp * interpreter, HASH *hash);
 void hash_set_size(Interp * interpreter, HASH *hash, UINTVAL size);





[PATCH] hash init (Version 2)

2002-08-12 Thread Jason Gloudon

The last patch had an issue I didn't see on the test I was working against.
mark_hash() assumes the buffer_pool is always initialized, but with the patch
this is no longer the case.

-- 
Jason


Index: parrot/hash.c
===
RCS file: /cvs/public/parrot/hash.c,v
retrieving revision 1.19
diff -u -r1.19 hash.c
--- parrot/hash.c   7 Aug 2002 20:27:53 -   1.19
+++ parrot/hash.c   13 Aug 2002 00:20:39 -
 -126,7 +126,9 
 HashIndex i;
 
 buffer_lives((Buffer *)hash);
-buffer_lives(hash-bucket_pool);
+if(hash-bucket_pool){
+buffer_lives(hash-bucket_pool);
+}
 
 for (i = 0; i = hash-max_chain; i++) {
 HASHBUCKET *bucket = lookupBucket(hash, i);
 -281,10 +283,12 
 return NULL;
 }
 
-HASH *
-new_hash(Interp *interpreter)
+void
+new_hash(Interp *interpreter, HASH **hash_ptr)
 {
 HASH *hash = (HASH *)new_bufferlike_header(interpreter, sizeof(*hash));
+*hash_ptr = hash;
+
 /*  hash-buffer.flags |= BUFFER_report_FLAG; */
 
 /* We rely on the fact that expand_hash() will be called before
 -295,11 +299,13 
 hash-max_chain = (HashIndex) -1;
 
 hash-entries = 0;
+
+/* Ensure mark_hash doesn't try to mark the buffer live */
+hash-bucket_pool = NULL;
 hash-bucket_pool = new_buffer_header(interpreter);
 /*  hash-bucket_pool-flags |= BUFFER_report_FLAG; */
 hash-free_list = NULLBucketIndex;
 expand_hash(interpreter, hash);
-return hash;
 }
 
 /*=for api key hash_size
 -412,9 +418,10 
 
 HASH *
 hash_clone(struct Parrot_Interp * interp, HASH * hash) {
-HASH * ret = new_hash(interp);
+HASH *ret;
 BucketIndex* table = (BucketIndex*) hash-buffer.bufstart;
 BucketIndex i;
+new_hash(interp, ret);
 for (i = 0; i = hash-max_chain; i++) {
 HASHBUCKET * b = lookupBucket(hash, i);
 while (b) {
Index: parrot/classes/perlhash.pmc
===
RCS file: /cvs/public/parrot/classes/perlhash.pmc,v
retrieving revision 1.25
diff -u -r1.25 perlhash.pmc
--- parrot/classes/perlhash.pmc 12 Aug 2002 07:47:06 -  1.25
+++ parrot/classes/perlhash.pmc 13 Aug 2002 00:20:40 -
 -61,7 +61,7 
 undef-flags |= PMC_constant_FLAG;
 }
 SELF-flags |= PMC_custom_mark_FLAG;
-SELF-data = new_hash(INTERP);
+new_hash(INTERP, (HASH **)SELF-data);
 }
 
 /* The end of used parameter is passed into the mark_used function of
Index: parrot/include/parrot/hash.h
===
RCS file: /cvs/public/parrot/include/parrot/hash.h,v
retrieving revision 1.6
diff -u -r1.6 hash.h
--- parrot/include/parrot/hash.h7 Aug 2002 19:02:06 -   1.6
+++ parrot/include/parrot/hash.h13 Aug 2002 00:20:40 -
 -20,7 +20,7 
 /* HASH is really a hashtable, but 'hash' is standard perl nomenclature. */
 typedef struct _hash HASH;
 
-HASH *new_hash(Interp * interpreter);
+void new_hash(Interp * interpreter, HASH **hash_ptr);
 HASH *hash_clone(Interp * interpreter, HASH * hash);
 INTVAL hash_size(Interp * interpreter, HASH *hash);
 void hash_set_size(Interp * interpreter, HASH *hash, UINTVAL size);





Re: On writing JITs

2002-08-03 Thread Jason Gloudon

On Sat, Aug 03, 2002 at 11:35:08AM +0100, Nicholas Clark wrote:

 I presume in the general case I'd have to know whether to call
 Parrot_jit_normal_op() or Parrot_jit_cpcf_op(), so could there be a subroutine
 in jit.c that I could call to make the correct decision for me?

Here is a patch for the necessary function.

Index: jit.c
===
RCS file: /cvs/public/parrot/jit.c,v
retrieving revision 1.21
diff -u -r1.21 jit.c
--- jit.c   2 Aug 2002 03:24:02 -   1.21
+++ jit.c   3 Aug 2002 19:13:05 -
 -303,6 +303,18 
 (ptrdiff_t)(jit_info-native_ptr - jit_info-arena_start);
 }
 
+/* An op jitting function can call this function to emit the appropriate
+ * generic code to invoke the op function for the current op */
+
+void Parrot_jit_fallback(Parrot_jit_info *jit_info, struct Parrot_Interp * 
+interpreter){
+if(interpreter-op_info_table[*jit_info-cur_op].jump){
+Parrot_jit_cpcf_op(jit_info, interpreter);
+}
+else {
+Parrot_jit_normal_op(jit_info, interpreter);
+}
+}
+
 /*
  * Local variables:
  * c-indentation-style: bsd
Index: include/parrot/jit.h
===
RCS file: /cvs/public/parrot/include/parrot/jit.h,v
retrieving revision 1.16
diff -u -r1.16 jit.h
--- include/parrot/jit.h7 Jun 2002 04:58:45 -   1.16
+++ include/parrot/jit.h3 Aug 2002 19:13:06 -
 -97,6 +97,8 
 struct Parrot_Interp * interpreter);
 void Parrot_jit_normal_op(Parrot_jit_info *jit_info, 
   struct Parrot_Interp * interpreter);
+void Parrot_jit_fallback(Parrot_jit_info *jit_info, 
+ struct Parrot_Interp * interpreter);
 
 Parrot_jit_optimizer_t *
 optimize_jit(struct Parrot_Interp *, 

-- 
Jason



Re: On writing JITs

2002-08-03 Thread Jason Gloudon

On Sat, Aug 03, 2002 at 12:07:30PM -0400, Ken Fox wrote:
 Nicholas Clark wrote:
 It seems that foo  (foo - 1) is zero only for a power of 2 (or foo == 0) 
 but is there a fast way once you know that foo is a power of 2, to find out
 log2 foo?

The ARM doesn't have a find first set bit instruction ?

This code includes 3 different ways of finding log2.
 
http://www.ddj.com/ftp/2001/2001_07/aa0701.txt

I believe the LOOKUP method was the fastest for me on SPARC, if I recall
correctly.

-- 
Jason



Re: [perl #15922] [PATCH] jit documentatiion + tweaks

2002-08-01 Thread Jason Gloudon


Duh. Here's a unified diff.

-- 
Jason


Index: docs/jit.pod
===
RCS file: /cvs/public/parrot/docs/jit.pod,v
retrieving revision 1.4
diff -u -r1.4 jit.pod
--- docs/jit.pod29 Jul 2002 21:13:38 -  1.4
+++ docs/jit.pod1 Aug 2002 19:46:23 -
 -73,7 +73,9 
 =item jit/${jitcpuarch}/core.jit
 
 The functions to generate native code for core parrot opcodes are specified
-here.
+here. To simplify the maintenance of these functions, they are specified in a
+format that is pre-processed by Bjit2h.pl to produce a valid C source file,
+Bjit_cpu.c. See LFormat of .jit Files below.
 
 =item jit/${jitcpuarch}/string.jit
 
 -116,7 +118,7 
  
 =item jit2h.pl
 
-Reads the .jit files and prints the struct opcode_assembly_t.
+Preprocesses the .jit files to produce and prints the struct opcode_assembly_t.
 
 =back
 
 -129,12 +131,18 
 
 =item Iop-name { Ibody }
 
-Where Iop-name is the name of the Parrot opcode, and Ibody consists
-of a sequence of the following forms:
-
-=item Assembly instruction.
-
-Which may have one of this BIdentifiers as an argument: 
+Where Iop-name is the name of the Parrot opcode, and Ibody consists of C
+syntax code which may contain any of the identifiers listed in the following
+section.
+
+=item Identifiers
+
+In general, prefixing an identifier with I yields the address of the
+referenced Parrot register or constant.  If an identifier is given without a
+prefix, the value is returned by default.   To emphasis the use of the value,
+the I* prefix may be used.  Since Parrot register values vary during code
+execution, their values can not be obtained through identifier substitution
+alone.
 
 BINT_REG[n]
 
 -207,8 +215,6 
 BTEMP_CHAR[n]
 
 Gets replaced by the Inth temporary char array.
-
-You must preside all the identifiers with I requesting the address of that 
identifier, or I* requesting the value, I* can be used only with constants since 
the replacement is done before start running.
 
 BINTERPRETER[n]
 
Index: jit/i386/core.jit
===
RCS file: /cvs/public/parrot/jit/i386/core.jit,v
retrieving revision 1.20
diff -u -r1.20 core.jit
--- jit/i386/core.jit   5 Jul 2002 11:15:42 -   1.20
+++ jit/i386/core.jit   1 Aug 2002 19:46:23 -
 -5,7 +5,9 
 ;
 
 Parrot_end {
+emitm_addl_i_r(jit_info-native_ptr, 4, emit_ESP);
 NATIVECODE = emit_popl_r(NATIVECODE, emit_ESI);
+NATIVECODE = emit_popl_r(NATIVECODE, emit_EBP);
 emitm_ret(NATIVECODE);
 }
 
Index: jit/i386/jit_emit.h
===
RCS file: /cvs/public/parrot/jit/i386/jit_emit.h,v
retrieving revision 1.4
diff -u -r1.4 jit_emit.h
--- jit/i386/jit_emit.h 5 Jul 2002 11:11:09 -   1.4
+++ jit/i386/jit_emit.h 1 Aug 2002 19:46:24 -
 -98,7 +98,7 
 break;
 default :
 internal_exception(JIT_ERROR, Invalid scale factor %d\n, scale);
-break;
+return;
 }
 
 *pc = scale_byte | (i == emit_None ? emit_Index_None : emit_reg_Index(i)) |
 -108,8 +108,8 
 static char *emit_r_X(char *pc, int reg_opcode, int base, int i, int scale,
 long disp)
 {
-if((i  !scale) || (scale  !i)){
-internal_exception(JIT_ERROR,
+if(i  !scale){
+internal_exception(JIT_ERROR,
 emit_r_X passed invalid scale+index combo\n);
 }
 
 -341,6 +341,8 
 
 #define emitm_alul_i_r(pc, op1, op2, imm, reg) { *(pc++) = op1; *(pc++) = 
emit_alu_X_r(op2, reg); *(long *)((pc)) = (long)(imm); (pc) += 4; }
 
+#define emitm_alub_i_r(pc, op1, op2, imm, reg) { *(pc++) = op1; *(pc++) = 
+emit_alu_X_r(op2, reg); *(pc++) = (char)(imm); }
+
 #define emitm_alul_i_m(pc, op1, op2, imm, b, i, s, d) { \
  *(pc++) = op1; \
  (pc) = emit_r_X(pc, emit_reg(op2), b, i, s, d); \
 -366,6 +368,8 
 /* ADDs */
 
 #define emitm_addb_r_r(pc, reg1, reg2) emitm_alul_r_r(pc, 0x00, reg1, reg2)
+#define emitm_addb_i_r(pc, imm, reg)   emitm_alub_i_r(pc, 0x83, emit_b000, imm, reg)
+
 #define emitm_addl_r_r(pc, reg1, reg2) emitm_alul_r_r(pc, 0x01, reg1, reg2)
 #define emitm_addl_i_r(pc, imm, reg)   emitm_alul_i_r(pc, 0x81, emit_b000, imm, reg)
 #define emitm_addl_r_m(pc, reg, b, i, s, d) emitm_alul_r_m(pc, 0x01, reg, b, i, s, d)
 -667,14 +671,25 
 void Parrot_jit_begin(Parrot_jit_info *jit_info,
   struct Parrot_Interp * interpreter)
 {
+/* Maintain the stack frame pointer for the sake of gdb */
+jit_info-native_ptr = emit_pushl_r(jit_info-native_ptr, emit_EBP);
+emitm_movl_r_r(jit_info-native_ptr, emit_ESP, emit_EBP);
+
+/* Save ESI, as it's value is clobbered by jit_cpcf_op */
 jit_info-native_ptr = emit_pushl_r(jit_info-native_ptr, emit_ESI);
+
+/* Cheat on op function calls by writing the interpreter arg on the stack
+ * just once. If an op function ever modifies the interpreter argument on
+ * the stack this will stop 

[perl@gloudon.com: [PATCH] packfile reading]

2002-06-12 Thread Jason Gloudon


Could someone apply this ?

- Forwarded message from Jason Gloudon [EMAIL PROTECTED] -

Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm
Precedence: bulk
Delivered-To: mailing list [EMAIL PROTECTED]
Date: Mon, 10 Jun 2002 19:33:56 -0400
From: Jason Gloudon [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Subject: [PATCH] packfile reading
User-Agent: Mutt/1.3.25i


This fixes the problem with reading .pbc files on win32. Someone may want to
write the code to do something useful with the results of stat() when mmap() is
not being used.


Index: assemble.pl
===
RCS file: /cvs/public/parrot/assemble.pl,v
retrieving revision 1.66
diff -u -r1.66 assemble.pl
--- assemble.pl 10 Jun 2002 05:40:06 -  1.66
+++ assemble.pl 10 Jun 2002 23:24:45 -
@@ -813,6 +813,7 @@
   close FILE;
 }
 else {
+  binmode STDOUT;
   print $bytecode;
 }
 
Index: embed.c
===
RCS file: /cvs/public/parrot/embed.c,v
retrieving revision 1.26
diff -u -r1.26 embed.c
--- embed.c 8 Jun 2002 03:38:45 -   1.26
+++ embed.c 10 Jun 2002 23:24:45 -
@@ -110,6 +110,7 @@
 INTVAL read_result;
 
 program_code = (char *)malloc(program_size + 1024);
+program_size = 0;
 if (NULL == program_code) {
 fprintf(stderr,
 Parrot VM: Could not allocate buffer to read packfile from 
PIO.\n);

- End forwarded message -

-- 
Jason



Re: [netlabs #702] BASIC causes sevg's in parrot

2002-06-12 Thread Jason Gloudon

On Tue, Jun 11, 2002 at 12:04:19PM -, Clinton A. Pierce wrote:
 # New Ticket Created by  Clinton A. Pierce 
 # Please include the string:  [netlabs #702]
 # in the subject line of all future correspondence about this issue. 
 # URL: http://bugs6.perl.org/rt2/Ticket/Display.html?id=702 
 
 
 To reproduce, sync with CVS, build, run basic.pl -- that's all.  This 
 version of BASIC is unchanged since it last worked

The problem was with my last stack patch. During DOD the control stack chunks
have to be walked now, since their contents are allocated using buffers.

-- 
Jason


Index: resources.c
===
RCS file: /cvs/public/parrot/resources.c,v
retrieving revision 1.63
diff -u -r1.63 resources.c
--- resources.c 12 Jun 2002 22:58:29 -  1.63
+++ resources.c 13 Jun 2002 00:44:42 -
 -428,7 +428,7 
 }
 }
 
-/* Finally the general stack */
+/* Now the general stack */
 start_stack = cur_stack = interpreter-user_stack;
 chunks_traced = 0;
 /* The general stack's circular, so we need to be careful */
 -442,6 +442,19 
 buffer_lives((Buffer *)entry[i].entry.string_val);
 }
 }
+}
+
+chunks_traced++;
+cur_stack = cur_stack-prev;
+}
+
+   /* Finally the control stack frames must be marked live */
+start_stack = cur_stack = interpreter-control_stack;
+chunks_traced = 0;
+/* This stack, like the general stack is circular */
+while (cur_stack  ((start_stack != cur_stack) || (chunks_traced == 0))) {
+if(cur_stack-buffer){ 
+buffer_lives(cur_stack-buffer);
 }
 
 chunks_traced++;





[PATCH] packfile reading

2002-06-10 Thread Jason Gloudon


This fixes the problem with reading .pbc files on win32. Someone may want to
write the code to do something useful with the results of stat() when mmap() is
not being used.


Index: assemble.pl
===
RCS file: /cvs/public/parrot/assemble.pl,v
retrieving revision 1.66
diff -u -r1.66 assemble.pl
--- assemble.pl 10 Jun 2002 05:40:06 -  1.66
+++ assemble.pl 10 Jun 2002 23:24:45 -
 -813,6 +813,7 
   close FILE;
 }
 else {
+  binmode STDOUT;
   print $bytecode;
 }
 
Index: embed.c
===
RCS file: /cvs/public/parrot/embed.c,v
retrieving revision 1.26
diff -u -r1.26 embed.c
--- embed.c 8 Jun 2002 03:38:45 -   1.26
+++ embed.c 10 Jun 2002 23:24:45 -
 -110,6 +110,7 
 INTVAL read_result;
 
 program_code = (char *)malloc(program_size + 1024);
+program_size = 0;
 if (NULL == program_code) {
 fprintf(stderr,
 Parrot VM: Could not allocate buffer to read packfile from 
PIO.\n);



Re: Stack

2002-06-09 Thread Jason Gloudon


This seems like a good time to send in this patch:

It allocates the stack content memory using a buffer. This makes the stack
chunks and the memory used to hold stack contents visible to the garbage
collector.  One can incrementally add to this to support copy-on-write
semantics for the chunk contents, which I understand is going to be useful in
taking continuations. This could be done by making the stack chunks themselves
buffer headers or perhaps PMCs, which would be cool for introspection.


Index: debug.c
===
RCS file: /cvs/public/parrot/debug.c,v
retrieving revision 1.6
diff -u -p -r1.6 debug.c
--- debug.c 4 Jun 2002 14:44:52 -   1.6
+++ debug.c 6 Jun 2002 14:37:25 -
 -1204,7 +1204,7  PDB_print_user_stack(struct Parrot_Inter
 
 valid_chunk(chunk, command, depth, STACK_CHUNK_DEPTH, i);
 
-entry = chunk-entry[depth];
+entry = (Stack_entry *)(chunk-buffer-bufstart) + depth;
 
 switch (entry-entry_type) {
 case STACK_ENTRY_INT:
Index: resources.c
===
RCS file: /cvs/public/parrot/resources.c,v
retrieving revision 1.61
diff -u -p -r1.61 resources.c
--- resources.c 4 Jun 2002 19:36:58 -   1.61
+++ resources.c 6 Jun 2002 14:37:27 -
 -302,6 +302,7  trace_active_PMCs(struct Parrot_Interp *
 unsigned int i, j, chunks_traced;
 Stack_chunk *cur_stack, *start_stack;
 struct PRegChunk *cur_chunk;
+Stack_entry *entry;
 
 /* We have to start somewhere, and the global stash is a good
  * place */
 -336,10 +337,15  trace_active_PMCs(struct Parrot_Interp *
 chunks_traced = 0;
 /* The general stack's circular, so we need to be careful */
 while (cur_stack  ((start_stack != cur_stack) || (chunks_traced == 0))) {
-for (i = 0; i  cur_stack-used; i++) {
-if (STACK_ENTRY_PMC == cur_stack-entry[i].entry_type 
-cur_stack-entry[i].entry.pmc_val) {
-last = mark_used(cur_stack-entry[i].entry.pmc_val, last);
+if(cur_stack-buffer){
+buffer_lives(cur_stack-buffer);
+
+entry = (Stack_entry *)(cur_stack-buffer-bufstart);
+for (i = 0; i  cur_stack-used; i++) {
+if (STACK_ENTRY_PMC == entry[i].entry_type 
+entry[i].entry.pmc_val) {
+last = mark_used(entry[i].entry.pmc_val, last);
+}
 }
 }
 
 -398,6 +404,7  trace_active_buffers(struct Parrot_Inter
 UINTVAL i, j, chunks_traced;
 Stack_chunk *cur_stack, *start_stack;
 struct SRegChunk *cur_chunk;
+Stack_entry *entry;
 
 /* First mark the current set. We assume that all pointers in S
  * registers are pointing to valid buffers. This is not a good
 -426,10 +433,14  trace_active_buffers(struct Parrot_Inter
 chunks_traced = 0;
 /* The general stack's circular, so we need to be careful */
 while (cur_stack  ((start_stack != cur_stack) || (chunks_traced == 0))) {
-for (i = 0; i  cur_stack-used; i++) {
-if (STACK_ENTRY_STRING == cur_stack-entry[i].entry_type 
-cur_stack-entry[i].entry.string_val) {
-buffer_lives((Buffer *)cur_stack-entry[i].entry.string_val);
+if(cur_stack-buffer){ 
+buffer_lives(cur_stack-buffer);
+entry = (Stack_entry *)(cur_stack-buffer-bufstart);
+for (i = 0; i  cur_stack-used; i++) {
+if (STACK_ENTRY_STRING == entry[i].entry_type 
+entry[i].entry.string_val) {
+buffer_lives((Buffer *)entry[i].entry.string_val);
+}
 }
 }
 
Index: stacks.c
===
RCS file: /cvs/public/parrot/stacks.c,v
retrieving revision 1.30
diff -u -p -r1.30 stacks.c
--- stacks.c17 May 2002 21:38:20 -  1.30
+++ stacks.c6 Jun 2002 14:37:27 -
 -21,15 +21,22  new_stack(Interp *interpreter)
 {
 #ifdef TIDY
 int i;
+Stack_entry *entry;
 #endif
+
 Stack_chunk *stack = mem_allocate_aligned(sizeof(Stack_chunk));
 
 stack-used = 0;
 stack-next = stack;
 stack-prev = stack;
+stack-buffer = new_buffer_header(interpreter);
+Parrot_allocate(interpreter, stack-buffer,
+sizeof(Stack_entry) * STACK_CHUNK_DEPTH);
+
 #ifdef TIDY
+entry = (Stack_entry *)stack-buffer-bufstart;
 for (i = 0; i  STACK_CHUNK_DEPTH; i++)
-stack-entry[i].flags = NO_STACK_ENTRY_FLAGS;
+entry[i].flags = NO_STACK_ENTRY_FLAGS;
 #endif
 return stack;
 }
 -56,7 +63,7  Stack_entry *
 stack_entry(Interp *interpreter, Stack_chunk *stack_base, Intval depth)
 {
 Stack_chunk *chunk;
-Stack_entry *entry = NULL;
+Stack_entry *entry;
 size_t offset = (size_t)depth;
 
 /* For negative depths, look from the bottom of the stack up. */
 -68,7 +75,7  

Re: Near-term schedule

2002-06-08 Thread Jason Gloudon

On Fri, Jun 07, 2002 at 11:23:56PM -0400, Dan Sugalski wrote:

 2) A revamped stack system so we can support exceptions

What is the intent for stacks ?

-- 
Jason



Re: cvs.perl.org moved

2002-06-06 Thread Jason Gloudon

On Thu, Jun 06, 2002 at 12:04:03AM -0700, Ask Bjoern Hansen wrote:
 
 Robert Spier and I moved cvs.perl.org to a new server tonight.
 Everything should work as usual, except maybe a bit faster.  If
 anything is odd, not working as it used to, working better, not
 working at all, please send us mail at cvs at perl.org.

Has the CVSROOT changed ?

cvs checkout parrot

/home/perlcvs: no such repository
cvs checkout: authorization failed: server cvs.perl.org rejected access to 
/home/perlcvs for user anonymous

-- 
Jason



[PATCH] vtable PDD patch

2002-06-05 Thread Jason Gloudon


This clarifies some semantics of the get_string and substr vtables.

Index: docs/pdds/pdd02_vtables.pod
===
RCS file: /home/perlcvs/parrot/docs/pdds/pdd02_vtables.pod,v
retrieving revision 1.10
diff -r1.10 pdd02_vtables.pod
175c175,176
 encoding of the PMC's choice.
---
 encoding of the PMC's choice.  This string may be modified without modifying
 the PMC.
324,325c325,327
 Return a substring of the passed in PMC. Returns a substring, either
 as a PMC or a STRING.
---
 Return a substring of the passed in PMC. Returns a substring, either as a PMC
 or a STRING. When returning a STRING, the string may be modified without
 modifying the PMC.



Re: Some tasks for the interested

2002-06-01 Thread Jason Gloudon

On Thu, Apr 25, 2002 at 01:58:29PM -0400, Dan Sugalski wrote:

 1) We need to have a set of 'new stack frame' ops that close out the 
 current stack frames and start new ones. Should take an optional size 
 that presizes the stacks.

 3) The stack chunks need to be decoupled from the chunk headers, and 
 we need to implement COW for the stacks.
 
 4) The stack frames need to be GCable.

Which of these are still relevant ?

-- 
Jason



[PATCH] old packfile patch

2002-05-20 Thread Jason Gloudon


The disassembler isn't happy at the moment, this patch appears to fix 
the problem it has with the bytecode header.

Index: lib/Parrot/PackFile.pm
===
RCS file: /home/perlcvs/parrot/lib/Parrot/PackFile.pm,v
retrieving revision 1.15
diff -p -r1.15 PackFile.pm
*** lib/Parrot/PackFile.pm  15 May 2002 04:33:29 -  1.15
--- lib/Parrot/PackFile.pm  20 May 2002 16:14:03 -
*** sub unpack
*** 187,206 
$self-{MINOR} = shift_byte($string);
$self-{FLAGS} = shift_byte($string);
$self-{FLOATTYPE} = shift_byte($string);
! 
!   # Unused fields 
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
! 
!   $string = substr($string, 8);
  
my $magic = shift_op($string);
  
--- 187,193 
$self-{MINOR} = shift_byte($string);
$self-{FLAGS} = shift_byte($string);
$self-{FLOATTYPE} = shift_byte($string);
!   $string = substr($string, 10);
  
my $magic = shift_op($string);
  
-- 
Jason


Index: lib/Parrot/PackFile.pm
===
RCS file: /home/perlcvs/parrot/lib/Parrot/PackFile.pm,v
retrieving revision 1.15
diff -p -r1.15 PackFile.pm
*** lib/Parrot/PackFile.pm  15 May 2002 04:33:29 -  1.15
--- lib/Parrot/PackFile.pm  20 May 2002 16:14:03 -
*** sub unpack
*** 187,206 
$self-{MINOR} = shift_byte($string);
$self-{FLAGS} = shift_byte($string);
$self-{FLOATTYPE} = shift_byte($string);
! 
!   # Unused fields 
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
!   shift_byte($string);
! 
!   $string = substr($string, 8);
  
my $magic = shift_op($string);
  
--- 187,193 
$self-{MINOR} = shift_byte($string);
$self-{FLAGS} = shift_byte($string);
$self-{FLOATTYPE} = shift_byte($string);
!   $string = substr($string, 10);
  
my $magic = shift_op($string);
  



[PATCH] new header buflen

2002-05-20 Thread Jason Gloudon


The buflen of a new header was not always set to 0, which would cause SIGSEGVs
when parrot_reallocate tries to copy a non-zero length buffer with a bufstart
of NULL. This would happen when buffers get recycled.

I don't know if new_pmc_header has the same problem, but it also does not
initialize the buffer length. 

Index: resources.c
===
RCS file: /home/perlcvs/parrot/resources.c,v
retrieving revision 1.56
diff -c -r1.56 resources.c
*** resources.c 20 May 2002 16:16:01 -  1.56
--- resources.c 20 May 2002 23:06:31 -
***
*** 279,284 
--- 279,286 
  return_me-flags = 0;
  /* Don't let it point to garbage memory */
  return_me-bufstart = NULL;
+ /* Use the right length */
+ return_me-buflen = 0;
  /* Return it */
  return return_me;
  }

-- 
Jason


Index: resources.c
===
RCS file: /home/perlcvs/parrot/resources.c,v
retrieving revision 1.56
diff -c -r1.56 resources.c
*** resources.c 20 May 2002 16:16:01 -  1.56
--- resources.c 20 May 2002 23:06:31 -
***
*** 279,284 
--- 279,286 
  return_me-flags = 0;
  /* Don't let it point to garbage memory */
  return_me-bufstart = NULL;
+ /* Use the right length */
+ return_me-buflen = 0;
  /* Return it */
  return return_me;
  }



no money down idea for computed goto

2002-04-22 Thread Jason Gloudon


I don't have the time right now to do this myself, so here is a simple
idea to evaluate.

Currently, the computed goto decode and dispatch is essentially:

goto *ops_addr[ *cur_opcode ];

Now a big part of the gain of the prederef runops core comes from decoding each
op once instead of each time it is executed.  The prederef core does this by
creating an array shadowing the byte code which stores pointers to the op
functions for the decoded ops.

One could modify the computed goto runops analagously, by creating a parallel
array that stores the decoded label address of each op. Suppose the parallel
array is pointed to by decoded_ops, then op dispatch would then look like :

goto *decoded_ops[ cur_opcode - start_of_bytecode ];

The C compiler might be able to optimize away the explicit subtraction. If not
one can do the equivalent pointer math, but I won't try to write that here.

In the ideal case, where sizeof(opcode_t) == sizeof(void *), one could possibly
cheat like the jit compiler does and overwrite the original bytecode instead of
using a parallel array, but that may not be good.

-- 
Jason



Re: [PATCH] intconst parameter type

2002-04-18 Thread Jason Gloudon

On Thu, Apr 18, 2002 at 03:24:58PM +1000, Andrew J Bromage wrote:

   - Nobody is likely to use it any time soon.

People say that about my brain, but they haven't tried to take it from me
yet :)

Having registers provide the destination for some branches makes it possible to
generate code that eliminates most of the comparisions needed to implement C
style case/switch statements, so this is not a useless feature.

   - It is in general impossible for an optimizer to determine
 where the branch targets are if you allow registers as
 branch targets.  Even when it's possible, it's too hard.

That's why a compiler would put information about possible targets of branches
somewhere available to the optimizer.

   - Eliminating it speeds up life.pasm by about 5-10% according
 to my highly unscientific benchmark.

What about mops.pasm ? The speedup (if real) is probably just a side-effect of
deleting the code for those ops.

-- 
Jason



Re: PMCs requiring a 'set' dest register?

2002-04-02 Thread Jason Gloudon

On Tue, Apr 02, 2002 at 01:33:59AM -0500, Michel J Lambert wrote:

 If instead, registers are aliased onto traditional memory variables, such
 that a PMC pointed to by a register is *also* pointed to by a stash
 somewhere, then it's a bit harder.

I believe this is the desired scheme.

Blocking and unblocking dead object detection is probably the simplest way to
go.  The GC PDD describes the functions to do this, but they aren't
implemented.

http://dev.perl.org/perl8/pdd/pdd09.pod

Making the PMC registers PMC** will make for a lot of overhead even where it
is not necessary.

-- 
Jason



Re: Prospective jit patch

2002-04-01 Thread Jason Gloudon

On Mon, Apr 01, 2002 at 01:33:02AM -0300, Daniel Grunblatt wrote:

 Did you continue working on this or can I take this patch to continue?

I haven't made any changes since then so you can work off this patch.

-- 
Jason



Re: Computed-goto Patch

2002-03-27 Thread Jason Gloudon

On Wed, Mar 27, 2002 at 02:55:59AM -0500, Michel J Lambert wrote:
 Attached is a patch to implement computed-goto on gcc, taken from the
 original post by Daniel Grunblatt:
 http:[EMAIL PROTECTED]/msg06255.html

The patch is slightly broken, core_cg_ops.h in interpreter.c versus
core_ops_cg.h everywhere else.

It does take a while to build the computed goto ops file. I still have to test
it myself.

I can't tell what has actually been changed in pbc2c.pl, due to the large
amount of indentation fixup included in the patch. Can you say what you changed
there ?

The existing pbc2c implementation worked without computed goto is this still
the case ?  The CGoto.pm OpTrans is currently being used by the bytecode to C
compiler.  The existing CGoto.pm should be cloned with a more appropriate name
before it gets patched to work with a computed goto core.

-- 
Jason



Prospective jit patch

2002-03-24 Thread Jason Gloudon


This is a not-yet-suitable for applying patch that removes the dependency on an
external assembler and disassembler for Just-In-Time compiler support.  All
assembly is done at run-time via macros. This is sufficient to allow some
flexibility in instruction selection at run-time, but a lot more work would be
needed to enable real optimizations like register allocation etc.  I would like
to know if anyone would be interested in helping make this worthy of applying,
and if it works/does not work for anyone.

In its current form, it should work on :

1) Any x86 OS, with the notable inclusion of windows OSes using visual studio
tools.

2) Sparc systems using 32-bit Intvals (64 bit Intvals still do not work).
Systems where perl identifies the cpu as 'sun4' work without changes. Systems
where the cpu is identified as 'sparc' can get by with a symlink from jit/sparc
to jit/sun4.

I haven't touched the alpha jit, Daniel ?

-- 
Jason



-- 
Jason


diff --exclude=CVS -urN parrot/Configure.pl parrot-jit/Configure.pl
--- parrot/Configure.pl Tue Mar 19 17:53:57 2002
+++ parrot-jit/Configure.pl Sun Mar 24 18:46:57 2002
 -151,12 +151,22 
 ($osname, $cpuarch) = ($cpuarch, );
 }
 
+if($cpuarch =~ /MSWin32/){
+$cpuarch = 'i386';
+$osname = 'MSWin32';
+}
+if(($osname =~ /cygwin/i) || ($cpuarch =~ /cygwin/i)){
+$cpuarch = 'i386';
+}
+
+$cpuarch  =~ s/i[456]86/i386/i;
+$cpuarch  =~ s/sparc/sun4/i;
 $jitarchname  =  $cpuarch-$osname;
-$jitarchname =~ s/i[456]86/i386/i;
 $jitarchname  =~ s/-(net|free|open)bsd$/-bsd/i;
 $jitcapable   = 0;
 
-if (-e lib/Parrot/Jit/$jitarchname.pm) {
+
+if (-e jit/$cpuarch) {
 $jitcapable = 1;
 }
 
 -276,7 +286,7 
 $c{cc_hasjit} =  -DHAS_JIT -D . uc $jitcpuarch;
 $c{jit_h} = \$(INC)/jit.h;
 $c{jit_struct_h} = \$(INC)/jit_struct.h;
-$c{jit_o} = jit\$(O);
+$c{jit_o} = jit\$(O) jit_cpu\$(O);
 }
 
 #
diff --exclude=CVS -urN parrot/MANIFEST parrot-jit/MANIFEST
--- parrot/MANIFEST Sun Mar 24 16:10:49 2002
+++ parrot-jit/MANIFEST Sun Mar 24 18:29:00 2002
 -149,9 +149,13 
 jit/i386/core.jit
 jit/i386/lib.jit
 jit/i386/string.jit
+jit/i386/core.cjt
+jit/i386/jit_emit.h
 jit/sun4/core.jit
 jit/sun4/lib.jit
 jit/sun4/string.jit
+jit/sun4/core.cjt
+jit/sun4/jit_emit.h
 jit2h.pl
 key.c
 languages/Makefile.in
diff --exclude=CVS -urN parrot/MANIFEST.SKIP parrot-jit/MANIFEST.SKIP
--- parrot/MANIFEST.SKIPThu Mar 21 18:39:49 2002
+++ parrot-jit/MANIFEST.SKIPThu Mar 21 21:15:54 2002
 -14,12 +14,14 
 ^vtable\.ops$
 ^include/parrot/vtable\.h$
 ^include/parrot/jit_struct\.h$
+^include/parrot/jit_emit\.h$
 ^include/parrot/oplib/core_ops\.h$
 ^include/parrot/oplib/core_ops_prederef\.h$
 
 ^core_ops\.c$
 ^core_ops_prederef\.c$
 ^vtable_ops\.c$
+^jit_cpu.c
 
 ^lib/Parrot/Jit\.pm$
 ^lib/Parrot/PMC\.pm$
diff --exclude=CVS -urN parrot/Makefile.in parrot-jit/Makefile.in
--- parrot/Makefile.in  Thu Mar 21 18:47:22 2002
+++ parrot-jit/Makefile.in  Sun Mar 24 18:31:48 2002
 -44,7 +44,7 
 
 GEN_OPSFILES = vtable.ops
 
-GEN_HEADERS = $(INC)/vtable.h ${jit_struct_h} $(INC)/oplib/core_ops.h \
+GEN_HEADERS = $(INC)/vtable.h $(INC)/oplib/core_ops.h \
 $(INC)/oplib/core_ops_prederef.h
 
 GEN_SOURCES = core_ops.c core_ops_prederef.c vtable_ops.c
 -69,7 +69,7 
 $(INC)/interp_guts.h ${jit_h} $(INC)/rx.h $(INC)/rxstacks.h \
 $(INC)/embed.h $(INC)/warnings.h $(INC)/misc.h
 
-ALL_H_FILES = $(GENERAL_H_FILES) ${jit_struct_h}
+ALL_H_FILES = $(GENERAL_H_FILES)
 
 CLASS_O_FILES = classes/default$(O) classes/array$(O) \
 classes/perlint$(O) classes/perlstring$(O) classes/perlnum$(O) \
 -286,7 +286,9 
 
 pmc$(O): $(GENERAL_H_FILES)
 
-jit$(O): $(GENERAL_H_FILES) ${jit_struct_h}
+jit$(O): $(GENERAL_H_FILES)
+
+jit_cpu$(O): $(GENERAL_H_FILES) $(INC)/jit_emit.h
 
 key$(O): $(GENERAL_H_FILES)
 
 -365,8 +367,11 
 $(INC)/vtable.h: vtable.tbl vtable_h.pl
$(PERL) vtable_h.pl
 
-$(INC)/jit_struct.h: jit2h.pl lib/Parrot/OpLib/core.pm lib/Parrot/Jit.pm 
jit/${jitcpuarch}/core.jit jit/${jitcpuarch}/string.jit
-   $(PERL) jit2h.pl ${jitcpuarch}  $(INC)/jit_struct.h
+$(INC)/jit_emit.h: jit/${jitcpuarch}/jit_emit.h
+   $(PERL) -MFile::Copy=cp -e ${PQ}cp q|jit/${jitcpuarch}/jit_emit.h|, 
+q|$(INC)/jit_emit.h|${PQ}
+
+jit_cpu.c: lib/Parrot/OpLib/core.pm $(INC)/jit_emit.h jit/${jitcpuarch}/core.cjt
+   jit2h.pl ${jitcpuarch} jit_cpu.c
 
 docs: docs/.dummy
 
diff --exclude=CVS -urN parrot/include/parrot/exceptions.h 
parrot-jit/include/parrot/exceptions.h
--- parrot/include/parrot/exceptions.h  Sun Mar  3 22:17:21 2002
+++ parrot-jit/include/parrot/exceptions.h  Sun Mar 10 11:28:51 2002
 -47,6 +47,7 
 #define ALLOCATION_ERROR 1
 #define INTERNAL_PANIC 1
 #define OUT_OF_BOUNDS 1
+#define JIT_ERROR 1
 
 #endif
 
diff --exclude=CVS -urN parrot/include/parrot/jit.h parrot-jit/include/parrot/jit.h
--- parrot/include/parrot/jit.h Sun Mar  3 22:17:21 2002
+++ parrot-jit/include/parrot/jit.h Wed Mar 

Re: Problems with strings on the stack (small, concise example)

2002-03-22 Thread Jason Gloudon

On Fri, Mar 22, 2002 at 10:06:44AM -0500, Joshua Nye wrote:

 Not sure if this is intended though. I though each type (INT,NUM,PMC,STR)
 has it's own stack?

This is the expected behaviour. There are only two stacks visible at the parrot
assembly level. The scratch (or data) stack, and the control flow stack.  The
push, pop, and save ops work on the scratch stack, which as you have found,
does type-checking.

-- 
Jason



[PATCH] Fix calculation of byte code end

2002-02-13 Thread Jason Gloudon

The type changes in struct Packfile break the pointer math used in a few places
to calculate the address of the end of the loaded byte code. This causes
segfaults in build_asm in jit.c when using -j. It also breaks the bounds
checking on opcode address in runops_slow_core.

The patch adds the necessary cast to correct the code_end calculations.

-- 
Jason


Index: interpreter.c
===
RCS file: /home/perlcvs/parrot/interpreter.c,v
retrieving revision 1.68
diff -u -r1.68 interpreter.c
--- interpreter.c   5 Feb 2002 09:20:07 -   1.68
+++ interpreter.c   14 Feb 2002 03:24:44 -
@@ -68,7 +68,7 @@
 
 code_start = (opcode_t *)interpreter-code-byte_code;
 code_size  = interpreter-code-byte_code_size;
-code_end   = (opcode_t *)(interpreter-code-byte_code + code_size);
+code_end   = (opcode_t *)((char *)interpreter-code-byte_code + code_size);
 
 pc = core(interpreter, pc);
 
@@ -294,7 +294,7 @@
 
 code_start = (opcode_t *)interpreter-code-byte_code;
 code_size  = interpreter-code-byte_code_size;
-code_end   = (opcode_t *)(interpreter-code-byte_code + code_size);
+code_end   = (opcode_t *)((char *)interpreter-code-byte_code + code_size);
 
 jit_code = build_asm(interpreter, pc, code_start, code_end);
 #ifdef ALPHA
@@ -345,7 +345,7 @@
 
 code_start = (opcode_t *)interpreter-code-byte_code;
 code_size  = interpreter-code-byte_code_size;
-code_end   = (opcode_t *)(interpreter-code-byte_code + code_size);
+code_end   = (opcode_t *)((char *)interpreter-code-byte_code + code_size);
 
 code_start_prederef = pc_prederef;
 
Index: runops_cores.c
===
RCS file: /home/perlcvs/parrot/runops_cores.c,v
retrieving revision 1.11
diff -u -r1.11 runops_cores.c
--- runops_cores.c  22 Jan 2002 16:57:25 -  1.11
+++ runops_cores.c  14 Feb 2002 03:24:44 -
@@ -49,7 +49,7 @@
 
 code_start = (opcode_t *)interpreter-code-byte_code;
 code_size  = interpreter-code-byte_code_size;
-code_end   = (opcode_t *)(interpreter-code-byte_code + code_size);
+code_end   = (opcode_t *)((char *)interpreter-code-byte_code + code_size);
 
 if (interpreter-flags  PARROT_TRACE_FLAG) {
   trace_op(interpreter, code_start, code_end, pc);



Re: Perl6/Parrot status

2002-02-07 Thread Jason Gloudon

On Thu, Feb 07, 2002 at 01:38:42PM -0500, Michael G Schwern wrote:
 On Thu, Feb 07, 2002 at 07:12:18PM +0100, Sebastian Bergmann wrote:
Is this for real? I can't really believe this...
 
 Yes, I have it on good authority from the Easter Bunny.

In case everyone is not familiar with the easter bunny concept, this is a joke.

-- 
Jason



Re: Enternative?

2002-02-06 Thread Jason Gloudon

On Wed, Feb 06, 2002 at 12:09:22PM -0800, Steve Fink wrote:

 but I think that's because re_backtrack returns a void*. run_native()
 returns an opcode_t*, which is fine for the regular core_ops.c but
 gets returned as void** in core_ops_prederef.c. I think the computed
 goto path does a third thing, but I don't know how to invoke that.

goto ADDRESS() for prederef needs the same type of calculation that expr_pop
uses to convert opcode_t * values to the corresponding void **.

CGoto is used by pbc2c.pl. There isn't actually a computed goto runops at the
moment. Enternative is only used by the C programs pbc2c generates. This code
doesn't enable prederef (no option parsing), so enternative in prederef mode
isn't possible yet.

-- 
Jason



Re: [PATCH] jit for solaris [APPLIED]

2002-02-05 Thread Jason Gloudon

On Tue, Feb 05, 2002 at 02:10:15PM -0500, Andy Dougherty wrote:
 I've applied the following little patch which is required for those using
 Sun's assembler.  It helps the make process a bit further along.
 I still get core dumps for test_parrot -j.  It might have to do
 with my 64-bit perl, but I don't have time to investigate.  This patch at
 least let the compilation get further.

Yes, the jit stuff on sparc will only work for a build environemnt with 32 bit
integers and pointers.

-- 
Jason



Re: Jit on Solaris: using dis instead of objdump?

2002-01-31 Thread Jason Gloudon


This should make solaris 'as' happy. There will be an assembler warning, but
it's harmless.


diff -r1.3 sun4Generic.pm
78c78
 return Parrot::Jit-Assemble(ld [\%o0], \%o0\njmpl \%o0, \%g0\n);
---
 return Parrot::Jit-Assemble(ld [\%o0], \%o0\njmpl \%o0, \%g0\nnop\n);
151c151
 .typemain,@function
---
 .typemain,#function


-- 
Jason



Re: Jit on Solaris: using dis instead of objdump?

2002-01-30 Thread Jason Gloudon

On Wed, Jan 30, 2002 at 03:27:18PM -0500, Andy Dougherty wrote:
 On Solaris, it looks like JIT will now be enabled if the user has also
 installed GNU objdump.  However, there is (often) already a disassembler
 in /usr/ccs/bin/dis.  It's output is similar, but not identical to,
 objdump.  Is anyone with a Solaris system familiar enough with jit
 internals to have a go at adapting it to use dis instead of GNU objdump?

The difference was pretty minimal. It should work with 'dis'.

-- 
Jason



Re: parrot and stdin

2002-01-15 Thread Jason Gloudon

On Tue, Jan 15, 2002 at 02:58:53PM -0500, Michel Lambert wrote:
 Some more minor fixes and cleanup to parrot's ability to read in pbc data
 off of STDIN. Note that using an MSVC-compiled parrot doesn't work in
 cygwin...it reads in less data than it should, both before and after this
 patch. Only a gcc/cygwin-compiled parrot works in cygwin. I don't think this
 is a bug, tho.

perhaps stdin needs to be in binmode.


-- 
Jason



[PATCH] pbc2c.pl control flow fix

2002-01-14 Thread Jason Gloudon


Pointer arithmetic not quite right in the generated code.  Also patches
pbc2c.pl to work with rx.ops.

-- 
Jason


Index: pbc2c.pl
===
RCS file: /home/perlcvs/parrot/pbc2c.pl,v
retrieving revision 1.12
diff -r1.12 pbc2c.pl
30c30
 my $ops = new Parrot::OpsFile ('core.ops', 'vtable.ops');
---
 my $ops = new Parrot::OpsFile ('core.ops', 'rx.ops', 'vtable.ops');
92c92
 print $ops-preamble;
---
 print $ops-preamble($trans);
238c238
 switch((ptrcast_t)cur_opcode - (ptrcast_t)start_code) {
---
 switch(((ptrcast_t)cur_opcode - (ptrcast_t)start_code) / sizeof(opcode_t)) {



[PATCH] bsr with prederef [Was Re: [PATCH] jumps with pbc2c.pl]

2002-01-12 Thread Jason Gloudon


Here is a patch that fixes prederef with respect to bsr.

-- 
Jason


Index: interpreter.c
===
RCS file: /home/perlcvs/parrot/interpreter.c,v
retrieving revision 1.57
diff -u -r1.57 interpreter.c
--- interpreter.c   12 Jan 2002 15:33:08 -  1.57
+++ interpreter.c   13 Jan 2002 01:00:05 -
@@ -257,7 +257,7 @@
 break;
 
   case PARROT_ARG_IC:
-pc_prederef[i] = (void *)pc[i];
+pc_prederef[i] = (void *)pc[i];
 break;
 
   case PARROT_ARG_NC:
Index: Parrot/OpTrans/CPrederef.pm
===
RCS file: /home/perlcvs/parrot/Parrot/OpTrans/CPrederef.pm,v
retrieving revision 1.3
diff -u -r1.3 CPrederef.pm
--- Parrot/OpTrans/CPrederef.pm 1 Jan 2002 03:43:12 -   1.3
+++ Parrot/OpTrans/CPrederef.pm 13 Jan 2002 01:00:05 -
@@ -66,7 +66,7 @@
 sub goto_pop
 {
   my ($self) = @_;
-  return return pop_dest(interpreter);
+  return return (((opcode_t *)pop_dest(interpreter) - (opcode_t 
+*)interpreter-code-byte_code) + interpreter-prederef_code);
 }
 
 
@@ -86,7 +86,7 @@
 'p'  = (*(PMC **)cur_opcode[%ld]),
 's'  = (*(STRING **)cur_opcode[%ld]),
 
-'ic' = (*(INTVAL *)cur_opcode[%ld]),
+'ic' = (*(INTVAL *)cur_opcode[%ld]),
 'nc' = (*(FLOATVAL *)cur_opcode[%ld]),
 'pc' = %ld /* ERROR: Don't know how to handle PMC constants yet! */,
 'sc' = (*(STRING **)cur_opcode[%ld]),



[PATCH] jumps with pbc2c.pl

2002-01-10 Thread Jason Gloudon


Here is a patch that makes pbc2c generated code work with the bsr opcode.  It
creates a new opcode 'enternative', and uses this to support a mixed model of
interpretation and execution of compiled C code.

Initially, an interpreter is created and started in order to execute a modified
copy of the bytecode. At certain known branch target addresses, the original
opcode is replaced by an 'enternative' opcode, which switches to execution of
the compiled C code. If a branch to a target address not identified by pbc2c
occurs, the compiled C code returns control to the interpreter which executes
the original bytecode until another 'enternative' opcode is encountered.

I'm also including a version of mops.pasm that includes a bsr opcode to test
the changes to pbc2c.

-- 
Jason


Index: core.ops
===
RCS file: /home/perlcvs/parrot/core.ops,v
retrieving revision 1.72
diff -u -r1.72 core.ops
--- core.ops9 Jan 2002 17:24:11 -   1.72
+++ core.ops10 Jan 2002 22:56:19 -
@@ -2475,6 +2475,10 @@
   goto NEXT();
 }
 
+op enternative() {
+  goto ADDRESS(run_native(interpreter, CUR_OPCODE, (opcode_t 
+*)interpreter-code-byte_code));
+}
+
 
 
 =item Bnew(out PMC, in INT)
Index: pbc2c.pl
===
RCS file: /home/perlcvs/parrot/pbc2c.pl,v
retrieving revision 1.11
diff -u -r1.11 pbc2c.pl
--- pbc2c.pl3 Jan 2002 19:41:46 -   1.11
+++ pbc2c.pl10 Jan 2002 22:56:19 -
@@ -18,6 +18,7 @@
 use Parrot::PackFile::ConstTable;
 use Parrot::OpsFile;
 use Parrot::OpTrans::CGoto;
+use Parrot::OpLib::core;
 
 my $trans = Parrot::OpTrans::CGoto-new;
 
@@ -67,88 +68,46 @@
 # compile_byte_code()
 #
 
-my $pc;
-my $new_pc = 1;
 my @args = ();
 
 sub compile_byte_code {
-my ($pf) = @_;
-
-my $nconst = $pf-const_table-const_count;
+my ($pf, $file_name) = @_;
+my ($byte_code);
+my $pc;
+my $new_pc = 0;
+my $offset=0;
+my $op_code;
+my $op;
+my %leaders;
+my @pc_list;
+my @blocks;
+my %opcodes;
 
 print END_C;
 #include parrot/parrot.h
 #include parrot/string.h
 END_C
 
+print $trans-defines;
 print $ops-preamble;
 
-print END_C;
-
-int
-main(int argc, char **argv) {
-inti;
-struct Parrot_Interp * interpreter;
-struct PackFile_Constant * c;
-struct PackFile *  pf;
-
-init_world();
-  
-interpreter = make_interpreter(0);
-pf  = PackFile_new();
-
-interpreter-code = pf;
-
-END_C
-
-for(my $i = 0; $i  $nconst; $i++) {
-  my $const = $pf-const_table-constant($i);
-  my $value = $const-value;
-
-  if  ($const-type eq Parrot::PackFile::Constant::type_code('PFC_INTEGER')) 
{ # TODO: Don't hardocde these codes.
-print END_C;
-c = PackFile_Constant_new_integer($value);
-END_C
-  } elsif ($const-type eq Parrot::PackFile::Constant::type_code('PFC_NUMBER')) { 
# TODO: Don't hardocde these codes.
-print END_C;
-c = PackFile_Constant_new_number($value);
-END_C
-  } elsif ($const-type eq Parrot::PackFile::Constant::type_code('PFC_STRING')) { 
# TODO: Don't hardocde these codes.
-my $type = $value-type;
-my $encoding = $value-encoding;
-my $size = $value-size;
-my $flags= $value-flags;
-my $data = Dumper($value-data);
-
-$data = '' . $data . '' unless $data =~ m/^/;
-
-print END_C;
-c = PackFile_Constant_new_string(interpreter, string_make(interpreter,
- $data, $size, $encoding, $flags, $type));
-END_C
-  } else {
-die;
-  }
-
-  print END_C;
-PackFile_ConstTable_push_constant(pf-const_table, c);
-
-END_C
-}
-
-my $cursor = 0;
 my $length = length($pf-byte_code);
 
-my $offset=0;
-
-my $op_code;
-my $op;
+# First instruction in bytecode must be the leader of a block
+$leaders{$new_pc} = 1;
 
+# This loop tries to identify instructions that may be the target
+# of control flow changing opcodes including the possible targets of ret
+# opcodes
 while ($offset + sizeof('op') = $length) {
+   my ($src, $is_branch);
+
 $pc   = $new_pc;
$op_code  = unpack x$offset l, $pf-byte_code;
 $op   = $ops-op($op_code) || die Can't find an op for opcode 
$op_code\n;
$offset  += sizeof('op');
+   push @pc_list, $pc;
+   $opcodes{$pc}-{op} = $op;
 $new_pc   = $pc + $op-size;
 
 @args = ();
@@ -160,24 +119,154 @@
 $offset += sizeof('op');
 push @args, $arg;
 }
+   push @{$opcodes{$pc}-{args}}, @args;
+
+$src = $op-full_body();
+   
+   # The regexes here correspond to the rewriting rules for the various
+   # forms of goto recognized by Parrot/OpsFile.pm and Parrot/Op.pm
+
+   # absolute address goto 
+   while($src =~ 

[PATCH] PerlUndef PMC methods

2002-01-04 Thread Jason Gloudon


This makes PerlUndef somewhat functional by adding logical,
arithmetic, and repeat methods.

Index: global_setup.c
===
RCS file: /home/perlcvs/parrot/global_setup.c,v
retrieving revision 1.12
diff -u -r1.12 global_setup.c
--- global_setup.c  1 Jan 2002 03:46:40 -   1.12
+++ global_setup.c  4 Jan 2002 18:59:12 -
@@ -25,6 +25,7 @@
 string_init(); /* Set up the string subsystem */
 
 /* Call base vtable class constructor methods! */
+Parrot_PerlUndef_class_init();
 Parrot_PerlInt_class_init();
 Parrot_PerlNum_class_init();
 Parrot_PerlString_class_init();
Index: classes/perlundef.pmc
===
RCS file: /home/perlcvs/parrot/classes/perlundef.pmc,v
retrieving revision 1.2
diff -u -r1.2 perlundef.pmc
--- classes/perlundef.pmc   18 Dec 2001 07:05:00 -  1.2
+++ classes/perlundef.pmc   4 Jan 2002 18:59:12 -
@@ -59,7 +59,7 @@
}
 
STRING* get_string () {
-  return NULL;
+  return string_make(INTERP,NULL,0,NULL,0,NULL);
}
 
STRING* get_string_index (INTVAL index) {
@@ -154,75 +154,139 @@
}
 
void add (PMC * value,  PMC* dest) {
+if(value-vtable == Parrot_base_vtables[enum_class_PerlUndef]) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
+   }
+else if(value-vtable == Parrot_base_vtables[enum_class_PerlInt]) {
+   dest-vtable-set_integer(INTERP, dest, value);
+   }
+   else {
+   dest-vtable-set_number(INTERP, dest, value);
+   }
}
 
void add_int (INTVAL value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, value);
}
 
void add_bigint (BIGINT value,  PMC* dest) {
}
 
void add_float (FLOATVAL value,  PMC* dest) {
+   dest-vtable-set_number_native(INTERP, dest, value);
}
 
void add_bigfloat (BIGFLOAT value,  PMC* dest) {
}
 
void add_same (PMC * value,  PMC* dest) {
+  dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void subtract (PMC * value,  PMC* dest) {
+if(value-vtable == Parrot_base_vtables[enum_class_PerlUndef]) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
+   }
+else if(value-vtable == Parrot_base_vtables[enum_class_PerlInt]) {
+   dest-vtable-set_integer_native(INTERP, dest,
+   -value-vtable-get_integer(INTERP, value));
+   }
+   else {
+   dest-vtable-set_number_native(INTERP, dest,
+   -value-vtable-get_number(INTERP, value));
+   }
}
 
void subtract_int (INTVAL value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, -value);
}
 
void subtract_bigint (BIGINT value,  PMC* dest) {
}
 
void subtract_float (FLOATVAL value,  PMC* dest) {
+   dest-vtable-set_number_native(INTERP, dest, -value);
}
 
void subtract_bigfloat (BIGFLOAT value,  PMC* dest) {
}
 
void subtract_same (PMC * value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void multiply (PMC * value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void multiply_int (INTVAL value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void multiply_bigint (BIGINT value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void multiply_float (FLOATVAL value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void multiply_bigfloat (BIGFLOAT value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void multiply_same (PMC * value,  PMC* dest) {
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void divide (PMC * value,  PMC* dest) {
+   if(value-vtable == Parrot_base_vtables[enum_class_PerlUndef]) {
+   fprintf(stderr, division by zero!\n);
+   exit(1);
+   }
+   else if(value-vtable == Parrot_base_vtables[enum_class_PerlInt]) {
+   if(value-vtable-get_integer(INTERP, value) == 0) {
+   fprintf(stderr, division by zero!\n);
+   exit(1);
+   }
+   }
+   else if(value-vtable-get_number(INTERP, value) == 0) {
+   fprintf(stderr, division by zero!\n);
+   exit(1);
+   }
+
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void divide_int (INTVAL value,  PMC* dest) {
+   if(value == 0) {
+   fprintf(stderr, division by zero!\n);
+   exit(1);
+   }
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void divide_bigint (BIGINT value,  PMC* dest) {
+   /* need test for value == 0 */
+   dest-vtable-set_integer_native(INTERP, dest, 0);
}
 
void divide_float (FLOATVAL value,  PMC* dest) {
+   if(value == 0) {
+   fprintf(stderr, division 

Re: [PATCH] PerlUndef PMC methods

2002-01-04 Thread Jason Gloudon

On Fri, Jan 04, 2002 at 03:14:05PM -0500, Dan Sugalski wrote:

 Adding undef to undef? Why bother? :)
 
 Who needs to initialize variables anyway? :)
 
 We need to add in some warning code, I think. I'll stub out an interface.

Exceptions of some kind would be nice too :)

-- 
Jason



[PATCH] broken/missing PMC logical operations

2002-01-03 Thread Jason Gloudon


The PerlInt logical-or is using get_integer instead of get_bool for logical
operations. This patch corrects that.

Perlnum and perlstring have working get_bool's, so the default logical_or and
logical_and should be sufficient. The empty methods are pointed to the default
logical_or.

Index: classes/perlint.pmc
===
RCS file: /home/perlcvs/parrot/classes/perlint.pmc,v
retrieving revision 1.10
diff -u -r1.10 perlint.pmc
--- classes/perlint.pmc 27 Dec 2001 18:32:22 -  1.10
+++ classes/perlint.pmc 3 Jan 2002 14:14:03 -
@@ -486,14 +486,14 @@
 /* No set_bool :( */
 dest-vtable-set_integer_native(INTERP, dest,
 SELF-cache.int_val || 
-value-vtable-get_integer(INTERP, value)
+value-vtable-get_bool(INTERP, value)
 );
 }
 
 void logical_and (PMC* value, PMC* dest) {
 dest-vtable-set_integer_native(INTERP, dest,
 SELF-cache.int_val  
-value-vtable-get_integer(INTERP, value)
+value-vtable-get_bool(INTERP, value)
 );
 }
 
Index: classes/perlnum.pmc
===
RCS file: /home/perlcvs/parrot/classes/perlnum.pmc,v
retrieving revision 1.11
diff -u -r1.11 perlnum.pmc
--- classes/perlnum.pmc 27 Dec 2001 18:32:22 -  1.11
+++ classes/perlnum.pmc 3 Jan 2002 14:14:03 -
@@ -416,9 +416,7 @@
 
 void logical_and (PMC* value, PMC* dest) = default;
 
-void logical_not (PMC* value) {
-fprintf(stderr,logical_not not implemented\n);
-}
+void logical_not (PMC* value) = default;
 
 void match (PMC * value,REGEX* re) {
 fprintf(stderr,match not implemented\n);
Index: classes/perlstring.pmc
===
RCS file: /home/perlcvs/parrot/classes/perlstring.pmc,v
retrieving revision 1.11
diff -u -r1.11 perlstring.pmc
--- classes/perlstring.pmc  30 Dec 2001 12:04:56 -  1.11
+++ classes/perlstring.pmc  3 Jan 2002 14:14:04 -
@@ -419,14 +419,11 @@
 BOOLVAL is_equal (PMC* value) {
 }
 
-void logical_or (PMC* value, PMC* dest) {
-}
+void logical_or (PMC* value, PMC* dest) = default;
 
-void logical_and (PMC* value, PMC* dest) {
-}
+void logical_and (PMC* value, PMC* dest) = default;
 
-void logical_not (PMC* value) {
-}
+void logical_not (PMC* value) = default;
 
 void match (PMC * value,REGEX* re) {
 }
-- 
Jason



Re: .ops metadata [was: Re: JIT me some speed!]

2001-12-26 Thread Jason Gloudon

On Mon, Dec 24, 2001 at 02:11:15PM -0500, Gregor N. Purdy wrote:

 Or, do we really need to have the three-way in/out/inout tagset?
 
   inline op set(out i, in i|ic) {
 $1 = $2;
   }

Making the distinction between the three cases enables a number of
optimizations of native code based on analysing data flow.  'in' would be good
as an implicit default, as many PMC opcodes will not overwrite any PMC
registers.

An optimizing native code generator (whether static or JIT) will also need to
be aware of operands that may implicitly clobber parrot register values or
modify control flow, so that it knows when it musth spill updated parrot
register values in hardware registers back to their memory locations and when
it must reload hardware registers from main memory.

-- 
Jason



[PATCH] Thread Local Storage

2001-12-22 Thread Jason Gloudon


Here is a big diff that removes the interpreter argument from vtable function
calls, and creates macros for obtaining the pointer to an interpreter structure
for the current thread from thread local storage, assuming only that there is
one interpreter per thread. It works on unixish systems with pthread, on
mswin32, and systems with no threading (using a global variable). There is no
code here for creating threads etc., this is just intended to eliminate
gratuitous passing of the interpreter pointer to places it is not needed.
Currently it gives a small but consistent increase in the PMC mops figure of
about 5 percent.

I have separate platform thread files since there are a number of different
threading alternatives for some systems, though it might be more reasonable to
ifdef these in platform files.

I'd like to know if no one cares or does care and has suggestions.

-- 
Jason


diff -urN --exclude=CVS parrot/Configure.pl parrot-fixed/Configure.pl
--- parrot/Configure.pl Fri Dec 21 08:47:38 2001
+++ parrot-fixed/Configure.pl   Sat Dec 22 10:49:59 2001
@@ -116,6 +116,7 @@
make_set_make=  $Config{make_set_make},

platform = $^O,
+   threadplatform = $Config{'i_pthread'} ? 'pthread' : 'fakethreads',
 
 cpuarch  = $cpuarch,
 osname   = $osname,
@@ -162,6 +163,9 @@
 copy(platforms/generic.c, platform.c);
 }
 
+copy(platforms/$c{threadplatform}.h, include/parrot/plat_thread.h);
+copy(platforms/$c{threadplatform}.c, plat_thread.c);
+
 unless( $c{debugging} ) {
$c{ld_debug} = ' ';
$c{cc_debug} = ' ';
@@ -179,6 +183,9 @@
$c{$_}=$Config{$_};
$c{headers}.=defineifdef((/^i_(.*)$/));
 }
+
+$c{ccflags} .=  -D_REENTRANT if $Config{'i_pthread'};
+$c{libs} .=  -lpthread if $Config{'i_pthread'};
 
 print END;
 
diff -urN --exclude=CVS parrot/Makefile.in parrot-fixed/Makefile.in
--- parrot/Makefile.in  Fri Dec 21 14:32:43 2001
+++ parrot-fixed/Makefile.inFri Dec 21 18:42:56 2001
@@ -19,7 +19,7 @@
 chartype$(O) runops_cores$(O) trace$(O) pmc$(O) key$(O) \
 encodings/singlebyte$(O) encodings/utf8$(O) encodings/utf16$(O) \
 encodings/utf32$(O) chartypes/unicode$(O) chartypes/usascii$(O) resources$(O) \
-platform$(O) $(CLASS_O_FILES) jit$(O)
+platform$(O) $(CLASS_O_FILES) jit$(O) thread$(O) plat_thread$(O)
 
 #DO NOT ADD C COMPILER FLAGS HERE
 #Add them in Configure.pl--look for the
diff -urN --exclude=CVS parrot/Parrot/Vtable.pm parrot-fixed/Parrot/Vtable.pm
--- parrot/Parrot/Vtable.pm Sun Dec 16 07:45:00 2001
+++ parrot-fixed/Parrot/Vtable.pm   Fri Dec 21 19:03:10 2001
@@ -47,7 +47,7 @@
 }
 }
 $vtbl{$expand_name}{type} = $type;
-$vtbl{$expand_name}{proto} = $type (*$expand_name)(struct Parrot_Interp 
*interpreter, PMC* pmc;
+$vtbl{$expand_name}{proto} = $type (*$expand_name)(PMC* pmc;
 
 # Parse the function parameters
 for (@line) {
diff -urN --exclude=CVS parrot/classes/default.pmc parrot-fixed/classes/default.pmc
--- parrot/classes/default.pmc  Tue Dec 18 02:05:00 2001
+++ parrot-fixed/classes/default.pmcFri Dec 21 19:20:30 2001
@@ -224,16 +224,16 @@
}
 
void logical_or (PMC* value,  PMC* dest) {
-dest-vtable-set_integer_native(INTERP, dest, 
-SELF-vtable-get_bool(INTERP, SELF) ||
-value-vtable-get_bool(INTERP, value)
+dest-vtable-set_integer_native(dest, 
+SELF-vtable-get_bool(SELF) ||
+value-vtable-get_bool(value)
 );
}
 
void logical_and (PMC* value,  PMC* dest) {
-dest-vtable-set_integer_native(INTERP, dest, 
-SELF-vtable-get_bool(INTERP, SELF) 
-value-vtable-get_bool(INTERP, value)
+dest-vtable-set_integer_native(dest, 
+SELF-vtable-get_bool(SELF) 
+value-vtable-get_bool(value)
 );
}
 
diff -urN --exclude=CVS parrot/classes/perlarray.pmc parrot-fixed/classes/perlarray.pmc
--- parrot/classes/perlarray.pmcTue Dec 18 02:05:00 2001
+++ parrot-fixed/classes/perlarray.pmc  Fri Dec 21 19:20:30 2001
@@ -93,7 +93,7 @@
 }
 
 void set_integer (PMC* value) {
-   INTVAL size = value-vtable-get_integer(INTERP,value);
+   INTVAL size = value-vtable-get_integer(value);
KEY* key = SELF-cache.struct_val;
key_set_size(INTERP,key,size);
 }
@@ -186,15 +186,15 @@
 void add (PMC * value, PMC* dest) {
if(value-vtable == Parrot_base_vtables[enum_class_PerlInt]) {
dest-vtable = Parrot_base_vtables[enum_class_PerlInt];
-dest-vtable-set_integer_native(INTERP, dest, 
-   SELF-vtable-get_integer(INTERP, SELF) +
+dest-vtable-set_integer_native(dest, 
+   SELF-vtable-get_integer(SELF) +
 value-cache.int_val
 );
}
else if(value-vtable == Parrot_base_vtables[enum_class_PerlNum]) {
dest-vtable = 

[PATCH] Consistent use of INTERP in PMC code

2001-12-21 Thread Jason Gloudon

Just some cleanups for consistent access to the interpreter in PMC code.

Index: classes/perlstring.pmc
===
RCS file: /home/perlcvs/parrot/classes/perlstring.pmc,v
retrieving revision 1.7
diff -u -r1.7 perlstring.pmc
--- classes/perlstring.pmc  18 Dec 2001 07:05:00 -  1.7
+++ classes/perlstring.pmc  21 Dec 2001 01:13:18 -
@@ -47,7 +47,7 @@
 
 INTVAL get_integer () {
STRING* s = (STRING*) SELF-cache.struct_val;
-   return string_to_int(interpreter, s);
+   return string_to_int(INTERP, s);
 }
 
 INTVAL get_integer_index () {
@@ -55,7 +55,7 @@
 
 FLOATVAL get_number () {
STRING* s = (STRING*) SELF-cache.struct_val;
-   return string_to_num(interpreter, s);
+   return string_to_num(INTERP, s);
 }
 
 FLOATVAL get_number_index () {
Index: classes/perlundef.pmc
===
RCS file: /home/perlcvs/parrot/classes/perlundef.pmc,v
retrieving revision 1.2
diff -u -r1.2 perlundef.pmc
--- classes/perlundef.pmc   18 Dec 2001 07:05:00 -  1.2
+++ classes/perlundef.pmc   21 Dec 2001 01:13:18 -
@@ -80,17 +80,17 @@
 
void set_integer (PMC * value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlInt];
-  pmc-vtable-set_integer(interpreter, pmc, value);
+  pmc-vtable-set_integer(INTERP, pmc, value);
}
 
void set_integer_native (INTVAL value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlInt];
-  pmc-vtable-set_integer_native(interpreter, pmc, value);
+  pmc-vtable-set_integer_native(INTERP, pmc, value);
}
 
void set_integer_bigint (BIGINT value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlInt];
-  pmc-vtable-set_integer_bigint(interpreter, pmc, value);
+  pmc-vtable-set_integer_bigint(INTERP, pmc, value);
}
 
void set_integer_same (PMC * value) {
@@ -102,17 +102,17 @@
 
void set_number (PMC * value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlNum];
-  pmc-vtable-set_number(interpreter, pmc, value);
+  pmc-vtable-set_number(INTERP, pmc, value);
}
 
void set_number_native (FLOATVAL value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlNum];
-  pmc-vtable-set_number_native(interpreter, pmc, value);
+  pmc-vtable-set_number_native(INTERP, pmc, value);
}
 
void set_number_bigfloat (BIGFLOAT value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlNum];
-  pmc-vtable-set_number_bigfloat(interpreter, pmc, value);
+  pmc-vtable-set_number_bigfloat(INTERP, pmc, value);
}
 
void set_number_same (PMC * value) {
@@ -124,22 +124,22 @@
 
void set_string (PMC * value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlString];
-  pmc-vtable-set_string(interpreter, pmc, value);
+  pmc-vtable-set_string(INTERP, pmc, value);
}
 
void set_string_native (STRING * value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlString];
-  pmc-vtable-set_string_native(interpreter, pmc, value);
+  pmc-vtable-set_string_native(INTERP, pmc, value);
}
 
void set_string_unicode (STRING * value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlString];
-  pmc-vtable-set_string_unicode(interpreter, pmc, value);
+  pmc-vtable-set_string_unicode(INTERP, pmc, value);
}
 
void set_string_other (STRING * value) {
   pmc-vtable = Parrot_base_vtables[enum_class_PerlString];
-  pmc-vtable-set_string_other(interpreter, pmc, value);
+  pmc-vtable-set_string_other(INTERP, pmc, value);
}
 
void set_string_same (PMC * value) {



Re: JIT stuff stomps on Windows compilation

2001-12-21 Thread Jason Gloudon

On Thu, Dec 20, 2001 at 07:37:42AM -0500, Gregor N. Purdy wrote:

 I see Simon already changed 'cp ...' to 'perl -MFile::Copy...'. I just
 changed that to '$(PERL) -MFile::Copy...'.

NT 4.0's cmd shell does not like single quotes.

diff -r1.82 Makefile.in
22c22
 platform$(O) $(CLASS_O_FILES) jit$(O)
---
 platform$(O) $(CLASS_O_FILES) jit$(O) thread$(O)
64c64
   $(PERL) -MFile::Copy=cp -e 'cp q|Parrot/Jit/${jitarchname}.pm|, q|Parrot/Jit.pm|'
---
   $(PERL) -MFile::Copy=cp -e cp q|Parrot/Jit/${jitarchname}.pm|, q|Parrot/Jit.pm|

-- 
Jason



Re: [COMMIT] Something or other

2001-12-21 Thread Jason Gloudon

On Fri, Dec 21, 2001 at 02:59:52PM -0500, Gregor N. Purdy wrote:

   * Eventually getting rid of (all?) references to the implicit args
 of opfuncs (interpreter and cur_opcode). If they are implicit,
 let them stay hidden. Dan is thinking this may become easier
 when/if we can store interpreter as TLS or something.

I have the essentials of pthread and win32 local storage working, with a
fallback to a global interpreter variable for fakethreads. I would have sent
the diffs to the list but in light of the most recent commit I will have to do
some merging to have something that will apply against the current CVS.

The issue that comes up again of course is managing porting.  in the source.
Presently now I have a thread.h, a platform_thread.h, and a platform_thread.c,
where the latter two must be provided for each type of available thread API
(NOT a particular hardware/OS combinarion but each API). This means I do have a
win32 thread .c and .h, so in case something bizzare like pthreads works under
mingw32 or cygnus all one has to do is create appropriate hints.

If anyone has any strong preferences about organizing this this I'd like to
hear them.

-- 
Jason



Re: [COMMIT] miniperl has been somewhat busy...

2001-12-17 Thread Jason Gloudon

On Sun, Dec 16, 2001 at 11:56:46PM -0500, Jeff G wrote:

 so it generates code that has commands like 'set P0, P1', so that
 instruction needs to be added. The consensus on that thread seems to be
 that it should perform a deep copy of the PMC, at least to the pointer
 level. I'll hopefully be committing this tonight.

Can you clarify what you mean by deep copy at least to the pointer level ? 

set P0, P1
 
should invoke P0's assignment vtable function (does anyone know if it already
exists under a different name ?). For the existing PMC's the appropriate
assignment vtable calls P1's clone function with P0 as the destination.

Clone for Perlundef, Perlnum, and Perlint, are basically memcopy. Clone for
PerlString needs to make a copy of the underlying STRING.

PMCs that implement tied or strictly typed variables can provide more complex
assignment functions.

This allows tie'ing and type checking to take place within P0. For example,
PMCs that will only accept integer values can do get_integer/set_integer
instead of using clone.

-- 
Jason



Re: [COMMIT] miniperl has been somewhat busy...

2001-12-17 Thread Jason Gloudon

On Mon, Dec 17, 2001 at 09:43:28AM -0500, Dan Sugalski wrote:

 Can you clarify what you mean by deep copy at least to the pointer level ?
 
 set P0, P1
 
 should invoke P0's assignment vtable function (does anyone know if it 
 already
 exists under a different name ?). For the existing PMC's the appropriate
 assignment vtable calls P1's clone function with P0 as the destination.
 
 The entry's set_xxx, where xxx is integer, number, string, or value. 
 However, that's not appropriate here--set P0, P1 should just copy the 
 pointer from P1 to P0. Actually stuffing the value of the PMC pointed to by 
 P1 into the one pointed to in P0 should be done with a different op.

Ok, so set creates an alias. The string set opcode should also create an
alias for consistency, no ?

-- 
Jason



Re: [COMMIT] miniperl has been somewhat busy...

2001-12-17 Thread Jason Gloudon

On Mon, Dec 17, 2001 at 10:33:00AM -0500, Dan Sugalski wrote:

 Ok, so set creates an alias. The string set opcode should also create an
 alias for consistency, no ?
 
 It does. Or it did last I checked...

It was changed to make a copy. A high level language implementor wanted Perl
language level assignment.

AUTO_OP set(s, s|sc) {
  $1 = string_copy(interpreter, $2);
}

-- 
Jason



[PATCH] Re: Quick note to language implementers...

2001-12-14 Thread Jason Gloudon

On Thu, Dec 13, 2001 at 05:18:07PM -0500, Dan Sugalski wrote:
 I'm not sure we'll ultimately go this way, but I've added the following ops 
 to the core:
 
 setline
 setpackage
 setfile
 getline
 getpackage
 getfile

The debuginfo.t tests are missing 'end' opcodes. My win32 setup doens't like
this.

Index: debuginfo.t
===
RCS file: /home/perlcvs/parrot/t/op/debuginfo.t,v
retrieving revision 1.1
diff -w -r1.1 debuginfo.t
14a15
   end
29a31
   end
44a47
   end
75a79
   end

-- 
Jason



Re: Am I just an idiot...

2001-12-14 Thread Jason Gloudon

On Fri, Dec 14, 2001 at 09:59:30AM -0800, Brent Dax wrote:

 # new P0, PerlInt
 # new P1, PerlString
 # set P1, P0

 What I'm basically asking is, in that case are we going to be calling
   $1-vtable-set_string($2-vtable-get_string())
 or
   $1-vtable-set_integer($2-vtable-get_integer())

Assuming set does the equivalent of perl's '=' assignment this should call:

$2-vtable-clone($1)

Which makes a copy of $2 in $1 by overwriting the PMC structure of $1 with $2's
contents. 

'alias' seems like a good name for the pointer copy opcode.

-- 
Jason



Re: Key stuff for aggregates

2001-12-05 Thread Jason Gloudon

On Wed, Dec 05, 2001 at 12:18:53AM -0800, Brent Dax wrote:

 I'm probably just inexperienced and idiotic, but what's wrong with
 simple 'get_from_aggregate target, aggregate, key' and maybe
 'get_list_from_aggregate target_list, aggregate, key_list'?  (Obviously
 we'd shorten the names, but you get the idea.)  target would be set to
 the actual element, not just a copy of it, so setting that would set the
 original.

This is not the whole picture as the elements of an aggregate do not always
have associated vtables to compute with. Consider an array of native integers
(or native doubles). If you 'get' an lvalue from it, you won't know the
underlying type, so computing with it is messy unless you wrap the lvalue up in
some type of reference PMC. Creating one to access every element of an array
will create lots of extraneous temporaries.

Using the aggregate's vtable is another way of getting the job done that avoids
all the extra reference PMCs. However, references will have to be supported.

-- 
Jason



Re: Butt-ugliness reduction

2001-11-17 Thread Jason Gloudon

On Sat, Nov 17, 2001 at 02:22:44PM +, [EMAIL PROTECTED] wrote:
 Alan Burlison [EMAIL PROTECTED] wrote:
  Dave Mitchell wrote:
   * Is there ever any need to for a PMC type which holds both an int and
   a
   num? In the Perl 5 case we were constrained by code that expected to
   always
   find an int (or a num) in a fixed slot in the SV; with PMCs, all
   access
   to these slots is via methods, so an int-num or num-int conversion can
   be done on the fly.

If you use the same value enough times in places where you need an integral
value, (an array index, an argument to substr etc), it is faster to cache the
int value than converting from double (or BIGFLOAT) every time.

-- 
Jason



Re: Proper Tail Recursion

2001-11-16 Thread Jason Gloudon

On Thu, Nov 15, 2001 at 01:05:49PM -0500, Michael L Maraist wrote:

 I know it's dangerous to compare hardware to a VM, but the required 
 equivalent would be to not tear down ANY scoping, and additionally, the 
 definition of a subroutine would have to preallocate ALL scopes before-hand.

I think you're making more of it than is necessary. The scheme requirement is
that one can make an unbounded number of tail recursive calls in finite
storage. 

This can be done using the equivalent of Perl's magical goto. This might
destroy and re-create the same scope (though it's not clear how much real work
that entails) on each call, but the storage required will be fixed.

-- 
Jason



Re: PMCs and how the opcode functions will work

2001-11-16 Thread Jason Gloudon

On Thu, Nov 15, 2001 at 08:18:32PM +, Simon Cozens wrote:

 I'm under the impression that the signature of the add method should be
 
 void foo (interpreter, destination, left, right)
 
 Shouldn't the above be more like:
 
 P1-vtable-vtable_funcs[VTABLE_ADD + P2-vtable-num_type](i, P0, P1, P2);

Didn't someone mention using thread local storage to make the interpreter
structure available for memory allocation purposes. It would surely be useful
here.

-- 
Jason



Re: [COMMIT] Multimethod reworkage

2001-11-16 Thread Jason Gloudon

On Fri, Nov 16, 2001 at 03:40:57PM +, Simon Cozens wrote:

Hurrah!


-- 
Jason



Re: Lexical implementation work

2001-11-15 Thread Jason Gloudon

On Wed, Nov 14, 2001 at 01:11:54PM -0500, Dan Sugalski wrote:

 Correction (and please correct this correction if I'm wrong):
 An INTVAL should never get a /native/ pointer in it.  However, when we do
 relitave or absolute jumps in parrot code, the destination is an INTVAL.

Is this really going to remain true ? That absolute jumps on Ix registers will
remain relative to the start of the current bytecode section ?  (Since INTVAL
is not going to contain a pointer, jump Ix cannot be equivalent to pc = (opcode
*)Ix).

-- 
Jason



Re: memory assumptions

2001-11-14 Thread Jason Gloudon

On Tue, Nov 13, 2001 at 06:05:51PM -0500, Michael L Maraist wrote:

 treat them separately.  We're already having to treat handles differently 
 than buffer-objects.  I'm also wanting to segregate lists of leaf-buffers, 

Ok here is a reference to the thread that mentioned copy-on-write for sharing
of string buffers.

http:[EMAIL PROTECTED]/msg03242.html

The final idea was to share string buffers among PMCs only for a special PMC
class which makes copies of the buffer when modified. This is useful for
constants strings.

Always trying to share buffers would not be useful, since most of the time a
string is copied in order to munge it.

So going to your original question, here we have potentially common case where
a given buffer has multiple parents.

-- 
Jason



Re: memory assumptions

2001-11-13 Thread Jason Gloudon

On Mon, Nov 12, 2001 at 11:59:08PM -0500, Michael L Maraist wrote:

 2)
 Can we assume that a buffer object is ONLY accessible by a single 
 reverse-path-to-PMC?  PMC's or array-buffers can point to other PMC's, so 
 it's possible to have multiple paths from the root to an object, but I'm 
 asking if, for example, we could use an algorithm that relied upon the fact 
 that it only has one direct parent.

That assumption would mean one could not directly share non-constant buffers
between strings. There has been talk of having copy-on-write strings.

-- 
Jason



Re: Lexical implementation work

2001-11-12 Thread Jason Gloudon

On Sun, Nov 11, 2001 at 08:57:15PM -0800, Brent Dax wrote:

 You get the idea?  And as for multidimensional stuff, what's wrong with:
 
   fetchlex P1, @lol
   fetchary P2, P1, 1
   fetchary P3, P2, 2
   #...

Consider (from exegesis 2):

my int @hit_count is dim(100,366,24);

This array is supposed to contain bare integer values as opposed to scalars in
order to be memory efficient. It has been said that there would be a single PMC
which references the appropriate block or blocks of memory.

Also, any array access, for example @hitcount[5][5][6]

has to be done using the vtable of @hitcount as there is no scalar for each
entry. Hence the variable number of keys.

 Yes, I know, some people don't like that multidimensional arrays are
 internally arrays of arrays, but that doesn't necessarily need to be
 obvious to the outside world, does it?  Internally, the nested arrays
 could have tweaked vtables to do whatever they ought to do.

You potentially make all multidimensional arrays slower this way, if you HAVE
to do a memory lookup for each dimension to find an entry, as opposed to
directly calculating its offset in a contiguous block of memory.

-- 
Jason



Re: PMC support

2001-11-08 Thread Jason Gloudon

On Thu, Nov 08, 2001 at 12:26:55PM -0500, Dan Sugalski wrote:
 At 10:22 AM 11/8/2001 -0700, Nathan Torkington wrote:
 I haven't seen much activity surrounding this.  I figured there'd be a
 flood with everyone writing support for their own favourite data
 types.  What's up?
 
 We're not quite there yet with docs and environment, I think.
 
 I'm about to go missing for a few days and pound on this stuff. I'll make a 
 dump or two over the next few days if Simon doesn't beat me to it.

Yes, as I asked a day or two ago, it is not clear how what the short term
target for implementation vs the proposed design, when it comes to what the
vtable entries should be.

For example, the different between the vtable entries for set_integer and
get_integer. I was hoping to create a few of the entries, but I don't know what
is expected of them.

-- 
Jason



Re: Vtables fixed, scalar started

2001-11-07 Thread Jason Gloudon

On Tue, Nov 06, 2001 at 05:22:27PM -0500, Dan Sugalski wrote:

 A variable with a numeric value can be taken in one of three ways:
 
 *) As an integer. Which means either platform-native or bigint
 *) As a float. Which means either platform-native or bigfloat
 *) As a generic number. Which means platform native int or float, bigint or 
 bigfloat, or (possibly) a complex number.

Ok, so shouldn't there be a get_float vtable operator ?

It would be helpful if the current target ranges of values for the types of
vtable functions (int_type, float_type, num_type, string_type) could be
enumerated again, the last version I saw:

   base_type: A unique identifier attached to the package. 0-INTVAL_MAX
   int_type: 0, 1, 2, 3 for same as you, native int, bigint, object
   float_type: 0, 1, 2, 3 for same as you, native float, bigfloat, object
   num_type: 0, 1, 2, 3, 4, 5 for same as you, native int, bigint, native
 float, bigfloat, object
   string_type: 0, 1, 2, 3, 4 for same as you, native string, unicode,
other, object
 
does not match with the code generated for the vtables. For example, the NUM
vtable functions are being generated with 5 variants, but the above indicates
at least 6, and with what you've said about possibly complex numbers, this
could be 7.

-- 
Jason



  1   2   >