[Define 0/1 if .init_array/.fini_array sections are available and working.])
])
+dnl Check whether the host supports symbol aliases.
+AC_DEFUN([gcc_CHECK_ATTRIBUTE_ALIAS], [
+ AC_CACHE_CHECK([whether the host/build supports symbol aliases],
+ gcc_cv_have_attribute_alias, [
+ if test "x${build}" = "x${host}"; then
+ AC_TRY_LINK([
+extern "C" void foo(void) { }
+extern void bar(void) __attribute__((alias("foo")));],
+ [bar();], gcc_cv_have_attribute_alias=yes, gcc_cv_have_attribute_alias=no)
+ else
+ gcc_cv_have_attribute_alias=no
+ fi])
+ if test $gcc_cv_have_attribute_alias = yes; then
+ AC_DEFINE(HAVE_ATTRIBUTE_ALIAS, 1,
+ [Define to 1 if the host/build supports __attribute__((alias(...))).])
+ fi])
+
dnl # gcc_GAS_FLAGS
dnl # Used by gcc_GAS_CHECK_FEATURE
dnl #
#endif
+/* Define to 1 if the host/build supports __attribute__((alias(...))). */
+#ifndef USED_FOR_TARGET
+#undef HAVE_ATTRIBUTE_ALIAS
+#endif
+
+
/* Define to 1 if you have the Mac OS X function
CFLocaleCopyPreferredLanguages in the CoreFoundation framework. */
#ifndef USED_FOR_TARGET
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the host/build supports symbol aliases" >&5
+$as_echo_n "checking whether the host/build supports symbol aliases... " >&6; }
+if ${gcc_cv_have_attribute_alias+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ if test "x${build}" = "x${host}"; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+extern "C" void foo(void) { }
+extern void bar(void) __attribute__((alias("foo")));
+int
+main ()
+{
+bar();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ gcc_cv_have_attribute_alias=yes
+else
+ gcc_cv_have_attribute_alias=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ else
+ gcc_cv_have_attribute_alias=no
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_have_attribute_alias" >&5
+$as_echo "$gcc_cv_have_attribute_alias" >&6; }
+ if test $gcc_cv_have_attribute_alias = yes; then
+
+$as_echo "#define HAVE_ATTRIBUTE_ALIAS 1" >>confdefs.h
+
+ fi
+
# Some assemblers (GNU as for LoongArch) generates relocations for
# leb128 symbol arithmetic for relaxation, we need to disable relaxation
# probing leb128 support then.
gcc_AC_INITFINI_ARRAY
+gcc_CHECK_ATTRIBUTE_ALIAS
+
# Some assemblers (GNU as for LoongArch) generates relocations for
# leb128 symbol arithmetic for relaxation, we need to disable relaxation
# probing leb128 support then.
/* Stubs for GGC referenced through instantiations triggered by hash-map. */
-void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
- size_t, size_t MEM_STAT_DECL)
+void *
+ggc_internal_cleared_alloc (size_t, void (*)(void *),
+ size_t, size_t MEM_STAT_DECL)
{
return NULL;
}
-void ggc_free (void *)
+
+void *
+ggc_internal_cleared_alloc_no_dtor (size_t, void (*)(void *),
+ size_t, size_t MEM_STAT_DECL)
+{
+ return NULL;
+}
+
+void
+ggc_free (void *)
{
}
}
/* Allocate a block of memory, then clear it. */
+#ifdef HAVE_ATTRIBUTE_ALIAS
+extern "C" void *
+ggc_internal_cleared_alloc_ (size_t size, void (*f)(void *), size_t s, size_t n
+ MEM_STAT_DECL)
+{
+ void *buf = ggc_internal_alloc (size, f, s, n PASS_MEM_STAT);
+ memset (buf, 0, size);
+ return buf;
+}
+
+extern void *
+ggc_internal_cleared_alloc (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_cleared_alloc_")));
+extern void *
+ggc_internal_cleared_alloc_no_dtor (size_t size, void (*f)(void *),
+ size_t s, size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_cleared_alloc_")));
+#else
void *
ggc_internal_cleared_alloc (size_t size, void (*f)(void *), size_t s, size_t n
MEM_STAT_DECL)
return buf;
}
+#ifdef __GNUC__
+__attribute__ ((__noinline__))
+#endif
+void *
+ggc_internal_cleared_alloc_no_dtor (size_t size, void (*f)(void *),
+ size_t s, size_t n MEM_STAT_DECL)
+{
+ return ggc_internal_cleared_alloc (s, f, s, n PASS_MEM_STAT);
+}
+#endif
+
/* Resize a block of memory, possibly re-allocating it. */
void *
ggc_realloc (void *x, size_t size MEM_STAT_DECL)
return requested_size;
}
+#ifdef HAVE_ATTRIBUTE_ALIAS
+extern "C" void *
+ggc_internal_alloc_ (size_t size, void (*f)(void *), size_t, size_t
+ MEM_STAT_DECL)
+{
+ gcc_assert (!f); // ggc-none doesn't support finalizers
+ return xmalloc (size);
+}
+
+extern "C" void *
+ggc_internal_cleared_alloc_ (size_t size, void (*f)(void *), size_t, size_t
+ MEM_STAT_DECL)
+{
+ gcc_assert (!f); // ggc-none doesn't support finalizers
+ return xcalloc (size, 1);
+}
+
+extern void *
+ggc_internal_alloc (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_alloc_")));
+extern void *
+ggc_internal_alloc_no_dtor (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_alloc_")));
+extern void *
+ggc_internal_cleared_alloc (size_t size, void (*f)(void *),
+ size_t s, size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_cleared_alloc_")));
+extern void *
+ggc_internal_cleared_alloc_no_dtor (size_t size, void (*f)(void *),
+ size_t s, size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_cleared_alloc_")));
+#else
void *
ggc_internal_alloc (size_t size, void (*f)(void *), size_t, size_t
MEM_STAT_DECL)
return xcalloc (size, 1);
}
+void *
+ggc_internal_alloc_no_dtor (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+{
+ return ggc_internal_alloc (size, f, s, n PASS_MEM_STAT);
+}
+
+void *
+ggc_internal_cleared_alloc_no_dtor (size_t size, void (*f)(void *),
+ size_t s, size_t n MEM_STAT_DECL)
+{
+ return ggc_internal_cleared_alloc (size, f, s, n PASS_MEM_STAT);
+}
+#endif
+
void *
ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
{
/* Allocate a chunk of memory of SIZE bytes. Its contents are undefined. */
+#ifdef HAVE_ATTRIBUTE_ALIAS
+extern "C" void *
+ggc_internal_alloc_ (size_t size, void (*f)(void *), size_t s, size_t n
+ MEM_STAT_DECL)
+#else
void *
ggc_internal_alloc (size_t size, void (*f)(void *), size_t s, size_t n
MEM_STAT_DECL)
+#endif
{
size_t order, word, bit, object_offset, object_size;
struct page_entry *entry;
return result;
}
+#ifdef HAVE_ATTRIBUTE_ALIAS
+extern void *
+ggc_internal_alloc (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_alloc_")));
+extern void *
+ggc_internal_alloc_no_dtor (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+ __attribute__((__alias__ ("ggc_internal_alloc_")));
+#else
+#ifdef __GNUC__
+__attribute__ ((__noinline__))
+#endif
+void *
+ggc_internal_alloc_no_dtor (size_t size, void (*f)(void *), size_t s,
+ size_t n MEM_STAT_DECL)
+{
+ return ggc_internal_alloc (size, f, s, n PASS_MEM_STAT);
+}
+#endif
+
/* Mark function for strings. */
void
/* The internal primitive. */
extern void *ggc_internal_alloc (size_t, void (*)(void *), size_t,
- size_t CXX_MEM_STAT_INFO)
+ size_t CXX_MEM_STAT_INFO);
+/* If the second argument is non-NULL, it can't be marked ATTRIBUTE_MALLOC,
+ because ggc_free performs finalization. Add an alias or wrapper used just
+ for the NULL finalizer which can be marked with ATTRIBUTE_MALLOC. */
+extern void *ggc_internal_alloc_no_dtor (size_t, void (*)(void *), size_t,
+ size_t CXX_MEM_STAT_INFO)
ATTRIBUTE_MALLOC;
inline void *
ggc_internal_alloc (size_t s CXX_MEM_STAT_INFO)
{
- return ggc_internal_alloc (s, NULL, 0, 1 PASS_MEM_STAT);
+ return ggc_internal_alloc_no_dtor (s, NULL, 0, 1 PASS_MEM_STAT);
}
extern size_t ggc_round_alloc_size (size_t requested_size);
/* Allocates cleared memory. */
extern void *ggc_internal_cleared_alloc (size_t, void (*)(void *),
size_t, size_t
- CXX_MEM_STAT_INFO) ATTRIBUTE_MALLOC;
+ CXX_MEM_STAT_INFO);
+extern void *ggc_internal_cleared_alloc_no_dtor (size_t, void (*)(void *),
+ size_t, size_t
+ CXX_MEM_STAT_INFO)
+ ATTRIBUTE_MALLOC;
inline void *
ggc_internal_cleared_alloc (size_t s CXX_MEM_STAT_INFO)
{
- return ggc_internal_cleared_alloc (s, NULL, 0, 1 PASS_MEM_STAT);
+ return ggc_internal_cleared_alloc_no_dtor (s, NULL, 0, 1 PASS_MEM_STAT);
}
/* Resize a block. */
return static_cast<T *> (ggc_internal_alloc (sizeof (T), finalize<T>, 0, 1
PASS_MEM_STAT));
else
- return static_cast<T *> (ggc_internal_alloc (sizeof (T), NULL, 0, 1
- PASS_MEM_STAT));
+ return static_cast<T *> (ggc_internal_alloc_no_dtor (sizeof (T), NULL,
+ 0, 1 PASS_MEM_STAT));
}
/* GGC allocation function that does not call finalizer for type
inline T *
ggc_alloc_no_dtor (ALONE_CXX_MEM_STAT_INFO)
{
- return static_cast<T *> (ggc_internal_alloc (sizeof (T), NULL, 0, 1
- PASS_MEM_STAT));
+ return static_cast<T *> (ggc_internal_alloc_no_dtor (sizeof (T), NULL, 0, 1
+ PASS_MEM_STAT));
}
template<typename T>
finalize<T>, 0, 1
PASS_MEM_STAT));
else
- return static_cast<T *> (ggc_internal_cleared_alloc (sizeof (T), NULL, 0, 1
- PASS_MEM_STAT));
+ return static_cast<T *> (ggc_internal_cleared_alloc_no_dtor (sizeof (T),
+ NULL, 0, 1
+ PASS_MEM_STAT));
}
template<typename T>
return static_cast<T *> (ggc_internal_alloc (c * sizeof (T), finalize<T>,
sizeof (T), c PASS_MEM_STAT));
else
- return static_cast<T *> (ggc_internal_alloc (c * sizeof (T), NULL, 0, 0
- PASS_MEM_STAT));
+ return static_cast<T *> (ggc_internal_alloc_no_dtor (c * sizeof (T),
+ NULL, 0, 0
+ PASS_MEM_STAT));
}
template<typename T>
sizeof (T), c
PASS_MEM_STAT));
else
- return static_cast<T *> (ggc_internal_cleared_alloc (c * sizeof (T), NULL,
- 0, 0 PASS_MEM_STAT));
+ return static_cast<T *> (ggc_internal_cleared_alloc_no_dtor (c
+ * sizeof (T),
+ NULL, 0, 0
+ PASS_MEM_STAT));
}
inline void *