libstdc++: merge non-abi changes from Apple's developer tools

Take some changes from Apple's Developer Tools 4.0 [1]:

block.patch
emergency-buffer-reduction.patch
test_cleanup.patch

vector_copy_no_alloc.patch
	problem/6473222 copy-constructing a std::vector	from an
	empty std::vector calls malloc

2008-10-27  Howard Hinnant
stl_tree_system_header.patch
	Added #pragma GCC system_header to stl_tree.h.
copy_doc.patch
	Corrected documentation concerning copy in stl_algobase.h.
string_compare.patch
	Fixed basic_string.h, basic_string.tcc, incorrect 64bit to
	32bit narrowing.

Reference:

[1] http://opensource.apple.com/source/libstdcxx/libstdcxx-39/patches-4.2.1/

Obtained from:	Apple
MFC after:	1 month
This commit is contained in:
Pedro F. Giffuni 2013-11-21 16:44:36 +00:00
parent 2bd5e058b7
commit 096464d39c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258429
9 changed files with 78 additions and 55 deletions

View File

@ -390,6 +390,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2)
{ _M_copy(__p, __k1, __k2 - __k1); }
static int
_S_compare(size_type __x, size_type __y)
{
if (__x > __y)
return 1;
if (__x < __y)
return -1;
return 0;
}
void
_M_mutate(size_type __pos, size_type __len1, size_type __len2);
@ -1934,7 +1944,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
int __r = traits_type::compare(_M_data(), __str.data(), __len);
if (!__r)
__r = __size - __osize;
__r = _S_compare(__size, __osize);
return __r;
}

View File

@ -903,7 +903,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const size_type __len = std::min(__n, __osize);
int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
if (!__r)
__r = __n - __osize;
__r = _S_compare(__n, __osize);
return __r;
}
@ -921,7 +921,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
int __r = traits_type::compare(_M_data() + __pos1,
__str.data() + __pos2, __len);
if (!__r)
__r = __n1 - __n2;
__r = _S_compare(__n1, __n2);
return __r;
}
@ -936,7 +936,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const size_type __len = std::min(__size, __osize);
int __r = traits_type::compare(_M_data(), __s, __len);
if (!__r)
__r = __size - __osize;
__r = _S_compare(__size, __osize);
return __r;
}
@ -952,7 +952,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const size_type __len = std::min(__n1, __osize);
int __r = traits_type::compare(_M_data() + __pos, __s, __len);
if (!__r)
__r = __n1 - __osize;
__r = _S_compare(__n1, __osize);
return __r;
}
@ -968,7 +968,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const size_type __len = std::min(__n1, __n2);
int __r = traits_type::compare(_M_data() + __pos, __s, __len);
if (!__r)
__r = __n1 - __n2;
__r = _S_compare(__n1, __n2);
return __r;
}

View File

@ -373,7 +373,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* @param first An input iterator.
* @param last An input iterator.
* @param result An output iterator.
* @return result + (first - last)
* @return result + (last - first)
*
* This inline function will boil down to a call to @c memmove whenever
* possible. Failing that, if random access iterators are passed, then the

View File

@ -64,6 +64,8 @@
#ifndef _TREE_H
#define _TREE_H 1
#pragma GCC system_header
#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_construct.h>

View File

@ -119,9 +119,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
_Vector_base(size_t __n, const allocator_type& __a)
: _M_impl(__a)
{
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_finish = this->_M_impl._M_start;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
if (__n)
{
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_finish = this->_M_impl._M_start;
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
}
}
~_Vector_base()

View File

@ -342,12 +342,12 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{ return _M_bin[__which]; }
void
_M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block,
_M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block_record,
size_t __thread_id)
{
if (__gthread_active_p())
{
__block->_M_thread_id = __thread_id;
__block_record->_M_thread_id = __thread_id;
--__bin._M_free[__thread_id];
++__bin._M_used[__thread_id];
}
@ -697,11 +697,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{
// Already reserved.
typedef typename __pool_type::_Block_record _Block_record;
_Block_record* __block = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block->_M_next;
_Block_record* __block_record = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block_record->_M_next;
__pool._M_adjust_freelist(__bin, __block, __thread_id);
__c = reinterpret_cast<char*>(__block) + __pool._M_get_align();
__pool._M_adjust_freelist(__bin, __block_record, __thread_id);
__c = reinterpret_cast<char*>(__block_record) + __pool._M_get_align();
}
else
{

View File

@ -423,11 +423,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
s += buf;
s += tab;
s += "label: ";
sprintf(buf, "%u", ref.second.first);
sprintf(buf, "%lu", ref.second.first);
s += buf;
s += tab;
s += "size: ";
sprintf(buf, "%u", ref.second.second);
sprintf(buf, "%lu", ref.second.second);
s += buf;
s += '\n';
}

View File

@ -78,6 +78,14 @@ using namespace __cxxabiv1;
# define EMERGENCY_OBJ_COUNT 4
#endif
/* APPLE LOCAL begin reduce emergency buffer size */
/* 256 bytes is more than large enough for an std::bad_alloc object */
#undef EMERGENCY_OBJ_SIZE
#undef EMERGENCY_OBJ_COUNT
#define EMERGENCY_OBJ_SIZE 256
#define EMERGENCY_OBJ_COUNT 2
/* APPLE LOCAL end reduce emergency buffer size */
#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
typedef unsigned int bitmask_type;
#else

View File

@ -107,11 +107,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_Bin_record& __bin = _M_bin[__which];
char* __c = __p - _M_get_align();
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
_Block_record* __block_record = reinterpret_cast<_Block_record*>(__c);
// Single threaded application - return to global pool.
__block->_M_next = __bin._M_first[0];
__bin._M_first[0] = __block;
__block_record->_M_next = __bin._M_first[0];
__bin._M_first[0] = __block_record;
}
char*
@ -134,22 +134,22 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
__bin._M_address = __address;
char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
__bin._M_first[__thread_id] = __block;
_Block_record* __block_record = reinterpret_cast<_Block_record*>(__c);
__bin._M_first[__thread_id] = __block_record;
while (--__block_count > 0)
{
__c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
__block_record->_M_next = reinterpret_cast<_Block_record*>(__c);
__block_record = __block_record->_M_next;
}
__block->_M_next = NULL;
__block_record->_M_next = NULL;
__block = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block->_M_next;
__block_record = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block_record->_M_next;
// NB: For alignment reasons, we can't use the first _M_align
// bytes, even when sizeof(_Block_record) < _M_align.
return reinterpret_cast<char*>(__block) + __options._M_align;
return reinterpret_cast<char*>(__block_record) + __options._M_align;
}
void
@ -256,7 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// Know __p not null, assume valid block.
char* __c = __p - _M_get_align();
_Block_record* __block = reinterpret_cast<_Block_record*>(__c);
_Block_record* __block_record = reinterpret_cast<_Block_record*>(__c);
if (__gthread_active_p())
{
// Calculate the number of records to remove from our freelist:
@ -313,13 +313,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// Return this block to our list and update counters and
// owner id as needed.
if (__block->_M_thread_id == __thread_id)
if (__block_record->_M_thread_id == __thread_id)
--__bin._M_used[__thread_id];
else
__atomic_add(&__reclaimed_base[__block->_M_thread_id], 1);
__atomic_add(&__reclaimed_base[__block_record->_M_thread_id], 1);
__block->_M_next = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block;
__block_record->_M_next = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block_record;
++__bin._M_free[__thread_id];
}
@ -327,8 +327,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{
// Not using threads, so single threaded application - return
// to global pool.
__block->_M_next = __bin._M_first[0];
__bin._M_first[0] = __block;
__block_record->_M_next = __bin._M_first[0];
__bin._M_first[0] = __block_record;
}
}
@ -354,7 +354,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// blocks on global list (and if not add new ones) and
// get the first one.
_Bin_record& __bin = _M_bin[__which];
_Block_record* __block = NULL;
_Block_record* __block_record = NULL;
if (__gthread_active_p())
{
// Resync the _M_used counters.
@ -378,16 +378,16 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// No need to hold the lock when we are adding a whole
// chunk to our own list.
char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
__block = reinterpret_cast<_Block_record*>(__c);
__block_record = reinterpret_cast<_Block_record*>(__c);
__bin._M_free[__thread_id] = __block_count;
__bin._M_first[__thread_id] = __block;
__bin._M_first[__thread_id] = __block_record;
while (--__block_count > 0)
{
__c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
__block_record->_M_next = reinterpret_cast<_Block_record*>(__c);
__block_record = __block_record->_M_next;
}
__block->_M_next = NULL;
__block_record->_M_next = NULL;
}
else
{
@ -405,11 +405,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
{
__bin._M_free[__thread_id] = __block_count;
__bin._M_free[0] -= __block_count;
__block = __bin._M_first[0];
__block_record = __bin._M_first[0];
while (--__block_count > 0)
__block = __block->_M_next;
__bin._M_first[0] = __block->_M_next;
__block->_M_next = NULL;
__block_record = __block_record->_M_next;
__bin._M_first[0] = __block_record->_M_next;
__block_record->_M_next = NULL;
}
__gthread_mutex_unlock(__bin._M_mutex);
}
@ -423,30 +423,30 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
__bin._M_address = __address;
char* __c = static_cast<char*>(__v) + sizeof(_Block_address);
__block = reinterpret_cast<_Block_record*>(__c);
__bin._M_first[0] = __block;
__block_record = reinterpret_cast<_Block_record*>(__c);
__bin._M_first[0] = __block_record;
while (--__block_count > 0)
{
__c += __bin_size;
__block->_M_next = reinterpret_cast<_Block_record*>(__c);
__block = __block->_M_next;
__block_record->_M_next = reinterpret_cast<_Block_record*>(__c);
__block_record = __block_record->_M_next;
}
__block->_M_next = NULL;
__block_record->_M_next = NULL;
}
__block = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block->_M_next;
__block_record = __bin._M_first[__thread_id];
__bin._M_first[__thread_id] = __block_record->_M_next;
if (__gthread_active_p())
{
__block->_M_thread_id = __thread_id;
__block_record->_M_thread_id = __thread_id;
--__bin._M_free[__thread_id];
++__bin._M_used[__thread_id];
}
// NB: For alignment reasons, we can't use the first _M_align
// bytes, even when sizeof(_Block_record) < _M_align.
return reinterpret_cast<char*>(__block) + __options._M_align;
return reinterpret_cast<char*>(__block_record) + __options._M_align;
}
void