In the tcmalloc memory
allocator(http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html),
deallocation involves a costly lookup to get the size of the deleted
object. The size is required to find the right free list to release
back the object. By passing the size of the object to the delete
call, this lookup can be avoided. This patch adds support for operator
delete(void*, size_t) guarded by a -fsized-delete flag. It also adds a
default implementation of delete(void *, size_t) that ignores the size
parameter.
Bootstraps and no test regressions. OK for google/gcc-4_6 branch?
---------------
2011-12-11 Easwaran Raman <[email protected]>
* common.opt (fsized-delete): New option.
cp/ChangeLog.google-4_6:
2011-12-11 Easwaran Raman <[email protected]>
* decl.c (cxx_init_decl_processing): Specify a function that
takes a void* and size_t for DELETE_EXPR.
* call.c (build_op_delete_call): If fsized-delete is used, use
the variant that takes size_t as the second parameter except
when deleteting a pointer of type void *.
testsuite/ChangeLog.google-4_6:
2011-12-11 Easwaran Raman <[email protected]>
* g++.dg/other/sized-delete-1.C: New test.
libstdc++-v3/ChangeLog.google-4_6:
2011-12-11 Easwaran Raman <[email protected]>
* libsupc++/del_op.cc (delete): Define a new variant
void operator delete(void*, std::size_t).
* libsupc++/new (delete): Declare
void operator delete(void*, std::size_t) throw();
* testsuite/util/testsuite_abi.cc (check_version): Add new
known version GLIBCXX_3.4.17.
* config/abi/post/x86_64-linux-gnu/baseline_symbols.txt: Add
new symbol _ZdlPvm@@GLIBCXX_3.4.17.
* config/abi/pre/gnu.ver: Add new symbol _ZdlPvm at version
GLIBCXX_3.4.17.
Index: libstdc++-v3/libsupc++/del_op.cc
===================================================================
--- libstdc++-v3/libsupc++/del_op.cc (revision 182213)
+++ libstdc++-v3/libsupc++/del_op.cc (working copy)
@@ -46,3 +46,11 @@ operator delete(void* ptr) throw ()
if (ptr)
std::free(ptr);
}
+
+_GLIBCXX_WEAK_DEFINITION void
+operator delete(void* ptr,
+ std::size_t bytes __attribute__((__unused__))) throw ()
+{
+ if (ptr)
+ std::free(ptr);
+}
Index: libstdc++-v3/libsupc++/new
===================================================================
--- libstdc++-v3/libsupc++/new (revision 182213)
+++ libstdc++-v3/libsupc++/new (working copy)
@@ -93,6 +93,7 @@ namespace std
void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
+void operator delete(void*, std::size_t) throw();
void operator delete[](void*) throw();
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
Index: libstdc++-v3/testsuite/util/testsuite_abi.cc
===================================================================
--- libstdc++-v3/testsuite/util/testsuite_abi.cc (revision 182213)
+++ libstdc++-v3/testsuite/util/testsuite_abi.cc (working copy)
@@ -194,6 +194,7 @@ check_version(symbol& test, bool added)
known_versions.push_back("GLIBCXX_3.4.14");
known_versions.push_back("GLIBCXX_3.4.15");
known_versions.push_back("GLIBCXX_3.4.16");
+ known_versions.push_back("GLIBCXX_3.4.17");
known_versions.push_back("GLIBCXX_LDBL_3.4");
known_versions.push_back("GLIBCXX_LDBL_3.4.7");
known_versions.push_back("GLIBCXX_LDBL_3.4.10");
@@ -560,4 +561,3 @@ demangle(const std::string& mangled)
}
return name;
}
-
Index: libstdc++-v3/config/abi/post/x86_64-linux-gnu/baseline_symbols.txt
===================================================================
--- libstdc++-v3/config/abi/post/x86_64-linux-gnu/baseline_symbols.txt (revision 182213)
+++ libstdc++-v3/config/abi/post/x86_64-linux-gnu/baseline_symbols.txt (working copy)
@@ -2422,6 +2422,7 @@ FUNC:_ZTv0_n24_NSt9strstreamD1Ev@@GLIBCXX_3.4
FUNC:_ZdaPv@@GLIBCXX_3.4
FUNC:_ZdaPvRKSt9nothrow_t@@GLIBCXX_3.4
FUNC:_ZdlPv@@GLIBCXX_3.4
+FUNC:_ZdlPvm@@GLIBCXX_3.4.17
FUNC:_ZdlPvRKSt9nothrow_t@@GLIBCXX_3.4
FUNC:_Znam@@GLIBCXX_3.4
FUNC:_ZnamRKSt9nothrow_t@@GLIBCXX_3.4
Index: libstdc++-v3/config/abi/pre/gnu.ver
===================================================================
--- libstdc++-v3/config/abi/pre/gnu.ver (revision 182213)
+++ libstdc++-v3/config/abi/pre/gnu.ver (working copy)
@@ -1279,6 +1279,13 @@ GLIBCXX_3.4.16 {
} GLIBCXX_3.4.15;
+GLIBCXX_3.4.17 {
+
+ # operator delete(void*, , unsigned long)
+ _ZdlPvm;
+
+} GLIBCXX_3.4.16;
+
# Symbols in the support library (libsupc++) have their own tag.
CXXABI_1.3 {
Index: gcc/testsuite/g++.dg/other/sized-delete-1.C
===================================================================
--- gcc/testsuite/g++.dg/other/sized-delete-1.C (revision 0)
+++ gcc/testsuite/g++.dg/other/sized-delete-1.C (revision 0)
@@ -0,0 +1,14 @@
+// { dg-do link}
+// { dg-options "-O -fsized-delete" }
+// { dg-final { scan-assembler "_ZdlPv\[mj\]" } }
+struct A
+{
+ int a[100];
+};
+
+int main(void)
+{
+ A *a = new A;
+ delete a;
+ return 0;
+}
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 182213)
+++ gcc/cp/decl.c (working copy)
@@ -3519,6 +3519,7 @@ cxx_init_decl_processing (void)
{
tree void_ftype;
tree void_ftype_ptr;
+ tree void_ftype_ptr_sizetype;
build_common_tree_nodes (flag_signed_char);
@@ -3584,8 +3585,14 @@ cxx_init_decl_processing (void)
void_ftype = build_function_type_list (void_type_node, NULL_TREE);
void_ftype_ptr = build_function_type_list (void_type_node,
ptr_type_node, NULL_TREE);
+ void_ftype_ptr_sizetype = build_function_type_list (void_type_node,
+ ptr_type_node,
+ size_type_node,
+ NULL_TREE);
void_ftype_ptr
= build_exception_variant (void_ftype_ptr, empty_except_spec);
+ void_ftype_ptr_sizetype
+ = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec);
/* C++ extensions */
@@ -3635,7 +3642,7 @@ cxx_init_decl_processing (void)
current_lang_name = lang_name_cplusplus;
{
- tree newtype, deltype;
+ tree newtype, deltype, deltype2;
tree ptr_ftype_sizetype;
tree new_eh_spec;
@@ -3664,8 +3671,10 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (ptr_ftype_sizetype, new_eh_spec);
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
+ deltype2 = build_exception_variant (void_ftype_ptr_sizetype, empty_except_spec);
push_cp_library_fn (NEW_EXPR, newtype);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
+ push_cp_library_fn (DELETE_EXPR, deltype2);
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
push_cp_library_fn (VEC_DELETE_EXPR, deltype);
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c (revision 182213)
+++ gcc/cp/call.c (working copy)
@@ -5264,8 +5264,22 @@ build_op_delete_call (enum tree_code code, tree ad
usual deallocation function."
So (void*) beats (void*, size_t). */
- if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
- break;
+ /* If type is not void, pick (void*, size_t) version (which comes
+ first). */
+ if (!flag_sized_delete || TREE_CODE (type) == VOID_TYPE )
+ {
+ /* If -fsized-delete is not passed or if a void * is deleted,
+ prefer delete (void *) version. */
+ if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
+ break;
+ }
+ else
+ {
+ /* If -fsized-delete is passed and it is not a void *,
+ prefer delete (void *, size_t) version. */
+ if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
+ break;
+ }
}
}
Index: gcc/common.opt
===================================================================
--- gcc/common.opt (revision 182213)
+++ gcc/common.opt (working copy)
@@ -1898,6 +1898,10 @@ fsingle-precision-constant
Common Report Var(flag_single_precision_constant) Optimization
Convert floating point constants to single precision constants
+fsized-delete
+Common Report Var(flag_sized_delete) Optimization
+Support delete operator with objetc's size as the second parameter.
+
fsplit-ivs-in-unroller
Common Report Var(flag_split_ivs_in_unroller) Init(1) Optimization
Split lifetimes of induction variables when loops are unrolled