public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-jankratochvil-type-refcount: merge 5d5a30795cd5cafdbc99b11344de86ead535b776
@ 2008-12-15  0:33 jkratoch
  0 siblings, 0 replies; only message in thread
From: jkratoch @ 2008-12-15  0:33 UTC (permalink / raw)
  To: archer-commits

The branch, archer-jankratochvil-type-refcount has been updated
       via  250db25a0345574717bdbb2c95ec4d28972df8cb (commit)
       via  99bb72c6e4f47b898863446510de72a60b693d17 (commit)
       via  01546ee201a0997affba334011df98307a611890 (commit)
       via  d1ff02440097bc93c2a4c1f8867dea2ffcb1b552 (commit)
      from  17ec07b78f28e400d2e839d732abc94a6cb3ae2f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 250db25a0345574717bdbb2c95ec4d28972df8cb
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Dec 15 01:24:46 2008 +0100

    merge 5d5a30795cd5cafdbc99b11344de86ead535b776

commit 99bb72c6e4f47b898863446510de72a60b693d17
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Dec 15 01:18:29 2008 +0100

    merge 97c867eb4023181294200de2f15111dc425ed93b

commit 01546ee201a0997affba334011df98307a611890
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Dec 15 01:17:06 2008 +0100

    merge c608cbbc9fc946922eafad36d63e841a31ed0fbe

commit d1ff02440097bc93c2a4c1f8867dea2ffcb1b552
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Dec 15 01:13:07 2008 +0100

    merge 1602a8f317a3c80926162137f3ef9d88369edfe9

-----------------------------------------------------------------------

Summary of changes:
 gdb/ada-lang.c   |   23 ++--
 gdb/coffread.c   |    2 +-
 gdb/dwarf2read.c |    8 +-
 gdb/gdbtypes.c   |  346 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 gdb/gdbtypes.h   |    6 +-
 gdb/jv-lang.c    |    2 +-
 gdb/mdebugread.c |    2 +-
 gdb/stabsread.c  |    4 +-
 gdb/valops.c     |    4 -
 gdb/value.c      |   38 +++++--
 10 files changed, 370 insertions(+), 65 deletions(-)

First 500 lines of diff:
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 1dc3c88..f469225 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -1666,8 +1666,8 @@ ada_type_of_array (struct value *arr, int bounds)
         return NULL;
       while (arity > 0)
         {
-          struct type *range_type = alloc_type (objf);
-          struct type *array_type = alloc_type (objf);
+          struct type *range_type = alloc_type (objf, NULL);
+          struct type *array_type = alloc_type (objf, NULL);
           struct value *low = desc_one_bound (descriptor, arity, 0);
           struct value *high = desc_one_bound (descriptor, arity, 1);
           arity -= 1;
@@ -1774,9 +1774,9 @@ packed_array_type (struct type *type, long *elt_bits)
   if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
     return type;
 
-  new_type = alloc_type (TYPE_OBJFILE (type));
   new_elt_type = packed_array_type (ada_check_typedef (TYPE_TARGET_TYPE (type)),
                                     elt_bits);
+  new_type = alloc_type (TYPE_OBJFILE (type), new_elt_type);
   create_array_type (new_type, new_elt_type, TYPE_FIELD_TYPE (type, 0));
   TYPE_FIELD_BITSIZE (new_type, 0) = *elt_bits;
   TYPE_NAME (new_type) = ada_type_name (type);
@@ -6799,7 +6799,7 @@ variant_field_index (struct type *type)
 static struct type *
 empty_record (struct objfile *objfile)
 {
-  struct type *type = alloc_type (objfile);
+  struct type *type = alloc_type (objfile, NULL);
   TYPE_CODE (type) = TYPE_CODE_STRUCT;
   TYPE_NFIELDS (type) = 0;
   TYPE_FIELDS (type) = NULL;
@@ -6856,7 +6856,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
         nfields++;
     }
 
-  rtype = alloc_type (TYPE_OBJFILE (type));
+  rtype = alloc_type (TYPE_OBJFILE (type), NULL);
   TYPE_CODE (rtype) = TYPE_CODE_STRUCT;
   INIT_CPLUS_SPECIFIC (rtype);
   TYPE_NFIELDS (rtype) = nfields;
@@ -7035,7 +7035,8 @@ template_to_static_fixed_type (struct type *type0)
         new_type = static_unwrap_type (field_type);
       if (type == type0 && new_type != field_type)
         {
-          TYPE_TARGET_TYPE (type0) = type = alloc_type (TYPE_OBJFILE (type0));
+          TYPE_TARGET_TYPE (type0) = type = alloc_type (TYPE_OBJFILE (type0),
+							NULL);
           TYPE_CODE (type) = TYPE_CODE (type0);
           INIT_CPLUS_SPECIFIC (type);
           TYPE_NFIELDS (type) = nfields;
@@ -7080,7 +7081,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
   else
     dval = dval0;
 
-  rtype = alloc_type (TYPE_OBJFILE (type));
+  rtype = alloc_type (TYPE_OBJFILE (type), NULL);
   TYPE_CODE (rtype) = TYPE_CODE_STRUCT;
   INIT_CPLUS_SPECIFIC (rtype);
   TYPE_NFIELDS (rtype) = nfields;
@@ -7252,7 +7253,7 @@ to_fixed_array_type (struct type *type0, struct value *dval,
       if (elt_type0 == elt_type)
         result = type0;
       else
-        result = create_array_type (alloc_type (TYPE_OBJFILE (type0)),
+        result = create_array_type (alloc_type (TYPE_OBJFILE (type0), NULL),
                                     elt_type, TYPE_INDEX_TYPE (type0));
     }
   else
@@ -7282,7 +7283,7 @@ to_fixed_array_type (struct type *type0, struct value *dval,
           struct type *range_type =
             to_fixed_range_type (TYPE_FIELD_NAME (index_type_desc, i),
                                  dval, TYPE_OBJFILE (type0));
-          result = create_array_type (alloc_type (TYPE_OBJFILE (type0)),
+          result = create_array_type (alloc_type (TYPE_OBJFILE (type0), NULL),
                                       result, range_type);
         }
       if (!ignore_too_big && TYPE_LENGTH (result) > varsize_limit)
@@ -9547,7 +9548,7 @@ to_fixed_range_type (char *name, struct value *dval, struct objfile *objfile)
       if (L < INT_MIN || U > INT_MAX)
 	return raw_type;
       else
-	return create_range_type (alloc_type (objfile), raw_type, 
+	return create_range_type (alloc_type (objfile, NULL), raw_type, 
 				  discrete_type_low_bound (raw_type),
 				  discrete_type_high_bound (raw_type));
     }
@@ -9612,7 +9613,7 @@ to_fixed_range_type (char *name, struct value *dval, struct objfile *objfile)
 
       if (objfile == NULL)
         objfile = TYPE_OBJFILE (base_type);
-      type = create_range_type (alloc_type (objfile), base_type, L, U);
+      type = create_range_type (alloc_type (objfile, NULL), base_type, L, U);
       TYPE_NAME (type) = name;
       return type;
     }
diff --git a/gdb/coffread.c b/gdb/coffread.c
index 8697554..f561382 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -346,7 +346,7 @@ coff_alloc_type (int index)
      We will fill it in later if we find out how.  */
   if (type == NULL)
     {
-      type = alloc_type (current_objfile);
+      type = alloc_type (current_objfile, NULL);
       *type_addr = type;
     }
   return type;
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a6584c4..49e257e 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3882,7 +3882,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
   /* The name is already allocated along with this objfile, so we don't
      need to duplicate it for the type.  */
   fnp->physname = physname ? physname : "";
-  fnp->type = alloc_type (objfile);
+  fnp->type = alloc_type (objfile, NULL);
   this_type = read_type_die (die, cu);
   if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
     {
@@ -4066,7 +4066,7 @@ quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
     return NULL;
 
   domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
   smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
 			TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
 			TYPE_VARARGS (pfn_type));
@@ -4103,7 +4103,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   if (type)
     return type;
 
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
   INIT_CPLUS_SPECIFIC (type);
   name = dwarf2_name (die, cu);
   if (name != NULL)
@@ -4316,7 +4316,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
   const char *name;
 
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   name = dwarf2_full_name (die, cu);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 5b9d0e8..96a15f5 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -146,6 +146,23 @@ static void print_bit_vector (B_TYPE *, int);
 static void print_arg_types (struct field *, int, int);
 static void dump_fn_fieldlists (struct type *, int);
 static void print_cplus_stuff (struct type *, int);
+static void type_init_refc (struct type *new_type, struct type *parent_type);
+
+/* A reference count structure for the type reference count map.  Each
+   type in a hierarchy of types is mapped to the same reference
+   count.  */
+struct type_refc_entry
+{
+  /* One type in the hierarchy.  Each type in the hierarchy gets its
+     own slot.  */
+  struct type *type;
+
+  /* A pointer to the shared reference count.  */
+  int *refc;
+};
+
+/* The hash table holding all reference counts.  */
+static htab_t type_refc_table;
 
 
 /* Alloc a new type structure and fill it with some defaults.  If
@@ -154,7 +171,7 @@ static void print_cplus_stuff (struct type *, int);
    structure by xmalloc () (for permanent types).  */
 
 struct type *
-alloc_type (struct objfile *objfile)
+alloc_type (struct objfile *objfile, struct type *parent)
 {
   struct type *type;
 
@@ -184,6 +201,9 @@ alloc_type (struct objfile *objfile)
   TYPE_VPTR_FIELDNO (type) = -1;
   TYPE_CHAIN (type) = type;	/* Chain back to itself.  */
 
+  if (objfile == NULL)
+    type_init_refc (type, parent);
+
   return (type);
 }
 
@@ -213,6 +233,9 @@ alloc_type_instance (struct type *oldtype)
 
   TYPE_CHAIN (type) = type;	/* Chain back to itself for now.  */
 
+  if (TYPE_OBJFILE (oldtype) == NULL)
+    type_init_refc (type, oldtype);
+
   return (type);
 }
 
@@ -257,7 +280,7 @@ make_pointer_type (struct type *type, struct type **typeptr)
 
   if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
     {
-      ntype = alloc_type (TYPE_OBJFILE (type));
+      ntype = alloc_type (TYPE_OBJFILE (type), type);
       if (typeptr)
 	*typeptr = ntype;
     }
@@ -269,6 +292,9 @@ make_pointer_type (struct type *type, struct type **typeptr)
       smash_type (ntype);
       TYPE_CHAIN (ntype) = chain;
       TYPE_OBJFILE (ntype) = objfile;
+
+      /* Callers may only supply storage if there is an objfile.  */
+      gdb_assert (objfile);
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
@@ -337,7 +363,7 @@ make_reference_type (struct type *type, struct type **typeptr)
 
   if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
     {
-      ntype = alloc_type (TYPE_OBJFILE (type));
+      ntype = alloc_type (TYPE_OBJFILE (type), type);
       if (typeptr)
 	*typeptr = ntype;
     }
@@ -349,6 +375,9 @@ make_reference_type (struct type *type, struct type **typeptr)
       smash_type (ntype);
       TYPE_CHAIN (ntype) = chain;
       TYPE_OBJFILE (ntype) = objfile;
+
+      /* Callers may only supply storage if there is an objfile.  */
+      gdb_assert (objfile);
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
@@ -397,7 +426,7 @@ make_function_type (struct type *type, struct type **typeptr)
 
   if (typeptr == 0 || *typeptr == 0)	/* We'll need to allocate one.  */
     {
-      ntype = alloc_type (TYPE_OBJFILE (type));
+      ntype = alloc_type (TYPE_OBJFILE (type), type);
       if (typeptr)
 	*typeptr = ntype;
     }
@@ -407,6 +436,9 @@ make_function_type (struct type *type, struct type **typeptr)
       objfile = TYPE_OBJFILE (ntype);
       smash_type (ntype);
       TYPE_OBJFILE (ntype) = objfile;
+
+      /* Callers may only supply storage if there is an objfile.  */
+      gdb_assert (objfile);
     }
 
   TYPE_TARGET_TYPE (ntype) = type;
@@ -648,7 +680,7 @@ lookup_memberptr_type (struct type *type, struct type *domain)
 {
   struct type *mtype;
 
-  mtype = alloc_type (TYPE_OBJFILE (type));
+  mtype = alloc_type (TYPE_OBJFILE (type), NULL);
   smash_to_memberptr_type (mtype, domain, type);
   return (mtype);
 }
@@ -660,7 +692,7 @@ lookup_methodptr_type (struct type *to_type)
 {
   struct type *mtype;
 
-  mtype = alloc_type (TYPE_OBJFILE (to_type));
+  mtype = alloc_type (TYPE_OBJFILE (to_type), NULL);
   TYPE_TARGET_TYPE (mtype) = to_type;
   TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type);
   TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type);
@@ -702,7 +734,7 @@ create_range_type (struct type *result_type, struct type *index_type,
 {
   if (result_type == NULL)
     {
-      result_type = alloc_type (TYPE_OBJFILE (index_type));
+      result_type = alloc_type (TYPE_OBJFILE (index_type), index_type);
     }
   TYPE_CODE (result_type) = TYPE_CODE_RANGE;
   TYPE_TARGET_TYPE (result_type) = index_type;
@@ -812,8 +844,14 @@ create_array_type (struct type *result_type,
 
   if (result_type == NULL)
     {
-      result_type = alloc_type (TYPE_OBJFILE (range_type));
+      result_type = alloc_type (TYPE_OBJFILE (range_type), element_type);
     }
+  else
+    {
+      /* Callers may only supply storage if there is an objfile.  */
+      gdb_assert (TYPE_OBJFILE (result_type));
+    }
+
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
   if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
@@ -831,6 +869,7 @@ create_array_type (struct type *result_type,
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ALLOC (result_type, sizeof (struct field));
   memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
+  /* FIXME: type alloc.  */
   TYPE_FIELD_TYPE (result_type, 0) = range_type;
   TYPE_VPTR_FIELDNO (result_type) = -1;
 
@@ -873,7 +912,12 @@ create_set_type (struct type *result_type, struct type *domain_type)
 {
   if (result_type == NULL)
     {
-      result_type = alloc_type (TYPE_OBJFILE (domain_type));
+      result_type = alloc_type (TYPE_OBJFILE (domain_type), domain_type);
+    }
+  else
+    {
+      /* Callers may only supply storage if there is an objfile.  */
+      gdb_assert (TYPE_OBJFILE (result_type));
     }
   TYPE_CODE (result_type) = TYPE_CODE_SET;
   TYPE_NFIELDS (result_type) = 1;
@@ -1432,7 +1476,7 @@ check_typedef (struct type *type)
 	  if (sym)
 	    TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym);
 	  else					/* TYPE_CODE_UNDEF */
-	    TYPE_TARGET_TYPE (type) = alloc_type (NULL);
+	    TYPE_TARGET_TYPE (type) = alloc_type (NULL, NULL);
 	}
       type = TYPE_TARGET_TYPE (type);
     }
@@ -1765,7 +1809,7 @@ init_type (enum type_code code, int length, int flags,
 {
   struct type *type;
 
-  type = alloc_type (objfile);
+  type = alloc_type (objfile, NULL);
   TYPE_CODE (type) = code;
   TYPE_LENGTH (type) = length;
 
@@ -1800,9 +1844,9 @@ init_type (enum type_code code, int length, int flags,
       TYPE_NAME (type) = obsavestring (name, strlen (name), 
 				       &objfile->objfile_obstack);
     }
-  else
+  else if (name)
     {
-      TYPE_NAME (type) = name;
+      TYPE_NAME (type) = xstrdup (name);
     }
 
   /* C++ fancies.  */
@@ -1815,6 +1859,10 @@ init_type (enum type_code code, int length, int flags,
     {
       INIT_CPLUS_SPECIFIC (type);
     }
+
+  if (!objfile)
+    type_incref (type);
+
   return (type);
 }
 
@@ -2922,15 +2970,17 @@ create_copied_types_hash (struct objfile *objfile)
 			       dummy_obstack_deallocate);
 }
 
-/* Recursively copy (deep copy) TYPE, if it is associated with
-   OBJFILE.  Return a new type allocated using malloc, a saved type if
-   we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
-   not associated with OBJFILE.  */
+/* A helper for copy_type_recursive.  This does all the work.
+   REPRESENTATIVE is a pointer to a type.  This is used to register
+   newly-created types in the type_refc_table.  Initially it pointer
+   to a NULL pointer, but it is filled in the first time a type is
+   copied.  */
 
-struct type *
-copy_type_recursive (struct objfile *objfile, 
-		     struct type *type,
-		     htab_t copied_types)
+static struct type *
+copy_type_recursive_1 (struct objfile *objfile, 
+		       struct type *type,
+		       htab_t copied_types,
+		       struct type **representative)
 {
   struct type_pair *stored, pair;
   void **slot;
@@ -2948,7 +2998,9 @@ copy_type_recursive (struct objfile *objfile,
   if (*slot != NULL)
     return ((struct type_pair *) *slot)->new;
 
-  new_type = alloc_type (NULL);
+  new_type = alloc_type (NULL, *representative);
+  if (!*representative)
+    *representative = new_type;
 
   /* We must add the new type to the hash table immediately, in case
      we encounter this type again during a recursive call below.  */
@@ -2985,8 +3037,8 @@ copy_type_recursive (struct objfile *objfile,
 	  TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i);
 	  if (TYPE_FIELD_TYPE (type, i))
 	    TYPE_FIELD_TYPE (new_type, i)
-	      = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i),
-				     copied_types);
+	      = copy_type_recursive_1 (objfile, TYPE_FIELD_TYPE (type, i),
+				       copied_types, representative);
 	  if (TYPE_FIELD_NAME (type, i))
 	    TYPE_FIELD_NAME (new_type, i) = 
 	      xstrdup (TYPE_FIELD_NAME (type, i));
@@ -3016,14 +3068,16 @@ copy_type_recursive (struct objfile *objfile,
   /* Copy pointers to other types.  */
   if (TYPE_TARGET_TYPE (type))
     TYPE_TARGET_TYPE (new_type) = 
-      copy_type_recursive (objfile, 
-			   TYPE_TARGET_TYPE (type),
-			   copied_types);
+      copy_type_recursive_1 (objfile, 
+			     TYPE_TARGET_TYPE (type),
+			     copied_types,
+			     representative);
   if (TYPE_VPTR_BASETYPE (type))
     TYPE_VPTR_BASETYPE (new_type) = 
-      copy_type_recursive (objfile,
-			   TYPE_VPTR_BASETYPE (type),
-			   copied_types);
+      copy_type_recursive_1 (objfile,
+			     TYPE_VPTR_BASETYPE (type),
+			     copied_types,
+			     representative);
   /* Maybe copy the type_specific bits.
 
      NOTE drow/2005-12-09: We do not copy the C++-specific bits like
@@ -3041,6 +3095,21 @@ copy_type_recursive (struct objfile *objfile,
   return new_type;
 }
 
+/* Recursively copy (deep copy) TYPE, if it is associated with
+   OBJFILE.  Return a new type allocated using malloc, a saved type if
+   we have already visited TYPE (using COPIED_TYPES), or TYPE if it is
+   not associated with OBJFILE.  */
+
+struct type *
+copy_type_recursive (struct objfile *objfile, 
+		     struct type *type,
+		     htab_t copied_types)
+{
+  struct type *representative = NULL;
+
+  return copy_type_recursive_1 (objfile, type, copied_types, &representative);
+}
+
 /* Make a copy of the given TYPE, except that the pointer & reference
    types are not preserved.
    
@@ -3054,7 +3123,7 @@ copy_type (const struct type *type)
 
   gdb_assert (TYPE_OBJFILE (type) != NULL);
 
-  new_type = alloc_type (TYPE_OBJFILE (type));
+  new_type = alloc_type (TYPE_OBJFILE (type), NULL);
   TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
   TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
   memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
@@ -3063,6 +3132,218 @@ copy_type (const struct type *type)
   return new_type;
 }
 
+/* Allocate a hash table which is used when freeing a struct type.  */
+
+static htab_t
+create_deleted_types_hash (void)
+{
+  return htab_create (1, htab_hash_pointer, htab_eq_pointer, NULL);
+}
+
+static void delete_type_recursive (struct type *type, htab_t deleted_types);
+
+/* A helper for delete_type_recursive which deletes a main_type and
+   the things to which it refers.  TYPE is a type whose main_type we
+   wish to destroy.  DELETED_TYPES is a hash holding already-seen
+   pointers; see delete_type_recursive.  */
+
+static void
+delete_main_type (struct type *type, htab_t deleted_types)
+{
+  int i;
+  void **slot;
+
+  if (!type)


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-12-15  0:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-12-15  0:33 [SCM] archer-jankratochvil-type-refcount: merge 5d5a30795cd5cafdbc99b11344de86ead535b776 jkratoch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).