From: Paul Brook Date: Tue, 29 Jun 2004 14:50:35 +0000 (+0000) Subject: target-def.h (TARGET_CXX_GET_COOKIE_SIZE, [...]): Define. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=46e995e0e40e16ca159d6f5b116829700bbc269f;p=gcc.git target-def.h (TARGET_CXX_GET_COOKIE_SIZE, [...]): Define. gcc/ * target-def.h (TARGET_CXX_GET_COOKIE_SIZE, TARGET_CXX_COOKIE_HAS_SIZE): Define. (TARGET_CXX): Use them. * target.h (struct gcc_target): Add cxx.get_cookie_size and cxx.cookie_has_size. * targhooks.c (default_cxx_get_cookie_size): New fucntion. * targhooks.h (default_cxx_get_cookie_size): Add prototype. * config/arm/arm.c (TARGET_CXX_GET_COOKIE_SIZE, TARGET_CXX_COOKIE_HAS_SIZE): Define. (arm_get_cookie_size, arm_cookie_has_size): New functions. * Make-lang.in (cp/init.o): Add dependency on $(TARGET_H). * doc/tm.texi: Document TARGET_CXX_GET_COOKIE_SIZE and TARGET_CXX_COOKIE_HAS_SIZE. gcc/cp/ * init.c: Include target.h. (get_cookie_size): Remove and replace with target hook. Update callers. (build_new_1): Store the element size in the cookie. libstdc++-v3/ * libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the element size in the cookie. testsuite/ * g++.old-deja/g++.abi/arraynew.C: Handle ARM EABI cookies. * g++.old-deja/g++.abi/cxa_vec.C: Allocate larger cookies for AEABI. From-SVN: r83854 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01c0285f4be..3ad291e0a92 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-06-29 Paul Brook + + * target-def.h (TARGET_CXX_GET_COOKIE_SIZE, + TARGET_CXX_COOKIE_HAS_SIZE): Define. + (TARGET_CXX): Use them. + * target.h (struct gcc_target): Add cxx.get_cookie_size and + cxx.cookie_has_size. + * targhooks.c (default_cxx_get_cookie_size): New fucntion. + * targhooks.h (default_cxx_get_cookie_size): Add prototype. + * config/arm/arm.c (TARGET_CXX_GET_COOKIE_SIZE, + TARGET_CXX_COOKIE_HAS_SIZE): Define. + (arm_get_cookie_size, arm_cookie_has_size): New functions. + * Make-lang.in (cp/init.o): Add dependency on $(TARGET_H). + * doc/tm.texi: Document TARGET_CXX_GET_COOKIE_SIZE and + TARGET_CXX_COOKIE_HAS_SIZE. + 2004-06-29 J"orn Rennecke * cfglayout.c (fixup_reorder_chain): Don't do anything for diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index a7262f54dd9..7cd1573a03c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -164,6 +164,8 @@ static bool arm_align_anon_bitfield (void); static tree arm_cxx_guard_type (void); static bool arm_cxx_guard_mask_bit (void); +static tree arm_get_cookie_size (tree); +static bool arm_cookie_has_size (void); /* Initialize the GCC target structure. */ @@ -273,6 +275,12 @@ static bool arm_cxx_guard_mask_bit (void); #undef TARGET_CXX_GUARD_MASK_BIT #define TARGET_CXX_GUARD_MASK_BIT arm_cxx_guard_mask_bit +#undef TARGET_CXX_GET_COOKIE_SIZE +#define TARGET_CXX_GET_COOKIE_SIZE arm_get_cookie_size + +#undef TARGET_CXX_COOKIE_HAS_SIZE +#define TARGET_CXX_COOKIE_HAS_SIZE arm_cookie_has_size + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -14564,3 +14572,28 @@ arm_cxx_guard_mask_bit (void) { return TARGET_AAPCS_BASED; } + + +/* The EABI specifies that all array cookies are 8 bytes long. */ + +static tree +arm_get_cookie_size (tree type) +{ + tree size; + + if (!TARGET_AAPCS_BASED) + return default_cxx_get_cookie_size (type); + + size = build_int_2 (8, 0); + TREE_TYPE (size) = sizetype; + return size; +} + + +/* The EABI says that array cookies should also contain the element size. */ + +static bool +arm_cookie_has_size (void) +{ + return TARGET_AAPCS_BASED; +} diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 532180d82c2..203c36a24cb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2004-06-29 Paul Brook + + * init.c: Include target.h. + (get_cookie_size): Remove and replace with target hook. + Update callers. + (build_new_1): Store the element size in the cookie. + 2004-06-29 Nathan Sidwell PR c++/16260 diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 997b8aac4a8..34fb529fbc8 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -235,7 +235,7 @@ cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \ diagnostic.h intl.h gt-cp-call.h convert.h target.h cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_H) cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ - except.h + except.h $(TARGET_H) cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \ $(TM_P_H) $(TARGET_H) gt-cp-method.h cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h diff --git a/gcc/cp/init.c b/gcc/cp/init.c index c96e14d8070..4e02b9d2bae 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "except.h" #include "toplev.h" +#include "target.h" static bool begin_init_stmts (tree *, tree *); static tree finish_init_stmts (bool, tree, tree); @@ -52,7 +53,6 @@ static tree get_temp_regvar (tree, tree); static tree dfs_initialize_vtbl_ptrs (tree, void *); static tree build_default_init (tree, tree); static tree build_new_1 (tree); -static tree get_cookie_size (tree); static tree build_dtor_call (tree, special_function_kind, int); static tree build_field_list (tree, tree, int *); static tree build_vtbl_address (tree); @@ -1756,29 +1756,6 @@ build_java_class_ref (tree type) return class_decl; } -/* Returns the size of the cookie to use when allocating an array - whose elements have the indicated TYPE. Assumes that it is already - known that a cookie is needed. */ - -static tree -get_cookie_size (tree type) -{ - tree cookie_size; - - /* We need to allocate an additional max (sizeof (size_t), alignof - (true_type)) bytes. */ - tree sizetype_size; - tree type_align; - - sizetype_size = size_in_bytes (sizetype); - type_align = size_int (TYPE_ALIGN_UNIT (type)); - if (INT_CST_LT_UNSIGNED (type_align, sizetype_size)) - cookie_size = sizetype_size; - else - cookie_size = type_align; - - return cookie_size; -} /* Called from cplus_expand_expr when expanding a NEW_EXPR. The return value is immediately handed to expand_expr. */ @@ -1925,7 +1902,7 @@ build_new_1 (tree exp) /* If a cookie is required, add some extra space. */ if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)) { - cookie_size = get_cookie_size (true_type); + cookie_size = targetm.cxx.get_cookie_size (true_type); size = size_binop (PLUS_EXPR, size, cookie_size); } /* Create the argument list. */ @@ -1948,7 +1925,7 @@ build_new_1 (tree exp) /* Use a global operator new. */ /* See if a cookie might be required. */ if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)) - cookie_size = get_cookie_size (true_type); + cookie_size = targetm.cxx.get_cookie_size (true_type); else cookie_size = NULL_TREE; @@ -2019,6 +1996,7 @@ build_new_1 (tree exp) if (cookie_size) { tree cookie; + tree cookie_ptr; /* Adjust so we're pointing to the start of the object. */ data_addr = get_target_expr (build (PLUS_EXPR, full_pointer_type, @@ -2027,11 +2005,23 @@ build_new_1 (tree exp) /* Store the number of bytes allocated so that we can know how many elements to destroy later. We use the last sizeof (size_t) bytes to store the number of elements. */ - cookie = build (MINUS_EXPR, build_pointer_type (sizetype), + cookie_ptr = build (MINUS_EXPR, build_pointer_type (sizetype), data_addr, size_in_bytes (sizetype)); - cookie = build_indirect_ref (cookie, NULL); + cookie = build_indirect_ref (cookie_ptr, NULL); cookie_expr = build (MODIFY_EXPR, sizetype, cookie, nelts); + + if (targetm.cxx.cookie_has_size ()) + { + /* Also store the element size. */ + cookie_ptr = build (MINUS_EXPR, build_pointer_type (sizetype), + cookie_ptr, size_in_bytes (sizetype)); + cookie = build_indirect_ref (cookie_ptr, NULL); + cookie = build (MODIFY_EXPR, sizetype, cookie, + size_in_bytes(true_type)); + cookie_expr = build (COMPOUND_EXPR, TREE_TYPE (cookie_expr), + cookie, cookie_expr); + } data_addr = TARGET_EXPR_SLOT (data_addr); } else @@ -2278,7 +2268,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type, { tree cookie_size; - cookie_size = get_cookie_size (type); + cookie_size = targetm.cxx.get_cookie_size (type); base_tbd = cp_convert (ptype, cp_build_binary_op (MINUS_EXPR, diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d01993f3a68..944477def10 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8477,6 +8477,19 @@ This hook determines how guard variables are used. It should return @code{true} indicates the least significant bit should be used. @end deftypefn +@deftypefn {Target Hook} tree TARGET_CXX_GET_COOKIE_SIZE (tree @var{type}) +This hook returns the size of the cookie to use when allocating an array +whose elements have the indicated @var{type}. Assumes that it is already +known that a cookie is needed. The default is +@code{max(sizeof (size_t), alignof(type))}, as defined in section 2.7 of the +IA64/Generic C++ ABI. +@end deftypefn + +@deftypefn {Target Hook} bool TARGET_CXX_COOKIE_HAS_SIZE (void) +This hook should return @code{true} if the element size should be stored in +array cookies. The default is to return @code{false}. +@end deftypefn + @node Misc @section Miscellaneous Parameters @cindex parameters, miscellaneous diff --git a/gcc/target-def.h b/gcc/target-def.h index 72fda5b2ab5..0761a06f716 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -400,10 +400,20 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TARGET_CXX_GUARD_MASK_BIT hook_bool_void_false #endif +#ifndef TARGET_CXX_GET_COOKIE_SIZE +#define TARGET_CXX_GET_COOKIE_SIZE default_cxx_get_cookie_size +#endif + +#ifndef TARGET_CXX_COOKIE_HAS_SIZE +#define TARGET_CXX_COOKIE_HAS_SIZE hook_bool_void_false +#endif + #define TARGET_CXX \ { \ TARGET_CXX_GUARD_TYPE, \ - TARGET_CXX_GUARD_MASK_BIT \ + TARGET_CXX_GUARD_MASK_BIT, \ + TARGET_CXX_GET_COOKIE_SIZE, \ + TARGET_CXX_COOKIE_HAS_SIZE \ } /* The whole shebang. */ diff --git a/gcc/target.h b/gcc/target.h index 2c4b5300ec4..da37fcd23bd 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -482,6 +482,11 @@ struct gcc_target tree (*guard_type) (void); /* Return true if only the low bit of the guard should be tested. */ bool (*guard_mask_bit) (void); + /* Returns the size of the array cookie for an array of type. */ + tree (*get_cookie_size) (tree); + /* Returns true if the element size should be stored in the + array cookie. */ + bool (*cookie_has_size) (void); } cxx; /* Leave the boolean fields at the end. */ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 5d2a75fe315..a2745c4cbcd 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -143,3 +143,28 @@ default_cxx_guard_type (void) { return long_long_integer_type_node; } + + +/* Returns the size of the cookie to use when allocating an array + whose elements have the indicated TYPE. Assumes that it is already + known that a cookie is needed. */ + +tree +default_cxx_get_cookie_size (tree type) +{ + tree cookie_size; + + /* We need to allocate an additional max (sizeof (size_t), alignof + (true_type)) bytes. */ + tree sizetype_size; + tree type_align; + + sizetype_size = size_in_bytes (sizetype); + type_align = size_int (TYPE_ALIGN_UNIT (type)); + if (INT_CST_LT_UNSIGNED (type_align, sizetype_size)) + cookie_size = sizetype_size; + else + cookie_size = type_align; + + return cookie_size; +} diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 427334f02c1..fba17f82001 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -33,3 +33,4 @@ extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *); extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *); extern tree default_cxx_guard_type (void); +extern tree default_cxx_get_cookie_size (tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3fe71ecf5db..1bc26719b39 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-29 Paul Brook + + * g++.old-deja/g++.abi/arraynew.C: Handle ARM EABI cookies. + * g++.old-deja/g++.abi/cxa_vec.C: Allocate larger cookies for AEABI. + 2004-06-29 Nathan Sidwell PR c++/16260 diff --git a/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C b/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C index 3b11796c271..273d137b85e 100644 --- a/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C +++ b/gcc/testsuite/g++.old-deja/g++.abi/arraynew.C @@ -36,11 +36,16 @@ template void check_cookie (int i) { void* a = new T[11]; + size_t x; // Compute the cookie location manually. - size_t x = __alignof__ (T); +#ifdef __ARM_EABI__ + x = 8; +#else + x = __alignof__ (T); if (x < sizeof (size_t)) x = sizeof (size_t); +#endif if ((char *) a - x != (char *) p) exit (i); @@ -48,6 +53,12 @@ void check_cookie (int i) size_t *sp = ((size_t *) a) - 1; if (*sp != 11) exit (i); + +#ifdef __ARM_EABI__ + size_t *sp = ((size_t *) a) - 2; + if (*sp != sizeof (T)) + exit (i); +#endif } template @@ -55,11 +66,16 @@ void check_placement_cookie (int i) { p = malloc (sizeof (T) * 11 + 100); void* a = new (p) T[11]; + size_t x; // Compute the cookie location manually. - size_t x = __alignof__ (T); +#ifdef __ARM_EABI__ + x = 8; +#else + x = __alignof__ (T); if (x < sizeof (size_t)) x = sizeof (size_t); +#endif if ((char *) a - x != (char *) p) exit (i); @@ -67,6 +83,12 @@ void check_placement_cookie (int i) size_t *sp = ((size_t *) a) - 1; if (*sp != 11) exit (i); + +#ifdef __ARM_EABI__ + size_t *sp = ((size_t *) a) - 2; + if (*sp != sizeof (T)) + exit (i); +#endif } struct X {}; diff --git a/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C b/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C index ed5a7de77e7..a6fdc44e597 100644 --- a/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C +++ b/gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C @@ -14,6 +14,13 @@ static int ctor_count = 0; static int dtor_count = 0; static bool dtor_repeat = false; +// Allocate enough padding to hold an array cookie. +#ifdef __ARM_EABI__ +#define padding 8 +#else +#define padding (sizeof (std::size_t)) +#endif + // our pseudo ctors and dtors static void ctor (void *) { @@ -71,8 +78,8 @@ void test0 () try { - void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor); - abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor); + void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); + abi::__cxa_vec_delete (ary, 1, padding, dtor); if (ctor_count || dtor_count || blocks) longjmp (jump, 1); } @@ -105,7 +112,7 @@ void test1 () ctor_count = 4; try { - void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor); + void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); longjmp (jump, 1); } catch (...) @@ -138,8 +145,8 @@ void test2 () dtor_count = 3; try { - void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor); - abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor); + void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); + abi::__cxa_vec_delete (ary, 1, padding, dtor); longjmp (jump, 1); } catch (...) @@ -174,8 +181,8 @@ void test3 () dtor_repeat = true; try { - void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor); - abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor); + void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); + abi::__cxa_vec_delete (ary, 1, padding, dtor); longjmp (jump, 1); } catch (...) @@ -212,7 +219,7 @@ void test4 () dtor_count = 2; try { - void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor); + void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); longjmp (jump, 1); } catch (...) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1de45fbd4f6..e433113f1f2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2004-06-29 Paul Brook + + * libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the + element size in the cookie. + 2004-06-28 Paolo Carlini * include/bits/cpp_type_traits.h: Move the additions to diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc index 86d41d9ea98..eb7851b0588 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -96,6 +96,10 @@ namespace __cxxabiv1 { base += padding_size; reinterpret_cast (base)[-1] = element_count; +#ifdef __ARM_EABI__ + // ARM EABI array cookies also contain the element size. + reinterpret_cast (base)[-2] = element_size; +#endif } try { @@ -131,6 +135,10 @@ namespace __cxxabiv1 { base += padding_size; reinterpret_cast(base)[-1] = element_count; +#ifdef __ARM_EABI__ + // ARM EABI array cookies also contain the element size. + reinterpret_cast (base)[-2] = element_size; +#endif } try {