diff options
author | Paul Brook <paul@codesourcery.com> | 2004-06-29 14:50:35 +0000 |
---|---|---|
committer | Paul Brook <pbrook@gcc.gnu.org> | 2004-06-29 14:50:35 +0000 |
commit | 46e995e0e40e16ca159d6f5b116829700bbc269f (patch) | |
tree | f6a9a6cf28955476ec2789692fe97c33db01c297 | |
parent | 50a2de961ffa6022ac3084c94f76d1462be04845 (diff) | |
download | gcc-46e995e0e40e16ca159d6f5b116829700bbc269f.zip gcc-46e995e0e40e16ca159d6f5b116829700bbc269f.tar.gz gcc-46e995e0e40e16ca159d6f5b116829700bbc269f.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 33 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/cp/init.c | 48 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 13 | ||||
-rw-r--r-- | gcc/target-def.h | 12 | ||||
-rw-r--r-- | gcc/target.h | 5 | ||||
-rw-r--r-- | gcc/targhooks.c | 25 | ||||
-rw-r--r-- | gcc/targhooks.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.abi/arraynew.C | 26 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.abi/cxa_vec.C | 23 | ||||
-rw-r--r-- | libstdc++-v3/ChangeLog | 5 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/vec.cc | 8 |
15 files changed, 188 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01c0285..3ad291e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-06-29 Paul Brook <paul@codesourcery.com> + + * 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 <joern.rennecke@superh.com> * 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 a7262f5..7cd1573 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 532180d..203c36a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2004-06-29 Paul Brook <paul@codesourcery.com> + + * 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 <nathan@codesourcery.com> PR c++/16260 diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 997b8aa..34fb529 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 c96e14d..4e02b9d 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 d01993f..944477d 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 72fda5b..0761a06 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 2c4b530..da37fcd 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 5d2a75f..a2745c4 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 427334f..fba17f8 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 3fe71ec..1bc2671 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-29 Paul Brook <paul@codesourcery.com> + + * 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 <nathan@codesourcery.com> 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 3b11796..273d137 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 <typename T> 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 <typename T> @@ -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 ed5a7de..a6fdc44 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 1de45fb..e433113 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2004-06-29 Paul Brook <paul@codesourcery.com> + + * libsupc++/vec.cc (__cxa_vec_new2, __cxa_vec_new3): Store the + element size in the cookie. + 2004-06-28 Paolo Carlini <pcarlini@suse.de> * 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 86d41d9..eb7851b 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -96,6 +96,10 @@ namespace __cxxabiv1 { base += padding_size; reinterpret_cast <std::size_t *> (base)[-1] = element_count; +#ifdef __ARM_EABI__ + // ARM EABI array cookies also contain the element size. + reinterpret_cast <std::size_t *> (base)[-2] = element_size; +#endif } try { @@ -131,6 +135,10 @@ namespace __cxxabiv1 { base += padding_size; reinterpret_cast<std::size_t *>(base)[-1] = element_count; +#ifdef __ARM_EABI__ + // ARM EABI array cookies also contain the element size. + reinterpret_cast <std::size_t *> (base)[-2] = element_size; +#endif } try { |