# New Ticket Created by  Jason Gloudon 
# Please include the string:  [perl #19418]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=19418 >



This patch gets garbage collection working on IA-64 linux. With a few more
changes it should work on HP-sUX as well.  The patch reorganizes the
trace_system_stack function that is now trace_mem_block, which examines an
arbitrary block of memory for possible buffer/PMC pointers.

The IA-64 is a big special case. In addition to having registers that must be
flushed to RAM, the registers are not flushed to the stack, but a separate
backing store area which is separate from the stack. To capture the remaining
registers, I've used the getcontext() call, as setjmp is not necessarily
sufficient.

Right now I've hard-coded the base address of the default backing store in
linux.  To make the current code work on all IA-64 platforms a base value of
the backing store for each interpreter thread will have to be noted as is done
for the stack pointer.

The code to flush the register store and return the current top of the register
store should go into asm/ia64.s .

I started trying to do this like I did for SPARC with pre-assembled code, but
I ran into two complications :

1) Thanks to the IA-64 ABI, function pointers are not simple pointers, but
instead point to function descriptors, which are somewhat awkward to construct
by hand because of compiler magic. I was able to sort this out and then ran
into 2.

2) Pages in the heap do not have execute permission by default on IA-64 linux,
so we'd have to put the code on the stack or use mprotect or mmap to create
pages with execute permissions in order to execute the pre-assembled code.

If anyone decides to implement Jit support for IA-64 they will have to deal
these issues.

-- 
Jason


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/46220/36192/934c5b/ia64.patch

-- attachment  2 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/46220/36193/8e42dc/ia64.s

? asm
Index: cpu_dep.c
===================================================================
RCS file: /cvs/public/parrot/cpu_dep.c,v
retrieving revision 1.3
diff -u -r1.3 cpu_dep.c
--- cpu_dep.c   11 Dec 2002 14:07:30 -0000      1.3
+++ cpu_dep.c   24 Dec 2002 19:53:52 -0000
@@ -12,12 +12,20 @@
 
 #include "parrot/parrot.h"
 
-void flush_register_windows(void);
+#ifdef __ia64__
 
-void
-flush_register_windows(void)
-{
-#ifdef __sparc
+#include <ucontext.h>
+extern void *flush_reg_store(void);
+#define BACKING_STORE_BASE 0x80000fff80000000
+
+#endif
+
+PMC * trace_system_stack(struct Parrot_Interp *interpreter, PMC *last);
+
+PMC *
+trace_system_areas(struct Parrot_Interp *interpreter, PMC *last){
+
+#ifdef __sparc /* Flush register windows */
     static union {
        int insns[4];
         double align_hack[2];
@@ -33,10 +41,42 @@
 
     static void (*fn_ptr)(void) = (void (*)(void))&u.align_hack[0];
     fn_ptr();
+#endif
+
+
+#ifdef __ia64__
+
+    struct ucontext ucp;
+    void *current_regstore_top;
 
+    getcontext(&ucp);
+    current_regstore_top = flush_reg_store();
+
+    last = trace_mem_block(interpreter, last, 0x80000fff80000000,
+                               (size_t)current_regstore_top);
 #else
 
-    return;
+#ifdef HAS_HEADER_SETJMP
+    Parrot_jump_buff env;
+
+    /* this should put registers in env, which then get marked in
+     * trace_system_stack below
+     */
+    setjmp(env);
+#endif
 
 #endif
+
+
+    return trace_system_stack(interpreter, last);
+}
+
+PMC *
+trace_system_stack(struct Parrot_Interp *interpreter, PMC *last){
+    size_t lo_var_ptr = (size_t)interpreter->lo_var_ptr;
+
+    last = trace_mem_block(interpreter, last, (size_t)lo_var_ptr,
+                          (size_t)&lo_var_ptr);
+
+    return last;
 }
Index: dod.c
===================================================================
RCS file: /cvs/public/parrot/dod.c,v
retrieving revision 1.38
diff -u -r1.38 dod.c
--- dod.c       12 Dec 2002 08:07:08 -0000      1.38
+++ dod.c       24 Dec 2002 19:53:53 -0000
@@ -20,7 +20,6 @@
 int CONSERVATIVE_POINTER_CHASING = 0;
 #endif
 
-extern void flush_register_windows(void);
 static size_t find_common_mask(size_t val1, size_t val2);
 
 PMC *
@@ -108,14 +107,6 @@
     struct Stash *stash;
     UINTVAL mask = PObj_is_PMC_ptr_FLAG | PObj_is_buffer_ptr_FLAG
             | PObj_custom_mark_FLAG;
-#ifdef HAS_HEADER_SETJMP
-    Parrot_jump_buff env;
-
-    /* this should put registers in env, which then get marked in
-     * trace_system_stack below
-     */
-    setjmp(env);
-#endif
 
     /* We have to start somewhere, and the global stash is a good place */
     last = current = interpreter->perl_stash->stash_hash;
@@ -129,7 +120,7 @@
 #if ! DISABLE_GC_DEBUG
     CONSERVATIVE_POINTER_CHASING = 1;
 #endif
-    last = trace_system_stack(interpreter, last);
+    last = trace_system_areas(interpreter, last);
 #if ! DISABLE_GC_DEBUG
     CONSERVATIVE_POINTER_CHASING = 0;
 #endif
@@ -533,10 +524,9 @@
 }
 
 PMC *
-trace_system_stack(struct Parrot_Interp *interpreter, PMC *last)
+trace_mem_block(struct Parrot_Interp *interpreter, PMC *last,
+               size_t lo_var_ptr, size_t hi_var_ptr)
 {
-    size_t lo_var_ptr = (size_t)interpreter->lo_var_ptr;
-    size_t hi_var_ptr = (size_t)&lo_var_ptr;
     size_t prefix, tmp_ptr;
     ptrdiff_t cur_var_ptr;
 
@@ -548,10 +538,7 @@
     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)
+    if (!lo_var_ptr || !hi_var_ptr)
         return last;
     if (lo_var_ptr < hi_var_ptr) {
         tmp_ptr = hi_var_ptr;
@@ -570,9 +557,10 @@
 
         /* Do a quick approximate range check by bit-masking */
         if ((ptr & mask) == prefix) {
-            /* Note that what we find on the stack is not guaranteed to be a
-             * live pmc/buffer, and could very well have its bufstart/vtable
-             * destroyed due to the linked list of free headers... */
+            /* Note that what we find via the stack or registers are not
+             * guaranteed to be live pmcs/buffers, and could very well their
+             * bufstart/vtable destroyed due to the linked list of free
+             * headers... */
             if (pmc_min <= ptr && ptr < pmc_max &&
                     is_pmc_ptr(interpreter, (void *)ptr)) {
                 /* ...so ensure that mark_used checks PObj_on_free_list_FLAG
Index: config/auto/jit.pl
===================================================================
RCS file: /cvs/public/parrot/config/auto/jit.pl,v
retrieving revision 1.10
diff -u -r1.10 jit.pl
--- config/auto/jit.pl  18 Dec 2002 04:24:07 -0000      1.10
+++ config/auto/jit.pl  24 Dec 2002 19:53:53 -0000
@@ -2,7 +2,7 @@
 
 use strict;
 use vars qw($description @args);
-use Parrot::Configure::Step;
+use Parrot::Configure::Step qw(copy_if_diff);
 
 
 $description = "Determining architecture, OS and JIT capability...";
@@ -67,6 +67,12 @@
        Configure::Data->get('intvalsize') > Configure::Data->get('ptrsize')) {
            $jitcapable = 0;
        }
+  }
+
+  if (-e "asm/$cpuarch.s") {
+    copy_if_diff("asm/$cpuarch.s", "asmfun.s");
+
+    Configure::Data->set(asmfun_o => 'asmfun$(O)');
   }
 
   $jitcapable = $set_jitcapable if defined $set_jitcapable;
Index: config/gen/makefiles/root.in
===================================================================
RCS file: /cvs/public/parrot/config/gen/makefiles/root.in,v
retrieving revision 1.62
diff -u -r1.62 root.in
--- config/gen/makefiles/root.in        12 Dec 2002 11:21:06 -0000      1.62
+++ config/gen/makefiles/root.in        24 Dec 2002 19:53:54 -0000
@@ -108,7 +108,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) cpu_dep$(O)
+       nci$(O) cpu_dep$(O) ${asmfun_o}
 
 O_FILES = $(INTERP_O_FILES) $(IO_O_FILES) $(CLASS_O_FILES) \
        $(ENCODING_O_FILES) $(CHARTYPE_O_FILES)
Index: include/parrot/dod.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/dod.h,v
retrieving revision 1.7
diff -u -r1.7 dod.h
--- include/parrot/dod.h        10 Dec 2002 13:43:28 -0000      1.7
+++ include/parrot/dod.h        24 Dec 2002 19:53:56 -0000
@@ -41,7 +41,8 @@
         ((interpreter)->GC_block_level)
 
 void Parrot_do_dod_run(struct Parrot_Interp *);
-PMC *trace_system_stack(struct Parrot_Interp *, PMC *);
+PMC *trace_system_areas(struct Parrot_Interp *, PMC *);
+PMC *trace_mem_block(struct Parrot_Interp *, PMC *, size_t, size_t);
 
 void free_unused_buffers(struct Parrot_Interp *interpreter,
                     struct Small_Object_Pool *pool, int cleanup);
        .file   "ia64.s"
                .text
                .psr abi64
                .psr lsb
                .lsb
        
                .align 16
                .global flush_reg_store
                .proc flush_reg_store
        flush_reg_store:
                .body
                flushrs
                ;;
                mov r8=ar.bsp
                br.ret.sptk.few rp
                .endp flush_reg_store

Reply via email to