@ -36,6 +36,7 @@
# include <cstddef>
# include <cstdint>
# include <cstring>
# include <limits>
# include "absl/log/absl_check.h"
# include "google/protobuf/arena.h"
@ -58,49 +59,43 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) {
// total_size must be non-zero since it is lower-bounded by new_size.
return elements ( ) + current_size_ ;
}
constexpr size_t ptr_size = sizeof ( rep ( ) - > elements [ 0 ] ) ;
Arena * arena = GetOwningArena ( ) ;
new_size = internal : : CalculateReserveSize < void * , kRepHeaderSize > ( total_size_ ,
new_size ) ;
ABSL_CHECK_LE ( static_cast < int64_t > ( new_size ) ,
static_cast < int64_t > (
( std : : numeric_limits < size_t > : : max ( ) - kRepHeaderSize ) /
sizeof ( rep ( ) - > elements [ 0 ] ) ) )
ABSL_CHECK_LE (
static_cast < int64_t > ( new_size ) ,
static_cast < int64_t > (
( std : : numeric_limits < size_t > : : max ( ) - kRepHeaderSize ) / ptr_size ) )
< < " Requested size is too large to fit into size_t. " ;
size_t bytes = kRepHeaderSize + sizeof ( rep ( ) - > elements [ 0 ] ) * new_size ;
size_t bytes = kRepHeaderSize + ptr_size * new_size ;
Rep * new_rep ;
void * old_tagged_ptr = tagged_rep_or_elem_ ;
if ( arena = = nullptr ) {
internal : : SizedPtr res = internal : : AllocateAtLeast ( bytes ) ;
new_size =
static_cast < int > ( ( res . n - kRepHeaderSize ) / sizeof ( rep ( ) - > elements [ 0 ] ) ) ;
new_size = static_cast < int > ( ( res . n - kRepHeaderSize ) / ptr_size ) ;
new_rep = reinterpret_cast < Rep * > ( res . p ) ;
} else {
new_rep = reinterpret_cast < Rep * > ( Arena : : CreateArray < char > ( arena , bytes ) ) ;
}
if ( using_sso ( ) ) {
new_rep - > elements [ 0 ] = old_tagged_ptr ;
new_rep - > allocated_size = old_tagged_ptr ! = nullptr ? 1 : 0 ;
new_rep - > elements [ 0 ] = old_tagged_ptr ;
} else {
if ( old_tagged_ptr ) {
Rep * old_rep = reinterpret_cast < Rep * > (
reinterpret_cast < uintptr_t > ( old_tagged_ptr ) - 1 ) ;
if ( old_rep - > allocated_size > 0 ) {
memcpy ( new_rep - > elements , old_rep - > elements ,
old_rep - > allocated_size * sizeof ( rep ( ) - > elements [ 0 ] ) ) ;
}
new_rep - > allocated_size = old_rep - > allocated_size ;
const size_t old_size =
total_size_ * sizeof ( rep ( ) - > elements [ 0 ] ) + kRepHeaderSize ;
if ( arena = = nullptr ) {
internal : : SizedDelete ( old_rep , old_size ) ;
} else {
arena_ - > ReturnArrayMemory ( old_rep , old_size ) ;
}
Rep * old_rep =
reinterpret_cast < Rep * > ( reinterpret_cast < uintptr_t > ( old_tagged_ptr ) - 1 ) ;
if ( old_rep - > allocated_size > 0 ) {
memcpy ( new_rep - > elements , old_rep - > elements ,
old_rep - > allocated_size * ptr_size ) ;
}
new_rep - > allocated_size = old_rep - > allocated_size ;
size_t old_size = total_size_ * ptr_size + kRepHeaderSize ;
if ( arena = = nullptr ) {
internal : : SizedDelete ( old_rep , old_size ) ;
} else {
new_rep - > allocated_size = 0 ;
arena - > ReturnArrayMemory ( old_rep , old_size ) ;
}
}