[This patch has been reviewed over several iterations in
 [email protected]]

Hello Pietro.

OK.
Thanks for the patch.


> Boehm GC has a malloc_atomic function that doesn't clear the new
> allocation and doesn't scan it for pointers.
>
> Add a wrapper for the GC malloc_atomic in the run-time library and use it to
> allocate GC-collectable strings in the library.
>
> Change the lowering of malloc on the front end to select the run-time GC 
> malloc
> function to be used based on the mode having pointers or not.  Use leaf
> allocations for modes that are not refs or that don't contain refs.
>
> A boolean `has_refs' member was added to MOID_T and the computation of the
> atrribute is done by the parser when generating the mode list.
>
> gcc/algol68/ChangeLog:
>
>       * a68-low-clauses.cc (a68_lower_collateral_clause): Update
>       call to a68_lower_alloca.
>       * a68-low-coercions.cc (a68_lower_widening): Likewise.
>       * a68-low-generator.cc (allocator_t): Adjust typedef.
>       (fill_in_buffer): Adjust call to allocator.
>       (gen_mode): Likewise.
>       * a68-low-multiples.cc (a68_row_malloc): Change type parameter to MOID_T
>       from tree. Adjust call to a68_lower_malloc.
>       * a68-low-posix.cc (a68_posix_fgets): Adjust call to a68_row_malloc.
>       (a68_posix_gets): Likewise.
>       * a68-low-runtime.def (MALLOC_LEAF): Add definition for
>       _libga68_malloc_leaf.
>       * a68-low-strings.cc (a68_string_concat): Adjust call to
>       a68_lower_malloc.
>       (a68_string_from_char): Likewise.
>       * a68-low-units.cc (a68_lower_slice): Likewise.
>       * a68-low.cc (a68_low_dup): Adjust calls to a68_lower_malloc
>       and a68_lower_alloca.
>       (a68_lower_alloca): Change type parameter to MOID_T from tree.
>       (a68_lower_malloc): Likewise. Use _libga68_malloc_leaf if the MOID_T
>       doesn't have refs, use _libga68_malloc otherwise.
>       * a68-parser-modes.cc (a68_create_mode): Set has_refs on the new mode.
>       (is_mode_has_refs): New function.
>       (compute_derived_modes): Set has_refs on the chain of modes.
>       * a68-parser.cc (a68_new_moid):
>       * a68-types.h (struct MOID_T): Add member `has_refs`.
>       (HAS_REFS): New macro.
>       * a68.h (a68_row_malloc): Update prototype.
>       (a68_lower_alloca): Likewise.
>       (a68_lower_malloc): Likewise.
>
> libga68/ChangeLog:
>
>       * ga68-alloc.c (_libga68_malloc_leaf): New function.
>       * ga68-posix.c (_libga68_posixfgets): Use _libga68_malloc_leaf
>       instead of _libga68_malloc.
>       * ga68-unistr.c (_libga68_u32_to_u8): Likewise.
>       (_libga68_u8_to_u32): Likewise.
>       * ga68.h (_libga68_malloc_leaf): New prototype.
>       * ga68.map: Add _libga68_malloc_leaf to the global map.
>
> Signed-off-by: Pietro Monteiro <[email protected]>
> ---
>  gcc/algol68/a68-low-clauses.cc   |  3 ++-
>  gcc/algol68/a68-low-coercions.cc |  2 +-
>  gcc/algol68/a68-low-generator.cc |  6 +++---
>  gcc/algol68/a68-low-multiples.cc |  5 +++--
>  gcc/algol68/a68-low-posix.cc     |  4 ++--
>  gcc/algol68/a68-low-runtime.def  |  1 +
>  gcc/algol68/a68-low-strings.cc   |  4 ++--
>  gcc/algol68/a68-low-units.cc     |  2 +-
>  gcc/algol68/a68-low.cc           | 20 +++++++++++++-------
>  gcc/algol68/a68-parser-modes.cc  | 32 ++++++++++++++++++++++++++++++--
>  gcc/algol68/a68-parser.cc        |  1 +
>  gcc/algol68/a68-types.h          |  6 +++++-
>  gcc/algol68/a68.h                |  8 ++++----
>  libga68/ga68-alloc.c             | 15 +++++++++++++++
>  libga68/ga68-posix.c             |  4 ++--
>  libga68/ga68-unistr.c            |  8 ++++----
>  libga68/ga68.h                   |  1 +
>  libga68/ga68.map                 |  1 +
>  18 files changed, 91 insertions(+), 32 deletions(-)
>
> diff --git a/gcc/algol68/a68-low-clauses.cc b/gcc/algol68/a68-low-clauses.cc
> index 20ab22929bc..26607d7f422 100644
> --- a/gcc/algol68/a68-low-clauses.cc
> +++ b/gcc/algol68/a68-low-clauses.cc
> @@ -1246,6 +1246,7 @@ a68_lower_collateral_clause (NODE_T *p ATTRIBUTE_UNUSED,
>                 tree sub_multiple_elements = a68_multiple_elements 
> (sub_multiple);
>                 tree elements_pointer_type = TREE_TYPE 
> (sub_multiple_elements);
>                 tree elements_type = TREE_TYPE (elements_pointer_type);
> +               MOID_T *elements_moid = a68_type_moid (elements_type);
>                 multiple_elements_size = fold_build2 (MULT_EXPR, sizetype,
>                                                            size_int 
> (num_units),
>                                                            size_in_bytes 
> (elements_type));
> @@ -1254,7 +1255,7 @@ a68_lower_collateral_clause (NODE_T *p ATTRIBUTE_UNUSED,
>                                                       a68_multiple_num_elems 
> (sub_multiple));
>                 multiple_elements = a68_lower_tmpvar ("multiple_elements%",
>                                                       elements_pointer_type,
> -                                                     a68_lower_alloca 
> (elements_type,
> +                                                     a68_lower_alloca 
> (elements_moid,
>                                                                         
> multiple_elements_size));
>  
>                 /* We can also now calculate the bounds of the new multiple.
> diff --git a/gcc/algol68/a68-low-coercions.cc 
> b/gcc/algol68/a68-low-coercions.cc
> index b9e1acee9ce..3941917223f 100644
> --- a/gcc/algol68/a68-low-coercions.cc
> +++ b/gcc/algol68/a68-low-coercions.cc
> @@ -350,7 +350,7 @@ a68_lower_widening (NODE_T *p, LOW_CTX_T ctx)
>        /* First allocate space for the elements.  */
>        tree elements = a68_lower_tmpvar ("elements%",
>                                       pointer_to_bool_type,
> -                                     a68_lower_alloca (a68_bool_type,
> +                                     a68_lower_alloca (M_BOOL,
>                                                         fold_build2 
> (MULT_EXPR,
>                                                                      sizetype,
>                                                                      size_int 
> (bits_size),
> diff --git a/gcc/algol68/a68-low-generator.cc 
> b/gcc/algol68/a68-low-generator.cc
> index 5c4d65569b3..e321b7d5ec2 100644
> --- a/gcc/algol68/a68-low-generator.cc
> +++ b/gcc/algol68/a68-low-generator.cc
> @@ -43,7 +43,7 @@
>  #include "a68.h"
>  
>  
> -typedef tree (*allocator_t) (tree, tree);
> +typedef tree (*allocator_t) (MOID_T*, tree);
>  
>  /* Lower to code that fill in BOUNDS and elements pointers in the given 
> buffer
>     pointed by BUFFER at offset OFFSET according to the mode MODE, and evals 
> to
> @@ -205,7 +205,7 @@ fill_in_buffer (tree buffer, tree offset, 
> tree_stmt_iterator *bounds, MOID_T *m,
>        MOID_T *elem_mode = SUB (m);
>        tree elem_size = fold_convert (sizetype, size_in_bytes (CTYPE 
> (elem_mode)));
>        tree elems_size = save_expr (fold_build2 (MULT_EXPR, sizetype, 
> elem_size, num_elems));
> -      tree elemsptr = (*allocator) (CTYPE (elem_mode), elems_size);
> +      tree elemsptr = (*allocator) (elem_mode, elems_size);
>        elemsptr = save_expr (elemsptr);
>  
>        /* And initialize them.  */
> @@ -337,7 +337,7 @@ static tree
>  gen_mode (MOID_T *m, tree_stmt_iterator *bounds, allocator_t allocator)
>  {
>    /* Allocate space for the value and fill it.  */
> -  tree buffer = (*allocator) (CTYPE (m), size_in_bytes (CTYPE (m)));
> +  tree buffer = (*allocator) (m, size_in_bytes (CTYPE (m)));
>    buffer = save_expr (buffer);
>    return fill_in_buffer (buffer, size_zero_node, bounds, m, allocator);
>  }
> diff --git a/gcc/algol68/a68-low-multiples.cc 
> b/gcc/algol68/a68-low-multiples.cc
> index 572162e30ac..bcaa4c28074 100644
> --- a/gcc/algol68/a68-low-multiples.cc
> +++ b/gcc/algol68/a68-low-multiples.cc
> @@ -1074,16 +1074,17 @@ a68_multiple_bounds_check_equal (NODE_T *p, tree m1, 
> tree m2)
>     *LOWER_BOUND and *UPPER_BOUND are the bounds for the DIM dimensions.  */
>  
>  tree
> -a68_row_malloc (tree type, int dim, tree elems, tree elems_size,
> +a68_row_malloc (MOID_T *m, int dim, tree elems, tree elems_size,
>               tree *lower_bound, tree *upper_bound)
>  {
> +  tree type = CTYPE (m);
>    tree ptr_to_type = build_pointer_type (type);
>  
>    a68_push_range (NULL);
>  
>    /* Allocate space for the descriptor.  */
>    tree ptr_to_multiple = a68_lower_tmpvar ("ptr_to_multiple%", ptr_to_type,
> -                                        a68_lower_malloc (type, 
> size_in_bytes (type)));
> +                                        a68_lower_malloc (m, size_in_bytes 
> (type)));
>    tree multiple = a68_row_value (type, dim,
>                                elems, elems_size,
>                                lower_bound, upper_bound);
> diff --git a/gcc/algol68/a68-low-posix.cc b/gcc/algol68/a68-low-posix.cc
> index 1a9d5eb1b63..c0fd947fdb4 100644
> --- a/gcc/algol68/a68-low-posix.cc
> +++ b/gcc/algol68/a68-low-posix.cc
> @@ -503,7 +503,7 @@ a68_posix_fgets (void)
>        tree upper_bound = fold_convert (ssizetype, len);
>        tree elems_size = fold_build2 (MULT_EXPR, sizetype,
>                                    len, size_in_bytes (a68_char_type));
> -      tree body = a68_row_malloc (CTYPE (M_STRING), 1 /* dim */,
> +      tree body = a68_row_malloc (M_STRING, 1 /* dim */,
>                                 elems, elems_size,
>                                 &lower_bound, &upper_bound);
>        a68_pop_function_range (body);
> @@ -545,7 +545,7 @@ a68_posix_gets (void)
>        tree upper_bound = fold_convert (ssizetype, len);
>        tree elems_size = fold_build2 (MULT_EXPR, sizetype,
>                                    len, size_in_bytes (a68_char_type));
> -      tree body = a68_row_malloc (CTYPE (M_STRING), 1 /* dim */,
> +      tree body = a68_row_malloc (M_STRING, 1 /* dim */,
>                                 elems, elems_size,
>                                 &lower_bound, &upper_bound);
>        a68_pop_function_range (body);
> diff --git a/gcc/algol68/a68-low-runtime.def b/gcc/algol68/a68-low-runtime.def
> index ecb8553238d..326e4d00bc9 100644
> --- a/gcc/algol68/a68-low-runtime.def
> +++ b/gcc/algol68/a68-low-runtime.def
> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
>  
>  DEF_A68_RUNTIME (ASSERT, "_libga68_assert", RT(VOID), P2(CONSTCHARPTR, 
> UINT), ECF_NORETURN)
>  DEF_A68_RUNTIME (MALLOC, "_libga68_malloc", RT(VOIDPTR), P1(SIZE), 
> ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
> +DEF_A68_RUNTIME (MALLOC_LEAF, "_libga68_malloc_leaf", RT(VOIDPTR), P1(SIZE), 
> ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
>  DEF_A68_RUNTIME (DEREFNIL, "_libga68_derefnil", RT(VOID), P2(CONSTCHARPTR, 
> UINT), ECF_NORETURN)
>  DEF_A68_RUNTIME (UNREACHABLE, "_libga68_unreachable", RT(VOID), 
> P2(CONSTCHARPTR, UINT), ECF_NORETURN)
>  DEF_A68_RUNTIME (INVALIDCHARERROR, "_libga68_invalidcharerror", RT(VOID), 
> P3(CONSTCHARPTR,UINT,INT), ECF_NORETURN)
> diff --git a/gcc/algol68/a68-low-strings.cc b/gcc/algol68/a68-low-strings.cc
> index f5822037e33..5af83bf944d 100644
> --- a/gcc/algol68/a68-low-strings.cc
> +++ b/gcc/algol68/a68-low-strings.cc
> @@ -149,7 +149,7 @@ a68_string_concat (tree str1, tree str2)
>                                       size_in_bytes (a68_char_type),
>                                       num_elems);
>        tree elements = a68_lower_tmpvar ("elements%", char_pointer_type,
> -                                     a68_lower_malloc (a68_char_type, 
> elements_size));
> +                                     a68_lower_malloc (M_CHAR, 
> elements_size));
>  
>        /* Copy elements.  */
>        tree to_index = a68_lower_tmpvar ("to_index%", sizetype, 
> size_zero_node);
> @@ -234,7 +234,7 @@ a68_string_from_char (tree c)
>    a68_push_range (M_STRING);
>  
>    tree elements = a68_lower_tmpvar ("elements%", char_pointer_type,
> -                                 a68_lower_malloc (a68_char_type,
> +                                 a68_lower_malloc (M_CHAR,
>                                                     size_one_node));
>    a68_add_stmt (fold_build2 (MODIFY_EXPR,
>                            void_type_node,
> diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc
> index 9802468873b..caaa5bb27ac 100644
> --- a/gcc/algol68/a68-low-units.cc
> +++ b/gcc/algol68/a68-low-units.cc
> @@ -778,7 +778,7 @@ a68_lower_slice (NODE_T *p, LOW_CTX_T ctx)
>       {
>         tree ptrtype = CTYPE (orig_sliced_multiple_mode);
>         tree slice_addr = fold_build1 (ADDR_EXPR, ptrtype, slice);
> -       tree alloc = a68_lower_malloc (ptrtype, size_in_bytes (TREE_TYPE 
> (slice)));
> +       tree alloc = a68_lower_malloc (orig_sliced_multiple_mode, 
> size_in_bytes (TREE_TYPE (slice)));
>         alloc = save_expr (alloc);
>         tree copy = a68_lower_memcpy (alloc, slice_addr, size_in_bytes 
> (TREE_TYPE (slice)));
>  
> diff --git a/gcc/algol68/a68-low.cc b/gcc/algol68/a68-low.cc
> index ac603ef13e7..d13e28a0fc8 100644
> --- a/gcc/algol68/a68-low.cc
> +++ b/gcc/algol68/a68-low.cc
> @@ -741,12 +741,14 @@ a68_low_dup (tree expr, bool use_heap)
>        tree element_pointer_type = TREE_TYPE (elements);
>        tree element_type = TREE_TYPE (element_pointer_type);
>        tree new_elements_size = save_expr (a68_multiple_elements_size (expr));
> +      tree new_elements_type = TREE_TYPE (TREE_TYPE (elements));
> +      MOID_T *new_elements_moid = a68_type_moid (new_elements_type);
>        tree new_elements = a68_lower_tmpvar ("new_elements%",
>                                           TREE_TYPE (elements),
>                                           (use_heap
> -                                          ? a68_lower_malloc (TREE_TYPE 
> (TREE_TYPE (elements)),
> +                                          ? a68_lower_malloc 
> (new_elements_moid,
>                                                                
> new_elements_size)
> -                                          : a68_lower_alloca (TREE_TYPE 
> (TREE_TYPE (elements)),
> +                                          : a68_lower_alloca 
> (new_elements_moid,
>                                                                
> new_elements_size)));
>  
>        /* Then copy the elements.
> @@ -1110,8 +1112,9 @@ a68_lower_memcpy (tree dst, tree src, tree size)
>     pointer to it.  */
>  
>  tree
> -a68_lower_alloca (tree type, tree size)
> +a68_lower_alloca (MOID_T *m, tree size)
>  {
> +  tree type = CTYPE (m);
>    tree call = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
>    call = build_call_expr_loc (UNKNOWN_LOCATION, call, 2,
>                             size,
> @@ -1121,14 +1124,17 @@ a68_lower_alloca (tree type, tree size)
>  }
>  
>  
> -/* Build a tree that allocates SIZE bytes on the heap and returns a *TYPE
> -   pointer to it.  */
> +/* Build a tree that allocates SIZE bytes on the heap and returns a pointer 
> to
> +   a tree with type equivalent to mode M.  */
>  
>  tree
> -a68_lower_malloc (tree type, tree size)
> +a68_lower_malloc (MOID_T *m, tree size)
>  {
> +  tree type = CTYPE (m);
> +  a68_libcall_fn libcall
> +    = (HAS_REFS (m) || HAS_ROWS (m)) ? A68_LIBCALL_MALLOC : 
> A68_LIBCALL_MALLOC_LEAF;
>    return fold_convert (build_pointer_type (type),
> -                    a68_build_libcall (A68_LIBCALL_MALLOC, ptr_type_node,
> +                    a68_build_libcall (libcall, ptr_type_node,
>                                         1, size));
>  }
>  
> diff --git a/gcc/algol68/a68-parser-modes.cc b/gcc/algol68/a68-parser-modes.cc
> index 6b96fa2033b..5842d1325f0 100644
> --- a/gcc/algol68/a68-parser-modes.cc
> +++ b/gcc/algol68/a68-parser-modes.cc
> @@ -175,6 +175,7 @@ a68_create_mode (int att, int dim, NODE_T *node, MOID_T 
> *sub, PACK_T *pack)
>    DIM (new_mode) = dim;
>    NODE (new_mode) = node;
>    HAS_ROWS (new_mode) = (att == ROW_SYMBOL);
> +  HAS_REFS (new_mode) = (att == REF_SYMBOL);
>    SUB (new_mode) = sub;
>    PACK (new_mode) = pack;
>    NEXT (new_mode) = NO_MOID;
> @@ -1033,6 +1034,30 @@ is_mode_has_row (MOID_T *m)
>      return (HAS_ROWS (m) || IS_ROW (m) || IS_FLEX (m));
>  }
>  
> +/* Whether mode has ref.  */
> +
> +static bool
> +is_mode_has_refs (MOID_T *m)
> +{
> +  if (IS_ROW (m) || IS_FLEX (m))
> +    {
> +      HAS_REFS (m) = is_mode_has_refs (SUB (m));
> +      return HAS_REFS (m);
> +    }
> +  else if (IS_STRUCT (m) || IS_UNION (m))
> +    {
> +      bool has_refs = false;
> +      for (PACK_T *p = PACK (m); p != NO_PACK; FORWARD (p))
> +     {
> +       HAS_REFS (MOID (p)) = is_mode_has_refs (MOID (p));
> +       has_refs |= HAS_REFS (MOID (p));
> +     }
> +      return has_refs;
> +    }
> +  else
> +    return HAS_REFS (m);
> +}
> +
>  /* Compute derived modes.  */
>  
>  static void
> @@ -1181,9 +1206,12 @@ compute_derived_modes (MODULE_T *mod)
>  
>    gcc_assert (M_STRING == M_FLEX_ROW_CHAR);
>  
> -  /* Find out what modes contain rows.  */
> +  /* Find out what modes contain rows, and refs.  */
>    for (z = TOP_MOID (mod); z != NO_MOID; FORWARD (z))
> -    HAS_ROWS (z) = is_mode_has_row (z);
> +    {
> +      HAS_ROWS (z) = is_mode_has_row (z);
> +      HAS_REFS (z) = is_mode_has_refs (z);
> +    }
>  
>    /* Check flexible modes.  */
>    for (z = TOP_MOID (mod); z != NO_MOID; FORWARD (z))
> diff --git a/gcc/algol68/a68-parser.cc b/gcc/algol68/a68-parser.cc
> index 725a8fc44de..1504e4dc25b 100644
> --- a/gcc/algol68/a68-parser.cc
> +++ b/gcc/algol68/a68-parser.cc
> @@ -726,6 +726,7 @@ a68_new_moid (void)
>    DIM (z) = 0;
>    USE (z) = false;
>    HAS_ROWS (z) = false;
> +  HAS_REFS (z) = false;
>    PORTABLE (z) = true;
>    DERIVATE (z) = false;
>    NODE (z) = NO_NODE;
> diff --git a/gcc/algol68/a68-types.h b/gcc/algol68/a68-types.h
> index 788e7230f92..f18d3501799 100644
> --- a/gcc/algol68/a68-types.h
> +++ b/gcc/algol68/a68-types.h
> @@ -187,6 +187,9 @@ struct GTY((chain_next ("%h.more"), chain_prev 
> ("%h.less"))) KEYWORD_T
>     HAS_ROWS is true if the mode contains rows somewhere in its internal
>     structure.
>  
> +   HAS_REFS is true if the mode contains refs somewhere in its internal
> +   structure.
> +
>     The interpretation of SUB depends on the kind of mode:
>     - For REF modes it is the referred mode.
>     - For FLEX modes it is the referred mode.
> @@ -244,7 +247,7 @@ struct GTY((chain_next ("%h.next"))) MOID_T
>    int number;
>    int attribute;
>    int dim;
> -  bool has_rows, use, portable, derivate;
> +  bool has_rows, has_refs, use, portable, derivate;
>    NODE_T *node;
>    PACK_T *pack;
>    MOID_T *sub, *equivalent_mode, *slice, *deflexed_mode, *name, 
> *multiple_mode, *next, *rowed, *trim;
> @@ -950,6 +953,7 @@ struct GTY(()) A68_T
>  #define GREEN(p) ((p)->green)
>  #define H(p) ((p)->h)
>  #define HANDLE(p) ((p)->handle)
> +#define HAS_REFS(p) ((p)->has_refs)
>  #define HAS_ROWS(p) ((p)->has_rows)
>  #define HEAP(p) ((p)->heap)
>  #define ID(p) ((p)->id)
> diff --git a/gcc/algol68/a68.h b/gcc/algol68/a68.h
> index 7c6d51bd064..34090d12c05 100644
> --- a/gcc/algol68/a68.h
> +++ b/gcc/algol68/a68.h
> @@ -699,9 +699,9 @@ tree a68_row_value (tree type, size_t dim,
>                   tree *lower_bound, tree *upper_bound);
>  tree a68_row_value_raw (tree type, tree descriptor,
>                       tree elements, tree elements_size);
> -tree a68_row_malloc (tree type, int dim,
> +tree a68_row_malloc (MOID_T *m, int dim,
>                   tree elements, tree elements_size,
> -                 tree *lower_bound, tree *upper_bound);                   
> +                 tree *lower_bound, tree *upper_bound);
>  tree a68_multiple_slice (NODE_T *p, tree multiple, bool slicing_name,
>                        int num_indexes, tree *indexes);
>  tree a68_multiple_copy_elems (MOID_T *to_mode, tree to, tree from);
> @@ -815,8 +815,8 @@ tree a68_get_skip_tree (MOID_T *m);
>  tree a68_get_empty (void);
>  void a68_ref_counts (tree exp, MOID_T *m, int *num_refs, int *num_pointers);
>  tree a68_consolidate_ref (MOID_T *m, tree expr);
> -tree a68_lower_alloca (tree type, tree size);
> -tree a68_lower_malloc (tree type, tree size);
> +tree a68_lower_alloca (MOID_T *m, tree size);
> +tree a68_lower_malloc (MOID_T *m, tree size);
>  tree a68_checked_indirect_ref (NODE_T *p, tree exp, MOID_T *exp_mode);
>  tree a68_low_deref (tree exp, NODE_T *p);
>  tree a68_low_dup (tree exp, bool use_heap = false);
> diff --git a/libga68/ga68-alloc.c b/libga68/ga68-alloc.c
> index 1a0b25a098c..df8a8956c52 100644
> --- a/libga68/ga68-alloc.c
> +++ b/libga68/ga68-alloc.c
> @@ -80,6 +80,15 @@ _libga68_malloc (size_t size)
>    return res;
>  }
>  
> +void *
> +_libga68_malloc_leaf (size_t size)
> +{
> +  void *res = (void *) GC_MALLOC_ATOMIC (size);
> +  if (!res)
> +    _libga68_abort ("Virtual memory exhausted\n");
> +  return res;
> +}
> +
>  #else
>  
>  void
> @@ -112,4 +121,10 @@ _libga68_malloc (size_t size)
>    return res;
>  }
>  
> +void *
> +_libga68_malloc_leaf (size_t size)
> +{
> +  return _libga68_malloc (size);
> +}
> +
>  #endif /* !LIBGA68_WITH_GC */
> diff --git a/libga68/ga68-posix.c b/libga68/ga68-posix.c
> index a671dd61d16..b6fba202497 100644
> --- a/libga68/ga68-posix.c
> +++ b/libga68/ga68-posix.c
> @@ -322,7 +322,7 @@ _libga68_posixfgets (int fd, int nchars, size_t *len)
>    if (nchars > 0)
>      {
>        /* Read exactly nchar or until EOF.  */
> -      res = _libga68_malloc (nchars * sizeof (uint32_t));
> +      res = _libga68_malloc_leaf (nchars * sizeof (uint32_t));
>        do
>       {
>         uc = _libga68_posixfgetc (fd);
> @@ -336,7 +336,7 @@ _libga68_posixfgets (int fd, int nchars, size_t *len)
>      {
>        /* Read until newline or EOF.  */
>        size_t allocated = 80 * sizeof (uint32_t);
> -      res = _libga68_malloc (allocated);
> +      res = _libga68_malloc_leaf (allocated);
>        do
>       {
>         uc = _libga68_posixfgetc (fd);
> diff --git a/libga68/ga68-unistr.c b/libga68/ga68-unistr.c
> index 2cdf732a6b2..2a71313c181 100644
> --- a/libga68/ga68-unistr.c
> +++ b/libga68/ga68-unistr.c
> @@ -363,7 +363,7 @@ _libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t 
> stride,
>            if (length + 6 > allocated)
>              allocated = length + 6;
>            if (result == resultbuf || result == NULL)
> -         memory = (uint8_t *) _libga68_malloc (allocated * sizeof (uint8_t));
> +         memory = (uint8_t *) _libga68_malloc_leaf (allocated * sizeof 
> (uint8_t));
>            else
>           memory =
>             (uint8_t *) _libga68_realloc (result, allocated * sizeof 
> (uint8_t));
> @@ -384,7 +384,7 @@ _libga68_u32_to_u8 (const uint32_t *s, size_t n, size_t 
> stride,
>        if (result == NULL)
>          {
>            /* Return a non-NULL value.  NULL means error.  */
> -          result = (uint8_t *) _libga68_malloc (1);
> +       result = (uint8_t *) _libga68_malloc_leaf (1);
>            if (result == NULL)
>              {
>                errno = ENOMEM;
> @@ -580,7 +580,7 @@ _libga68_u8_to_u32 (const uint8_t *s, size_t n, uint32_t 
> *resultbuf, size_t *len
>            if (length + 1 > allocated)
>              allocated = length + 1;
>            if (result == resultbuf || result == NULL)
> -         memory = (uint32_t *) _libga68_malloc (allocated * sizeof 
> (uint32_t));
> +         memory = (uint32_t *) _libga68_malloc_leaf (allocated * sizeof 
> (uint32_t));
>            else
>           memory =
>             (uint32_t *) _libga68_realloc (result, allocated * sizeof 
> (uint32_t));
> @@ -598,7 +598,7 @@ _libga68_u8_to_u32 (const uint8_t *s, size_t n, uint32_t 
> *resultbuf, size_t *len
>        if (result == NULL)
>          {
>            /* Return a non-NULL value.  NULL means error.  */
> -          result = (uint32_t *) _libga68_malloc (1);
> +       result = (uint32_t *) _libga68_malloc_leaf (1);
>          }
>      }
>    else if (result != resultbuf && length < allocated)
> diff --git a/libga68/ga68.h b/libga68/ga68.h
> index 008ce05282a..8d1cf20c162 100644
> --- a/libga68/ga68.h
> +++ b/libga68/ga68.h
> @@ -70,6 +70,7 @@ void _libga68_bounds_mismatch (const char *filename, 
> unsigned int lineno,
>  
>  void _libga68_init_heap (void) GA68_HIDDEN;
>  void *_libga68_malloc (size_t size);
> +void *_libga68_malloc_leaf (size_t size);
>  void *_libga68_malloc_internal (size_t size) GA68_HIDDEN;
>  void *_libga68_realloc (void *ptr, size_t size) GA68_HIDDEN;
>  void *_libga68_realloc_unchecked (void *ptr, size_t size) GA68_HIDDEN;
> diff --git a/libga68/ga68.map b/libga68/ga68.map
> index 6917e7905ae..6ee93228358 100644
> --- a/libga68/ga68.map
> +++ b/libga68/ga68.map
> @@ -11,6 +11,7 @@ LIBGA68_2.0 {
>      _libga68_longrandom;
>      _libga68_lower_bound;
>      _libga68_malloc;
> +    _libga68_malloc_leaf;
>      _libga68_posixargc;
>      _libga68_posixargv;
>      _libga68_posixclose;
>
> base-commit: 1c06e68228226a723e97687be62f06e373b40b3a

Reply via email to