/[cmucl]/src/lisp/gencgc.c
ViewVC logotype

Diff of /src/lisp/gencgc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.32 by gerd, Thu Mar 27 12:42:10 2003 UTC revision 1.32.2.1 by gerd, Mon Aug 25 17:06:43 2003 UTC
# Line 28  Line 28 
28  #define gc_abort() lose("GC invariant lost!  File \"%s\", line %d\n", \  #define gc_abort() lose("GC invariant lost!  File \"%s\", line %d\n", \
29                          __FILE__, __LINE__)                          __FILE__, __LINE__)
30    
31  #if 0  #if defined(i386)
32    #define set_alloc_pointer(value)  SetSymbolValue(ALLOCATION_POINTER, value)
33    #define get_alloc_pointer()       SymbolValue(ALLOCATION_POINTER)
34    #define get_binding_stack_pointer()     SymbolValue(BINDING_STACK_POINTER)
35    #define get_pseudo_atomic_atomic()      SymbolValue(PSEUDO_ATOMIC_ATOMIC)
36    #define set_pseudo_atomic_atomic()      SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(0));
37    #define clr_pseudo_atomic_atomic()      SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(1));
38    #define get_pseudo_atomic_interrupted() SymbolValue(PSEUDO_ATOMIC_INTERRUPTED)
39    #define clr_pseudo_atomic_interrupted() SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, make_fixnum(0))
40    #elif defined(sparc)
41    #define set_alloc_pointer(value)  (current_dynamic_space_free_pointer = (value))
42    #define get_alloc_pointer()       (current_dynamic_space_free_pointer)
43    #define get_binding_stack_pointer()     (current_binding_stack_pointer)
44    #define get_pseudo_atomic_atomic() \
45         ((unsigned long)current_dynamic_space_free_pointer & 4)
46    #define set_pseudo_atomic_atomic() \
47         (current_dynamic_space_free_pointer \
48           = (lispobj*) ((unsigned long)current_dynamic_space_free_pointer | 4))
49    #define clr_pseudo_atomic_atomic() \
50         (current_dynamic_space_free_pointer \
51           = (lispobj*) ((unsigned long) current_dynamic_space_free_pointer & ~4))
52    #define get_pseudo_atomic_interrupted() ((unsigned long) current_dynamic_space_free_pointer & 1)
53    #define clr_pseudo_atomic_interrupted() \
54         (current_dynamic_space_free_pointer \
55           = (lispobj*) ((unsigned long) current_dynamic_space_free_pointer & ~1))
56    #else
57    #endif
58    
59    /*
60     * Leave the gc_asserts enabled on sparc for a while yet until this
61     * stabilizes.
62     */
63    #if defined(sparc)
64  #define gc_assert(ex) do { \  #define gc_assert(ex) do { \
65          if (!(ex)) gc_abort(); \          if (!(ex)) gc_abort(); \
66  } while (0)  } while (0)
# Line 71  boolean  enable_page_protection = TRUE; Line 103  boolean  enable_page_protection = TRUE;
103  int verify_gens = NUM_GENERATIONS;  int verify_gens = NUM_GENERATIONS;
104    
105  /*  /*
106   * Enable a pre-scan verify of generation 0 before it's GCed.   * Enable a pre-scan verify of generation 0 before it's GCed.  (This
107     * makes GC very, very slow, so don't enable this unless you really
108     * need it!)
109   */   */
110  boolean pre_verify_gen_0 = FALSE;  boolean pre_verify_gen_0 = FALSE;
111    
# Line 88  boolean verify_dynamic_code_check = FALS Line 122  boolean verify_dynamic_code_check = FALS
122    
123  /*  /*
124   * Enable the checking of code objects for fixup errors after they are   * Enable the checking of code objects for fixup errors after they are
125   * transported.   * transported.  (Only used for x86.)
126   */   */
127  boolean check_code_fixups = FALSE;  boolean check_code_fixups = FALSE;
128    
# Line 403  static double gen_av_mem_age(int gen) Line 437  static double gen_av_mem_age(int gen)
437  void print_generation_stats(int  verbose)  void print_generation_stats(int  verbose)
438  {  {
439    int i, gens;    int i, gens;
440    int fpu_state[27];  #if defined(i386)
441    #define FPU_STATE_SIZE 27
442      int fpu_state[FPU_STATE_SIZE];
443    #elif defined(sparc)
444      /*
445       * 32 (single-precision) FP registers, and the FP state register.
446       * But Sparc V9 has 32 double-precision registers (equivalent to 64
447       * single-precision, but can't be accessed), so we leave enough room
448       * for that.
449       */
450    #define FPU_STATE_SIZE (((32 + 32 + 1) + 1)/2)
451      long long fpu_state[FPU_STATE_SIZE];
452    #endif
453    
454    /*    /*
455     * This code uses the FP instructions which may be setup for Lisp so     * This code uses the FP instructions which may be setup for Lisp so
456     * they need to the saved and reset for C.     * they need to the saved and reset for C.
457     */     */
458    fpu_save(fpu_state);    fpu_save(fpu_state);
459    
460    /* Number of generations to print out. */    /* Number of generations to print out. */
461    if (verbose)    if (verbose)
462      gens = NUM_GENERATIONS + 1;      gens = NUM_GENERATIONS + 1;
# Line 757  static void gc_alloc_new_region(int nbyt Line 803  static void gc_alloc_new_region(int nbyt
803    /* Bump up the last_free_page */    /* Bump up the last_free_page */
804    if (last_page + 1 > last_free_page) {    if (last_page + 1 > last_free_page) {
805      last_free_page = last_page + 1;      last_free_page = last_page + 1;
806      SetSymbolValue(ALLOCATION_POINTER,      set_alloc_pointer((lispobj) ((char *) heap_base +
807                     (lispobj) ((char *) heap_base +                                 PAGE_SIZE * last_free_page));
808                                PAGE_SIZE * last_free_page));  
809    }    }
810  }  }
811    
# Line 938  void gc_alloc_update_page_tables(int unb Line 984  void gc_alloc_update_page_tables(int unb
984       */       */
985      while (more) {      while (more) {
986  #if 0  #if 0
987        fprintf(stderr, "+")        fprintf(stderr, "+");
988  #endif  #endif
989        gc_assert(PAGE_ALLOCATED(next_page));        gc_assert(PAGE_ALLOCATED(next_page));
990        gc_assert(PAGE_UNBOXED_VAL(next_page) == unboxed);        gc_assert(PAGE_UNBOXED_VAL(next_page) == unboxed);
# Line 1241  static void *gc_alloc_large(int  nbytes, Line 1287  static void *gc_alloc_large(int  nbytes,
1287    /* Bump up the last_free_page */    /* Bump up the last_free_page */
1288    if (last_page + 1 > last_free_page) {    if (last_page + 1 > last_free_page) {
1289      last_free_page = last_page + 1;      last_free_page = last_page + 1;
1290      SetSymbolValue(ALLOCATION_POINTER,      set_alloc_pointer((lispobj) ((char *) heap_base +
1291                     (lispobj) ((char *) heap_base +                                 PAGE_SIZE * last_free_page));
                               PAGE_SIZE * last_free_page));  
1292    }    }
1293    
1294    return (void *) (page_address(first_page) + orig_first_page_bytes_used);    return (void *) (page_address(first_page) + orig_first_page_bytes_used);
# Line 1937  static void scavenge(lispobj *start, lon Line 1982  static void scavenge(lispobj *start, lon
1982  }  }
1983    
1984    
1985    #ifndef i386
1986    /* Scavenging Interrupt Contexts */
1987    
1988    static int boxed_registers[] = BOXED_REGISTERS;
1989    
1990    static void scavenge_interrupt_context(struct sigcontext *context)
1991    {
1992      int i;
1993    #ifdef reg_LIP
1994      unsigned long lip;
1995      unsigned long lip_offset;
1996      int lip_register_pair;
1997    #endif
1998      unsigned long pc_code_offset;
1999    #ifdef SC_NPC
2000      unsigned long npc_code_offset;
2001    #endif
2002    
2003    #ifdef reg_LIP
2004      /* Find the LIP's register pair and calculate it's offset */
2005      /* before we scavenge the context. */
2006    
2007      /*
2008       * I (RLT) think this is trying to find the boxed register that is
2009       * closest to the LIP address, without going past it.  Usually, it's
2010       * reg_CODE or reg_LRA.  But sometimes, nothing can be found.
2011       */
2012      lip = SC_REG(context, reg_LIP);
2013      lip_offset = 0x7FFFFFFF;
2014      lip_register_pair = -1;
2015      for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++)
2016        {
2017          unsigned long reg;
2018          long offset;
2019          int index;
2020    
2021          index = boxed_registers[i];
2022          reg = SC_REG(context, index);
2023          if (Pointerp(reg) && PTR(reg) <= lip) {
2024            offset = lip - reg;
2025            if (offset < lip_offset) {
2026              lip_offset = offset;
2027              lip_register_pair = index;
2028            }
2029          }
2030        }
2031    #endif /* reg_LIP */
2032    
2033      /* Compute the PC's offset from the start of the CODE */
2034      /* register. */
2035      pc_code_offset = SC_PC(context) - SC_REG(context, reg_CODE);
2036    #ifdef SC_NPC
2037      npc_code_offset = SC_NPC(context) - SC_REG(context, reg_CODE);
2038    #endif /* SC_NPC */
2039    
2040      /* Scanvenge all boxed registers in the context. */
2041      for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++)
2042        {
2043          int index;
2044          lispobj foo;
2045    
2046          index = boxed_registers[i];
2047          foo = SC_REG(context,index);
2048          scavenge((lispobj *) &foo, 1);
2049          SC_REG(context,index) = foo;
2050    
2051          scavenge((lispobj *) &(SC_REG(context, index)), 1);
2052        }
2053    
2054    #ifdef reg_LIP
2055      /* Fix the LIP */
2056    
2057      /*
2058       * But what happens if lip_register_pair is -1?  SC_REG on Solaris
2059       * (see solaris_register_address in solaris-os.c) will return
2060       * &context->uc_mcontext.gregs[2].  But gregs[2] is REG_nPC.  Is
2061       * that what we really want?  My guess is that that is not what we
2062       * want, so if lip_register_pair is -1, we don't touch reg_LIP at
2063       * all.  But maybe it doesn't really matter if LIP is trashed?
2064       */
2065      if (lip_register_pair >= 0)
2066        {
2067          SC_REG(context, reg_LIP) =
2068            SC_REG(context, lip_register_pair) + lip_offset;
2069        }
2070    #endif /* reg_LIP */
2071    
2072      /* Fix the PC if it was in from space */
2073      if (from_space_p(SC_PC(context)))
2074        SC_PC(context) = SC_REG(context, reg_CODE) + pc_code_offset;
2075    #ifdef SC_NPC
2076      if (from_space_p(SC_NPC(context)))
2077        SC_NPC(context) = SC_REG(context, reg_CODE) + npc_code_offset;
2078    #endif /* SC_NPC */
2079    }
2080    
2081    void scavenge_interrupt_contexts(void)
2082    {
2083      int i, index;
2084      struct sigcontext *context;
2085    
2086      index = fixnum_value(SymbolValue(FREE_INTERRUPT_CONTEXT_INDEX));
2087    
2088    #if defined(DEBUG_PRINT_CONTEXT_INDEX)
2089      printf("Number of active contexts: %d\n", index);
2090    #endif
2091    
2092      for (i = 0; i < index; i++)
2093        {
2094          context = lisp_interrupt_contexts[i];
2095          scavenge_interrupt_context(context);
2096        }
2097    }
2098    #endif
2099    
2100  /* Code and Code-Related Objects */  /* Code and Code-Related Objects */
2101    
2102    /*
2103     * Aargh!  Why is SPARC so different here?  What is the advantage of
2104     * making it different from all the other ports?
2105     */
2106    #ifdef sparc
2107    #define RAW_ADDR_OFFSET 0
2108    #else
2109  #define RAW_ADDR_OFFSET (6 * sizeof(lispobj) - type_FunctionPointer)  #define RAW_ADDR_OFFSET (6 * sizeof(lispobj) - type_FunctionPointer)
2110    #endif
2111    
2112  static lispobj trans_function_header(lispobj object);  static lispobj trans_function_header(lispobj object);
2113  static lispobj trans_boxed(lispobj object);  static lispobj trans_boxed(lispobj object);
# Line 2042  static int scav_function_pointer(lispobj Line 2210  static int scav_function_pointer(lispobj
2210  }  }
2211  #endif  #endif
2212    
2213    #ifdef i386
2214  /*  /*
2215   * Scan a x86 compiled code objected, looking for possible fixups that   * Scan a x86 compiled code objected, looking for possible fixups that
2216   * have been missed after a move.   * have been missed after a move.
# Line 2340  static void apply_code_fixups(struct cod Line 2509  static void apply_code_fixups(struct cod
2509    if (check_code_fixups)    if (check_code_fixups)
2510      sniff_code_object(new_code, displacement);      sniff_code_object(new_code, displacement);
2511  }  }
2512    #endif
2513    
2514  static struct code * trans_code(struct code *code)  static struct code * trans_code(struct code *code)
2515  {  {
# Line 2356  static struct code * trans_code(struct c Line 2526  static struct code * trans_code(struct c
2526    
2527    /* If object has already been transported, just return pointer */    /* If object has already been transported, just return pointer */
2528    if (*(lispobj *) code == 0x01)    if (*(lispobj *) code == 0x01)
2529      return (struct code*) (((lispobj *) code)[1]);      {
2530          return (struct code*) (((lispobj *) code)[1]);
2531        }
2532    
2533    
2534    gc_assert(TypeOf(code->header) == type_CodeHeader);    gc_assert(TypeOf(code->header) == type_CodeHeader);
2535    
# Line 2424  static struct code * trans_code(struct c Line 2597  static struct code * trans_code(struct c
2597  #if 0  #if 0
2598    sniff_code_object(new_code, displacement);    sniff_code_object(new_code, displacement);
2599  #endif  #endif
2600    #ifdef i386
2601    apply_code_fixups(code, new_code);    apply_code_fixups(code, new_code);
2602    #else
2603      /* From gc.c */
2604    #ifndef MACH
2605      os_flush_icache((os_vm_address_t) (((int *)new_code) + nheader_words),
2606                      ncode_words * sizeof(int));
2607    #endif
2608    #endif
2609    
2610    return new_code;    return new_code;
2611  }  }
# Line 2504  static lispobj trans_return_pc_header(li Line 2685  static lispobj trans_return_pc_header(li
2685    unsigned long offset;    unsigned long offset;
2686    struct code *code, *ncode;    struct code *code, *ncode;
2687    
   fprintf(stderr, "*** trans_return_pc_header: will this work?\n");  
   
2688    return_pc = (struct function *) PTR(object);    return_pc = (struct function *) PTR(object);
2689    offset = HeaderValue(return_pc->header) * 4;    offset = HeaderValue(return_pc->header) * 4;
2690    
2691    /* Transport the whole code object */    /* Transport the whole code object */
2692    code = (struct code *) ((unsigned long) return_pc - offset);    code = (struct code *) ((unsigned long) return_pc - offset);
2693    
2694    ncode = trans_code(code);    ncode = trans_code(code);
2695    
2696    return ((lispobj) ncode + offset) | type_OtherPointer;    return ((lispobj) ncode + offset) | type_OtherPointer;
# Line 2833  static int scav_boxed(lispobj *where, li Line 3013  static int scav_boxed(lispobj *where, li
3013    
3014  static lispobj trans_boxed(lispobj object)  static lispobj trans_boxed(lispobj object)
3015  {  {
3016          lispobj header;    lispobj header;
3017          unsigned long length;    unsigned long length;
3018    
3019          gc_assert(Pointerp(object));    gc_assert(Pointerp(object));
3020    
3021          header = *((lispobj *) PTR(object));    header = *((lispobj *) PTR(object));
3022          length = HeaderValue(header) + 1;    length = HeaderValue(header) + 1;
3023          length = CEILING(length, 2);    length = CEILING(length, 2);
3024    
3025          return copy_object(object, length);    return copy_object(object, length);
3026  }  }
3027    
3028  static lispobj trans_boxed_large(lispobj object)  static lispobj trans_boxed_large(lispobj object)
# Line 3311  scav_hash_vector (lispobj *where, lispob Line 3491  scav_hash_vector (lispobj *where, lispob
3491       length.  The first value is the symbol :empty, the first key is a       length.  The first value is the symbol :empty, the first key is a
3492       reference to the hash-table containing the key/value vector.       reference to the hash-table containing the key/value vector.
3493       (See hash-new.lisp, MAKE-HASH-TABLE.)  */       (See hash-new.lisp, MAKE-HASH-TABLE.)  */
3494    
3495    kv_length = fixnum_value (where[1]);    kv_length = fixnum_value (where[1]);
3496    kv_vector = where + 2;    kv_vector = where + 2;
3497    
3498    scavenge (kv_vector, 2);    scavenge (kv_vector, 2);
3499    
3500    gc_assert (Pointerp (kv_vector[0]));    gc_assert (Pointerp (kv_vector[0]));
# Line 3323  scav_hash_vector (lispobj *where, lispob Line 3504  scav_hash_vector (lispobj *where, lispob
3504    hash_table = (struct hash_table *) PTR (hash_table_obj);    hash_table = (struct hash_table *) PTR (hash_table_obj);
3505    empty_symbol = kv_vector[1];    empty_symbol = kv_vector[1];
3506    
3507      /*
3508       * For some reason, the following GC assert doesn't always hold true
3509       * on Sparc/gencgc.  I (RLT) don't know why that is.  So turn it off
3510       * for now.  I leave these printfs here so I can see it happening,
3511       * just in case.
3512       */
3513    #ifdef sparc
3514      if (where != (lispobj *) PTR (hash_table->table))
3515        {
3516          fprintf(stderr, "Hash table invariant failed during scavenging!\n");
3517          fprintf(stderr, " *** where = %lx\n", where);
3518          fprintf(stderr, " *** hash_table = %lx\n", hash_table);
3519          fprintf(stderr, " *** hash_table->table = %lx\n", PTR(hash_table->table));
3520    #if 0
3521          reset_printer();
3522          print(object);
3523          abort();
3524    #endif
3525        }
3526    #endif
3527    
3528    #ifndef sparc
3529    gc_assert (where == (lispobj *) PTR (hash_table->table));    gc_assert (where == (lispobj *) PTR (hash_table->table));
3530    #endif
3531    gc_assert (TypeOf (hash_table->instance_header) == type_InstanceHeader);    gc_assert (TypeOf (hash_table->instance_header) == type_InstanceHeader);
3532    gc_assert (TypeOf (*(lispobj *) PTR (empty_symbol)) == type_SymbolHeader);    gc_assert (TypeOf (*(lispobj *) PTR (empty_symbol)) == type_SymbolHeader);
3533    
# Line 4079  static void gc_init_tables(void) Line 4283  static void gc_init_tables(void)
4283          scavtab[type_ComplexVector] = scav_boxed;          scavtab[type_ComplexVector] = scav_boxed;
4284          scavtab[type_ComplexArray] = scav_boxed;          scavtab[type_ComplexArray] = scav_boxed;
4285          scavtab[type_CodeHeader] = scav_code_header;          scavtab[type_CodeHeader] = scav_code_header;
4286          /*scavtab[type_FunctionHeader] = scav_function_header;*/  #ifndef i386
4287          /*scavtab[type_ClosureFunctionHeader] = scav_function_header;*/          scavtab[type_FunctionHeader] = scav_function_header;
4288          /*scavtab[type_ReturnPcHeader] = scav_return_pc_header;*/          scavtab[type_ClosureFunctionHeader] = scav_function_header;
4289            scavtab[type_ReturnPcHeader] = scav_return_pc_header;
4290    #endif
4291  #ifdef i386  #ifdef i386
4292          scavtab[type_ClosureHeader] = scav_closure_header;          scavtab[type_ClosureHeader] = scav_closure_header;
4293          scavtab[type_FuncallableInstanceHeader] = scav_closure_header;          scavtab[type_FuncallableInstanceHeader] = scav_closure_header;
# Line 4102  static void gc_init_tables(void) Line 4308  static void gc_init_tables(void)
4308          scavtab[type_UnboundMarker] = scav_immediate;          scavtab[type_UnboundMarker] = scav_immediate;
4309          scavtab[type_WeakPointer] = scav_weak_pointer;          scavtab[type_WeakPointer] = scav_weak_pointer;
4310          scavtab[type_InstanceHeader] = scav_boxed;          scavtab[type_InstanceHeader] = scav_boxed;
4311            /*
4312             * Note: on the sparc we don't have to do anything special for
4313             * fdefns, cause the raw-addr has a function lowtag.
4314             */
4315    #ifndef sparc
4316          scavtab[type_Fdefn] = scav_fdefn;          scavtab[type_Fdefn] = scav_fdefn;
4317    #else
4318            scavtab[type_Fdefn] = scav_boxed;
4319    #endif
4320    
4321          scavtab[type_ScavengerHook] = scav_scavenger_hook;          scavtab[type_ScavengerHook] = scav_scavenger_hook;
4322    
4323          /* Transport Other Table */          /* Transport Other Table */
# Line 5387  static void unprotect_oldspace(void) Line 5602  static void unprotect_oldspace(void)
5602   * generation. Bytes_allocated and the generation bytes_allocated   * generation. Bytes_allocated and the generation bytes_allocated
5603   * counter are updated.  The number of bytes freed is returned.   * counter are updated.  The number of bytes freed is returned.
5604   */   */
5605    #ifdef i386
5606  extern void i586_bzero(void *addr, int nbytes);  extern void i586_bzero(void *addr, int nbytes);
5607    #else
5608    #define i586_bzero(addr, nbytes)        memset(addr, 0, nbytes)
5609    #endif
5610  static int free_oldspace(void)  static int free_oldspace(void)
5611  {  {
5612    int bytes_freed = 0;    int bytes_freed = 0;
# Line 5483  static void print_ptr(lispobj *addr) Line 5702  static void print_ptr(lispobj *addr)
5702            *(addr + 1), *(addr + 2), *(addr + 3), *(addr + 4));            *(addr + 1), *(addr + 2), *(addr + 3), *(addr + 4));
5703  }  }
5704    
5705    #ifdef sparc
5706    extern char  closure_tramp;
5707    #else
5708  extern int  undefined_tramp;  extern int  undefined_tramp;
5709    #endif
5710    
5711  static void verify_space(lispobj*start, size_t words)  static void verify_space(lispobj*start, size_t words)
5712  {  {
# Line 5542  static void verify_space(lispobj*start, Line 5765  static void verify_space(lispobj*start,
5765            print_ptr(start);            print_ptr(start);
5766          }          }
5767  #endif  #endif
5768        } else        } else {
5769          /* Verify that it points to another valid space */          /* Verify that it points to another valid space */
5770          if (!to_readonly_space && !to_static_space          if (!to_readonly_space && !to_static_space &&
5771              && thing != (int) &undefined_tramp) {  #if defined(sparc)
5772            fprintf(stderr, "*** Ptr %lx @ %lx sees Junk\n",              thing != (int) &closure_tramp
5773                    (unsigned long) thing, (unsigned long) start);  #else
5774            print_ptr(start);              thing != (int) &undefined_tramp
5775          }  #endif
5776                )
5777              {
5778                fprintf(stderr, "*** Ptr %lx @ %lx sees Junk (undefined_tramp = %lx)\n",
5779                        (unsigned long) thing, (unsigned long) start,
5780    #if defined(sparc)
5781                        (unsigned long) &closure_tramp
5782    #else
5783                        (unsigned long) &undefined_tramp
5784    #endif
5785                        );
5786                print_ptr(start);
5787              }
5788          }
5789    
5790      } else      } else
5791        if (thing & 0x3) /* Skip fixnums */        if (thing & 0x3) /* Skip fixnums */
5792          switch(TypeOf(*start)) {          switch(TypeOf(*start)) {
# Line 5694  static void verify_gc(void) Line 5931  static void verify_gc(void)
5931      (lispobj*) SymbolValue(STATIC_SPACE_FREE_POINTER)      (lispobj*) SymbolValue(STATIC_SPACE_FREE_POINTER)
5932      - (lispobj*) static_space;      - (lispobj*) static_space;
5933    int binding_stack_size =    int binding_stack_size =
5934      (lispobj*) SymbolValue(BINDING_STACK_POINTER)      (lispobj*) get_binding_stack_pointer()
5935      - (lispobj*) BINDING_STACK_START;      - (lispobj*) BINDING_STACK_START;
5936    
5937    verify_space((lispobj*) READ_ONLY_SPACE_START, read_only_space_size);    verify_space((lispobj*) READ_ONLY_SPACE_START, read_only_space_size);
# Line 5896  static void    garbage_collect_generation(i Line 6133  static void    garbage_collect_generation(i
6133     */     */
6134    unprotect_oldspace();    unprotect_oldspace();
6135    
6136    #ifdef i386
6137    /* Scavenge the stacks conservative roots. */    /* Scavenge the stacks conservative roots. */
6138    {    {
6139      lispobj **ptr;      lispobj **ptr;
# Line 5903  static void    garbage_collect_generation(i Line 6141  static void    garbage_collect_generation(i
6141           ptr > (lispobj **) &raise; ptr--)           ptr > (lispobj **) &raise; ptr--)
6142        preserve_pointer(*ptr);        preserve_pointer(*ptr);
6143    }    }
6144    #endif
6145    
6146  #ifdef CONTROL_STACKS  #ifdef CONTROL_STACKS
6147    scavenge_thread_stacks();    scavenge_thread_stacks();
6148  #endif  #endif
# Line 5911  static void    garbage_collect_generation(i Line 6151  static void    garbage_collect_generation(i
6151      int num_dont_move_pages = count_dont_move_pages();      int num_dont_move_pages = count_dont_move_pages();
6152      fprintf(stderr, "Non-movable pages due to conservative pointers = %d, %d bytes\n",      fprintf(stderr, "Non-movable pages due to conservative pointers = %d, %d bytes\n",
6153              num_dont_move_pages, PAGE_SIZE * num_dont_move_pages);              num_dont_move_pages, PAGE_SIZE * num_dont_move_pages);
6154    #ifndef i386
6155        /*
6156         * There shouldn't be any non-movable pages because we don't have
6157         * any conservative pointers!
6158         */
6159        gc_assert(num_dont_move_pages == 0);
6160    #endif
6161    }    }
6162    
6163    /* Scavenge all the rest of the roots. */    /* Scavenge all the rest of the roots. */
# Line 5920  static void    garbage_collect_generation(i Line 6167  static void    garbage_collect_generation(i
6167     * care to avoid SIG_DFL, SIG_IGN.     * care to avoid SIG_DFL, SIG_IGN.
6168     */     */
6169    
6170    #ifndef i386
6171      /*
6172       * If not x86, scavenge the interrupt context(s) and the control
6173       * stack.
6174       */
6175    #ifdef PRINTNOISE
6176      printf("Scavenging interrupt contexts ...\n");
6177    #endif
6178      scavenge_interrupt_contexts();
6179    #ifdef PRINTNOISE
6180      printf("Scavenging interrupt handlers (%d bytes) ...\n",
6181             sizeof(interrupt_handlers));
6182    #endif
6183      scavenge((lispobj *) interrupt_handlers,
6184               sizeof(interrupt_handlers) / sizeof(lispobj));
6185      {
6186        unsigned long control_stack_size;
6187    
6188        control_stack_size = current_control_stack_pointer - control_stack;
6189    #ifdef PRINTNOISE
6190        printf("Scavenging the control stack (%d bytes) ...\n",
6191               control_stack_size * sizeof(lispobj));
6192    #endif
6193        scavenge(control_stack, control_stack_size);
6194    #ifdef PRINTNOISE
6195        printf("Done scavenging the control stack.\n");
6196    #endif
6197      }
6198    
6199    #else /* x86 */
6200    for (i = 0; i < NSIG; i++) {    for (i = 0; i < NSIG; i++) {
6201      union interrupt_handler handler = interrupt_handlers[i];      union interrupt_handler handler = interrupt_handlers[i];
6202      if (handler.c != (void (*) (HANDLER_ARGS)) SIG_IGN      if (handler.c != (void (*) (HANDLER_ARGS)) SIG_IGN
6203          && handler.c != (void (*) (HANDLER_ARGS)) SIG_DFL)          && handler.c != (void (*) (HANDLER_ARGS)) SIG_DFL)
6204        scavenge((lispobj *) (interrupt_handlers + i), 1);        scavenge((lispobj *) (interrupt_handlers + i), 1);
6205    }    }
6206    #endif
6207    
6208    #ifdef PRINTNOISE
6209        printf("Scavenging the binding stack (%d bytes) ...\n",
6210               ((lispobj *) get_binding_stack_pointer() - binding_stack) * sizeof(lispobj));
6211    #endif
6212    /* Scavenge the binding stack. */    /* Scavenge the binding stack. */
6213    scavenge(binding_stack,    scavenge(binding_stack,
6214             (lispobj *) SymbolValue(BINDING_STACK_POINTER) - binding_stack);             (lispobj *) get_binding_stack_pointer() - binding_stack);
6215    
6216    #ifdef PRINTNOISE
6217        printf("Done scavenging the binding stack.\n");
6218    #endif
6219    /*    /*
6220     * Scavenge the scavenge_hooks in case this refers to a hook added     * Scavenge the scavenge_hooks in case this refers to a hook added
6221     * in a prior generation GC. From here on the scavenger_hook will     * in a prior generation GC. From here on the scavenger_hook will
# Line 5938  static void    garbage_collect_generation(i Line 6223  static void    garbage_collect_generation(i
6223     * doing here.     * doing here.
6224     */     */
6225    
6226    #ifdef PRINTNOISE
6227        printf("Scavenging the scavenger hooks ...\n");
6228    #endif
6229    scavenge((lispobj *) &scavenger_hooks, 1);    scavenge((lispobj *) &scavenger_hooks, 1);
6230    #ifdef PRINTNOISE
6231        printf("Done scavenging the scavenger hooks.\n");
6232    #endif
6233    
6234    if (SymbolValue(SCAVENGE_READ_ONLY_SPACE) != NIL) {    if (SymbolValue(SCAVENGE_READ_ONLY_SPACE) != NIL) {
6235      read_only_space_size = (lispobj *) SymbolValue(READ_ONLY_SPACE_FREE_POINTER)      read_only_space_size = (lispobj *) SymbolValue(READ_ONLY_SPACE_FREE_POINTER)
# Line 5978  static void    garbage_collect_generation(i Line 6269  static void    garbage_collect_generation(i
6269     */     */
6270    {    {
6271      int old_bytes_allocated = bytes_allocated;      int old_bytes_allocated = bytes_allocated;
6272      int bytes_allocated;      int bytes_allocated_diff;
6273    
6274      /* Start with a full scavenge */      /* Start with a full scavenge */
6275      scavenge_newspace_generation_one_scan(new_space);      scavenge_newspace_generation_one_scan(new_space);
# Line 5989  static void    garbage_collect_generation(i Line 6280  static void    garbage_collect_generation(i
6280      gc_alloc_update_page_tables(0, &boxed_region);      gc_alloc_update_page_tables(0, &boxed_region);
6281      gc_alloc_update_page_tables(1, &unboxed_region);      gc_alloc_update_page_tables(1, &unboxed_region);
6282    
6283      bytes_allocated = bytes_allocated - old_bytes_allocated;      bytes_allocated_diff = bytes_allocated - old_bytes_allocated;
6284    
6285      if (bytes_allocated != 0)      if (bytes_allocated_diff != 0)
6286        fprintf(stderr, "*** rescan of new_space allocated % more bytes?\n",        fprintf(stderr, "*** rescan of new_space allocated %d more bytes? (%ld vs %ld)\n",
6287                bytes_allocated);                bytes_allocated_diff, old_bytes_allocated, bytes_allocated);
6288    }    }
6289  #endif  #endif
6290    
# Line 6047  static void    garbage_collect_generation(i Line 6338  static void    garbage_collect_generation(i
6338  }  }
6339    
6340  /* Update last_free_page then ALLOCATION_POINTER */  /* Update last_free_page then ALLOCATION_POINTER */
6341  void    update_x86_dynamic_space_free_pointer(void)  void    update_dynamic_space_free_pointer(void)
6342  {  {
6343    int last_page = -1;    int last_page = -1;
6344    int i;    int i;
# Line 6058  void   update_x86_dynamic_space_free_point Line 6349  void   update_x86_dynamic_space_free_point
6349    
6350    last_free_page = last_page + 1;    last_free_page = last_page + 1;
6351    
6352    SetSymbolValue(ALLOCATION_POINTER,    set_alloc_pointer((lispobj) ((char *) heap_base + PAGE_SIZE * last_free_page));
                  (lispobj) ((char *) heap_base + PAGE_SIZE * last_free_page));  
6353  }  }
6354    
6355    
# Line 6188  void   collect_garbage(unsigned last_gen) Line 6478  void   collect_garbage(unsigned last_gen)
6478    gc_assert(boxed_region.free_pointer - boxed_region.start_addr == 0);    gc_assert(boxed_region.free_pointer - boxed_region.start_addr == 0);
6479    gc_alloc_generation = 0;    gc_alloc_generation = 0;
6480    
6481    update_x86_dynamic_space_free_pointer();    update_dynamic_space_free_pointer();
6482    
6483    SetSymbolValue(CURRENT_REGION_FREE_POINTER, (lispobj) boxed_region.free_pointer);    SetSymbolValue(CURRENT_REGION_FREE_POINTER, (lispobj) boxed_region.free_pointer);
6484    SetSymbolValue(CURRENT_REGION_END_ADDR, (lispobj) boxed_region.end_addr);    SetSymbolValue(CURRENT_REGION_END_ADDR, (lispobj) boxed_region.end_addr);
# Line 6301  void   gc_free_heap(void) Line 6591  void   gc_free_heap(void)
6591    unboxed_region.end_addr = page_address(0);    unboxed_region.end_addr = page_address(0);
6592    
6593    last_free_page = 0;    last_free_page = 0;
   SetSymbolValue(ALLOCATION_POINTER, (lispobj) heap_base);  
6594    
6595      set_alloc_pointer((lispobj) heap_base);
6596    
6597    SetSymbolValue(CURRENT_REGION_FREE_POINTER, (lispobj) boxed_region.free_pointer);    SetSymbolValue(CURRENT_REGION_FREE_POINTER, (lispobj) boxed_region.free_pointer);
6598    SetSymbolValue(CURRENT_REGION_END_ADDR, (lispobj) boxed_region.end_addr);    SetSymbolValue(CURRENT_REGION_END_ADDR, (lispobj) boxed_region.end_addr);
6599    
# Line 6395  void   gencgc_pickup_dynamic(void) Line 6686  void   gencgc_pickup_dynamic(void)
6686  {  {
6687    int page = 0;    int page = 0;
6688    int addr = DYNAMIC_0_SPACE_START;    int addr = DYNAMIC_0_SPACE_START;
6689    int alloc_ptr = SymbolValue(ALLOCATION_POINTER);    int alloc_ptr = get_alloc_pointer();
6690    
6691    /* Initialise the first region. */    /* Initialise the first region. */
6692    do {    do {
# Line 6443  void do_pending_interrupt(void); Line 6734  void do_pending_interrupt(void);
6734    
6735  int alloc_entered = 0;  int alloc_entered = 0;
6736    
6737  char *alloc(int nbytes)  char *
6738    alloc(int nbytes)
6739  {  {
6740    /* Check for alignment allocation problems. */    /* Check for alignment allocation problems. */
6741    gc_assert(((unsigned) SymbolValue(CURRENT_REGION_FREE_POINTER) & 0x7) == 0    gc_assert(((unsigned) SymbolValue(CURRENT_REGION_FREE_POINTER) & 0x7) == 0
# Line 6451  char *alloc(int nbytes) Line 6743  char *alloc(int nbytes)
6743    
6744    bytes_allocated_sum += nbytes;    bytes_allocated_sum += nbytes;
6745    
6746    if (SymbolValue(PSEUDO_ATOMIC_ATOMIC)) {    if (get_pseudo_atomic_atomic()) {
6747      /* Already within a pseudo atomic. */      /* Already within a pseudo atomic. */
6748      void *new_free_pointer;      void *new_free_pointer;
6749    
# Line 6475  char *alloc(int nbytes) Line 6767  char *alloc(int nbytes)
6767        auto_gc_trigger *= 2;        auto_gc_trigger *= 2;
6768        alloc_entered--;        alloc_entered--;
6769        /* Exit the pseudo atomic */        /* Exit the pseudo atomic */
6770        SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(0));        clr_pseudo_atomic_atomic();
6771        if (SymbolValue(PSEUDO_ATOMIC_INTERRUPTED) != 0)        if (get_pseudo_atomic_interrupted() != 0)
6772          /* Handle any interrupts that occurred during gc_alloc */          /* Handle any interrupts that occurred during gc_alloc */
6773          do_pending_interrupt();          do_pending_interrupt();
6774        funcall0(SymbolFunction(MAYBE_GC));        funcall0(SymbolFunction(MAYBE_GC));
6775        /* Re-enter the pseudo atomic. */        /* Re-enter the pseudo atomic. */
6776        SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, make_fixnum(0));        clr_pseudo_atomic_interrupted();
6777        SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(1));        set_pseudo_atomic_atomic();
6778        goto retry1;        goto retry1;
6779      }      }
6780      /* Call gc_alloc */      /* Call gc_alloc */
# Line 6512  char *alloc(int nbytes) Line 6804  char *alloc(int nbytes)
6804    retry2:    retry2:
6805      /* At least wrap this allocation in a pseudo atomic to prevent      /* At least wrap this allocation in a pseudo atomic to prevent
6806         gc_alloc from being re-entered. */         gc_alloc from being re-entered. */
6807      SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, make_fixnum(0));      clr_pseudo_atomic_interrupted();
6808      SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(1));      set_pseudo_atomic_atomic();
6809    
6810      if (alloc_entered++)      if (alloc_entered++)
6811        fprintf(stderr,"* Alloc re-entered\n");        fprintf(stderr,"* Alloc re-entered\n");
# Line 6527  char *alloc(int nbytes) Line 6819  char *alloc(int nbytes)
6819        SetSymbolValue(CURRENT_REGION_FREE_POINTER, (lispobj) new_free_pointer);        SetSymbolValue(CURRENT_REGION_FREE_POINTER, (lispobj) new_free_pointer);
6820    
6821        alloc_entered--;        alloc_entered--;
6822        SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(0));        clr_pseudo_atomic_atomic();
6823        if (SymbolValue(PSEUDO_ATOMIC_INTERRUPTED)) {        if (get_pseudo_atomic_interrupted()) {
6824          /* Handle any interrupts that occurred during gc_alloc */          /* Handle any interrupts that occurred during gc_alloc */
6825          do_pending_interrupt();          do_pending_interrupt();
6826          goto retry2;          goto retry2;
# Line 6541  char *alloc(int nbytes) Line 6833  char *alloc(int nbytes)
6833        auto_gc_trigger *= 2;        auto_gc_trigger *= 2;
6834        alloc_entered--;        alloc_entered--;
6835        /* Exit the pseudo atomic */        /* Exit the pseudo atomic */
6836        SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(0));        clr_pseudo_atomic_atomic();
6837        if (SymbolValue(PSEUDO_ATOMIC_INTERRUPTED) != 0)        if (get_pseudo_atomic_interrupted() != 0)
6838          /* Handle any interrupts that occurred during gc_alloc */          /* Handle any interrupts that occurred during gc_alloc */
6839          do_pending_interrupt();          do_pending_interrupt();
6840        funcall0(SymbolFunction(MAYBE_GC));        funcall0(SymbolFunction(MAYBE_GC));
# Line 6556  char *alloc(int nbytes) Line 6848  char *alloc(int nbytes)
6848      SetSymbolValue(CURRENT_REGION_END_ADDR, (lispobj) boxed_region.end_addr);      SetSymbolValue(CURRENT_REGION_END_ADDR, (lispobj) boxed_region.end_addr);
6849    
6850      alloc_entered--;      alloc_entered--;
6851      SetSymbolValue(PSEUDO_ATOMIC_ATOMIC, make_fixnum(0));      clr_pseudo_atomic_atomic();
6852      if (SymbolValue(PSEUDO_ATOMIC_INTERRUPTED) != 0) {      if (get_pseudo_atomic_interrupted() != 0) {
6853        /* Handle any interrupts that occurred during gc_alloc */        /* Handle any interrupts that occurred during gc_alloc */
6854        do_pending_interrupt();        do_pending_interrupt();
6855        goto retry2;        goto retry2;

Legend:
Removed from v.1.32  
changed lines
  Added in v.1.32.2.1

  ViewVC Help
Powered by ViewVC 1.1.5