Avoid calling GetArena() multiple times.
PiperOrigin-RevId: 583188151
diff --git a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc
index 62cbbae..732a60c 100644
--- a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc
+++ b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc
@@ -352,8 +352,9 @@
clear_$oneof_name$();
set_has_$name$();
$field$ = new ::absl::Cord;
- if (GetArena() != nullptr) {
- GetArena()->Own($field$);
+ ::$proto_ns$::Arena* arena = GetArena();
+ if (arena != nullptr) {
+ arena->Own($field$);
}
}
*$field$ = value;
@@ -372,8 +373,9 @@
clear_$oneof_name$();
set_has_$name$();
$field$ = new ::absl::Cord;
- if (GetArena() != nullptr) {
- GetArena()->Own($field$);
+ ::$proto_ns$::Arena* arena = GetArena();
+ if (arena != nullptr) {
+ arena->Own($field$);
}
}
*$field$ = value;
@@ -387,8 +389,9 @@
clear_$oneof_name$();
set_has_$name$();
$field$ = new ::absl::Cord;
- if (GetArena() != nullptr) {
- GetArena()->Own($field$);
+ ::$proto_ns$::Arena* arena = GetArena();
+ if (arena != nullptr) {
+ arena->Own($field$);
}
}
return $field$;
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 94d7e45..7872866 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -351,6 +351,7 @@
// constructor.)
const Descriptor* descriptor = type_info_->type;
+ Arena* arena = GetArena();
// Initialize oneof cases.
int oneof_count = 0;
for (int i = 0; i < descriptor->oneof_decl_count(); ++i) {
@@ -360,7 +361,7 @@
}
if (type_info_->extensions_offset != -1) {
- new (MutableExtensionsRaw()) ExtensionSet(GetArena());
+ new (MutableExtensionsRaw()) ExtensionSet(arena);
}
for (int i = 0; i < descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
@@ -374,7 +375,7 @@
if (!field->is_repeated()) { \
new (field_ptr) TYPE(field->default_value_##TYPE()); \
} else { \
- new (field_ptr) RepeatedField<TYPE>(GetArena()); \
+ new (field_ptr) RepeatedField<TYPE>(arena); \
} \
break;
@@ -391,7 +392,7 @@
if (!field->is_repeated()) {
new (field_ptr) int{field->default_value_enum()->number()};
} else {
- new (field_ptr) RepeatedField<int>(GetArena());
+ new (field_ptr) RepeatedField<int>(arena);
}
break;
@@ -403,7 +404,7 @@
ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr();
asp->InitDefault();
} else {
- new (field_ptr) RepeatedPtrField<std::string>(GetArena());
+ new (field_ptr) RepeatedPtrField<std::string>(arena);
}
break;
}
@@ -418,20 +419,20 @@
// when the constructor is called inside GetPrototype(), in which
// case we have already locked the factory.
if (lock_factory) {
- if (GetArena() != nullptr) {
+ if (arena != nullptr) {
new (field_ptr) DynamicMapField(
type_info_->factory->GetPrototype(field->message_type()),
- GetArena());
+ arena);
} else {
new (field_ptr) DynamicMapField(
type_info_->factory->GetPrototype(field->message_type()));
}
} else {
- if (GetArena() != nullptr) {
+ if (arena != nullptr) {
new (field_ptr)
DynamicMapField(type_info_->factory->GetPrototypeNoLock(
field->message_type()),
- GetArena());
+ arena);
} else {
new (field_ptr)
DynamicMapField(type_info_->factory->GetPrototypeNoLock(
@@ -439,7 +440,7 @@
}
}
} else {
- new (field_ptr) RepeatedPtrField<Message>(GetArena());
+ new (field_ptr) RepeatedPtrField<Message>(arena);
}
}
break;
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 32528d4..0a67b05 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -630,38 +630,40 @@
ClearExtension(number);
return;
}
- ABSL_DCHECK(message->GetArena() == nullptr || message->GetArena() == arena_);
- Arena* message_arena = message->GetArena();
+ Arena* const arena = arena_;
+ Arena* const message_arena = message->GetArena();
+ ABSL_DCHECK(message_arena == nullptr || message_arena == arena);
+
Extension* extension;
if (MaybeNewExtension(number, descriptor, &extension)) {
extension->type = type;
ABSL_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
extension->is_repeated = false;
extension->is_lazy = false;
- if (message_arena == arena_) {
+ if (message_arena == arena) {
extension->message_value = message;
} else if (message_arena == nullptr) {
extension->message_value = message;
- arena_->Own(message); // not nullptr because not equal to message_arena
+ arena->Own(message); // not nullptr because not equal to message_arena
} else {
- extension->message_value = message->New(arena_);
+ extension->message_value = message->New(arena);
extension->message_value->CheckTypeAndMergeFrom(*message);
}
} else {
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
if (extension->is_lazy) {
- extension->lazymessage_value->SetAllocatedMessage(message, arena_);
+ extension->lazymessage_value->SetAllocatedMessage(message, arena);
} else {
- if (arena_ == nullptr) {
+ if (arena == nullptr) {
delete extension->message_value;
}
- if (message_arena == arena_) {
+ if (message_arena == arena) {
extension->message_value = message;
} else if (message_arena == nullptr) {
extension->message_value = message;
- arena_->Own(message); // not nullptr because not equal to message_arena
+ arena->Own(message); // not nullptr because not equal to message_arena
} else {
- extension->message_value = message->New(arena_);
+ extension->message_value = message->New(arena);
extension->message_value->CheckTypeAndMergeFrom(*message);
}
}
@@ -708,8 +710,9 @@
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
MessageLite* ret = nullptr;
if (extension->is_lazy) {
- ret = extension->lazymessage_value->ReleaseMessage(prototype, arena_);
- if (arena_ == nullptr) {
+ Arena* const arena = arena_;
+ ret = extension->lazymessage_value->ReleaseMessage(prototype, arena);
+ if (arena == nullptr) {
delete extension->lazymessage_value;
}
} else {
@@ -737,9 +740,10 @@
ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
MessageLite* ret = nullptr;
if (extension->is_lazy) {
+ Arena* const arena = arena_;
ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype,
- arena_);
- if (arena_ == nullptr) {
+ arena);
+ if (arena == nullptr) {
delete extension->lazymessage_value;
}
} else {
@@ -994,10 +998,11 @@
HANDLE_TYPE(STRING, string, RepeatedPtrField<std::string>);
#undef HANDLE_TYPE
- case WireFormatLite::CPPTYPE_MESSAGE:
+ case WireFormatLite::CPPTYPE_MESSAGE: {
+ Arena* const arena = arena_;
if (is_new) {
extension->repeated_message_value =
- Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
+ Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena);
}
// We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
// it would attempt to allocate new objects.
@@ -1010,12 +1015,13 @@
extension->repeated_message_value)
->AddFromCleared<GenericTypeHandler<MessageLite>>();
if (target == nullptr) {
- target = other_message.New(arena_);
+ target = other_message.New(arena);
extension->repeated_message_value->AddAllocated(target);
}
target->CheckTypeAndMergeFrom(other_message);
}
break;
+ }
}
} else {
if (!other_extension.is_cleared) {
@@ -1041,6 +1047,7 @@
other_extension.descriptor);
break;
case WireFormatLite::CPPTYPE_MESSAGE: {
+ Arena* const arena = arena_;
Extension* extension;
bool is_new =
MaybeNewExtension(number, other_extension.descriptor, &extension);
@@ -1051,14 +1058,14 @@
if (other_extension.is_lazy) {
extension->is_lazy = true;
extension->lazymessage_value =
- other_extension.lazymessage_value->New(arena_);
+ other_extension.lazymessage_value->New(arena);
extension->lazymessage_value->MergeFrom(
GetPrototypeForLazyMessage(extendee, number),
- *other_extension.lazymessage_value, arena_);
+ *other_extension.lazymessage_value, arena);
} else {
extension->is_lazy = false;
extension->message_value =
- other_extension.message_value->New(arena_);
+ other_extension.message_value->New(arena);
extension->message_value->CheckTypeAndMergeFrom(
*other_extension.message_value);
}
@@ -1070,7 +1077,7 @@
if (extension->is_lazy) {
extension->lazymessage_value->MergeFrom(
GetPrototypeForLazyMessage(extendee, number),
- *other_extension.lazymessage_value, arena_);
+ *other_extension.lazymessage_value, arena);
} else {
extension->message_value->CheckTypeAndMergeFrom(
other_extension.lazymessage_value->GetMessage(
@@ -1079,7 +1086,7 @@
} else {
if (extension->is_lazy) {
extension->lazymessage_value
- ->MutableMessage(*other_extension.message_value, arena_)
+ ->MutableMessage(*other_extension.message_value, arena)
->CheckTypeAndMergeFrom(*other_extension.message_value);
} else {
extension->message_value->CheckTypeAndMergeFrom(
@@ -1097,9 +1104,9 @@
void ExtensionSet::Swap(const MessageLite* extendee, ExtensionSet* other) {
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
- if (GetArena() != nullptr && GetArena() == other->GetArena()) {
+ if (arena_ != nullptr && arena_ == other->arena_) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
- if (GetArena() == other->GetArena()) {
+ if (arena_ == other->arena_) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
InternalSwap(other);
} else {
@@ -1127,7 +1134,9 @@
ExtensionSet* other, int number) {
if (this == other) return;
- if (GetArena() == other->GetArena()) {
+ Arena* const arena = arena_;
+ Arena* const other_arena = other->arena_;
+ if (arena == other_arena) {
UnsafeShallowSwapExtension(other, number);
return;
}
@@ -1144,23 +1153,20 @@
// We do it this way to reuse the copy-across-arenas logic already
// implemented in ExtensionSet's MergeFrom.
ExtensionSet temp;
- temp.InternalExtensionMergeFrom(extendee, number, *other_ext,
- other->GetArena());
+ temp.InternalExtensionMergeFrom(extendee, number, *other_ext, other_arena);
Extension* temp_ext = temp.FindOrNull(number);
other_ext->Clear();
- other->InternalExtensionMergeFrom(extendee, number, *this_ext,
- this->GetArena());
+ other->InternalExtensionMergeFrom(extendee, number, *this_ext, arena);
this_ext->Clear();
InternalExtensionMergeFrom(extendee, number, *temp_ext, temp.GetArena());
} else if (this_ext == nullptr) {
- InternalExtensionMergeFrom(extendee, number, *other_ext, other->GetArena());
- if (other->GetArena() == nullptr) other_ext->Free();
+ InternalExtensionMergeFrom(extendee, number, *other_ext, other_arena);
+ if (other_arena == nullptr) other_ext->Free();
other->Erase(number);
} else {
- other->InternalExtensionMergeFrom(extendee, number, *this_ext,
- this->GetArena());
- if (GetArena() == nullptr) this_ext->Free();
+ other->InternalExtensionMergeFrom(extendee, number, *this_ext, arena);
+ if (arena == nullptr) this_ext->Free();
Erase(number);
}
}
@@ -1173,7 +1179,7 @@
if (this_ext == other_ext) return;
- ABSL_DCHECK_EQ(GetArena(), other->GetArena());
+ ABSL_DCHECK_EQ(arena_, other->arena_);
if (this_ext != nullptr && other_ext != nullptr) {
std::swap(*this_ext, *other_ext);
@@ -1189,16 +1195,17 @@
bool ExtensionSet::IsInitialized(const MessageLite* extendee) const {
// Extensions are never required. However, we need to check that all
// embedded messages are initialized.
+ Arena* const arena = arena_;
if (PROTOBUF_PREDICT_FALSE(is_large())) {
for (const auto& kv : *map_.large) {
- if (!kv.second.IsInitialized(this, extendee, kv.first, arena_)) {
+ if (!kv.second.IsInitialized(this, extendee, kv.first, arena)) {
return false;
}
}
return true;
}
for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) {
- if (!it->second.IsInitialized(this, extendee, it->first, arena_)) {
+ if (!it->second.IsInitialized(this, extendee, it->first, arena)) {
return false;
}
}
@@ -1639,8 +1646,9 @@
const KeyValue* begin = flat_begin();
const KeyValue* end = flat_end();
AllocatedData new_map;
+ Arena* const arena = arena_;
if (new_flat_capacity > kMaximumFlatCapacity) {
- new_map.large = Arena::Create<LargeMap>(arena_);
+ new_map.large = Arena::Create<LargeMap>(arena);
LargeMap::iterator hint = new_map.large->begin();
for (const KeyValue* it = begin; it != end; ++it) {
hint = new_map.large->insert(hint, {it->first, it->second});
@@ -1648,11 +1656,11 @@
flat_size_ = static_cast<uint16_t>(-1);
ABSL_DCHECK(is_large());
} else {
- new_map.flat = Arena::CreateArray<KeyValue>(arena_, new_flat_capacity);
+ new_map.flat = Arena::CreateArray<KeyValue>(arena, new_flat_capacity);
std::copy(begin, end, new_map.flat);
}
- if (arena_ == nullptr) {
+ if (arena == nullptr) {
DeleteFlatMap(begin, flat_capacity_);
}
flat_capacity_ = new_flat_capacity;
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index eb60d5f..c75c290 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -1044,21 +1044,24 @@
}
}
-void Reflection::Swap(Message* message1, Message* message2) const {
- if (message1 == message2) return;
+void Reflection::Swap(Message* lhs, Message* rhs) const {
+ if (lhs == rhs) return;
+
+ Arena* lhs_arena = lhs->GetArena();
+ Arena* rhs_arena = rhs->GetArena();
// TODO: Other Reflection methods should probably check this too.
- ABSL_CHECK_EQ(message1->GetReflection(), this)
+ ABSL_CHECK_EQ(lhs->GetReflection(), this)
<< "First argument to Swap() (of type \""
- << message1->GetDescriptor()->full_name()
+ << lhs->GetDescriptor()->full_name()
<< "\") is not compatible with this reflection object (which is for type "
"\""
<< descriptor_->full_name()
<< "\"). Note that the exact same class is required; not just the same "
"descriptor.";
- ABSL_CHECK_EQ(message2->GetReflection(), this)
+ ABSL_CHECK_EQ(rhs->GetReflection(), this)
<< "Second argument to Swap() (of type \""
- << message2->GetDescriptor()->full_name()
+ << rhs->GetDescriptor()->full_name()
<< "\") is not compatible with this reflection object (which is for type "
"\""
<< descriptor_->full_name()
@@ -1068,32 +1071,31 @@
// Check that both messages are in the same arena (or both on the heap). We
// need to copy all data if not, due to ownership semantics.
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
- if (message1->GetArena() == nullptr ||
- message1->GetArena() != message2->GetArena()) {
+ if (lhs_arena == nullptr || lhs_arena != rhs_arena) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
- if (message1->GetArena() != message2->GetArena()) {
+ if (lhs_arena != rhs_arena) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
// One of the two is guaranteed to have an arena. Switch things around
- // to guarantee that message1 has an arena.
- Arena* arena = message1->GetArena();
+ // to guarantee that lhs has an arena.
+ Arena* arena = lhs_arena;
if (arena == nullptr) {
- arena = message2->GetArena();
- std::swap(message1, message2); // Swapping names for pointers!
+ arena = rhs_arena;
+ std::swap(lhs, rhs); // Swapping names for pointers!
}
- Message* temp = message1->New(arena);
- temp->MergeFrom(*message2);
- message2->CopyFrom(*message1);
+ Message* temp = lhs->New(arena);
+ temp->MergeFrom(*rhs);
+ rhs->CopyFrom(*lhs);
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
- message1->CopyFrom(*temp);
+ lhs->CopyFrom(*temp);
if (arena == nullptr) delete temp;
#else // PROTOBUF_FORCE_COPY_IN_SWAP
- Swap(message1, temp);
+ Swap(lhs, temp);
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
return;
}
- UnsafeArenaSwap(message1, message2);
+ UnsafeArenaSwap(lhs, rhs);
}
template <bool unsafe_shallow_swap>
@@ -2318,27 +2320,34 @@
ABSL_DCHECK(sub_message == nullptr || sub_message->GetArena() == nullptr ||
sub_message->GetArena() == message->GetArena());
+ if (sub_message == nullptr) {
+ UnsafeArenaSetAllocatedMessage(message, nullptr, field);
+ return;
+ }
+
+ Arena* arena = message->GetArena();
+ Arena* sub_arena = sub_message->GetArena();
+ if (arena == sub_arena) {
+ UnsafeArenaSetAllocatedMessage(message, sub_message, field);
+ return;
+ }
+
// If message and sub-message are in different memory ownership domains
// (different arenas, or one is on heap and one is not), then we may need to
// do a copy.
- if (sub_message != nullptr &&
- sub_message->GetArena() != message->GetArena()) {
- if (sub_message->GetArena() == nullptr && message->GetArena() != nullptr) {
- // Case 1: parent is on an arena and child is heap-allocated. We can add
- // the child to the arena's Own() list to free on arena destruction, then
- // set our pointer.
- message->GetArena()->Own(sub_message);
- UnsafeArenaSetAllocatedMessage(message, sub_message, field);
- } else {
- // Case 2: all other cases. We need to make a copy. MutableMessage() will
- // either get the existing message object, or instantiate a new one as
- // appropriate w.r.t. our arena.
- Message* sub_message_copy = MutableMessage(message, field);
- sub_message_copy->CopyFrom(*sub_message);
- }
- } else {
- // Same memory ownership domains.
+ if (sub_arena == nullptr) {
+ ABSL_DCHECK_NE(arena, nullptr);
+ // Case 1: parent is on an arena and child is heap-allocated. We can add
+ // the child to the arena's Own() list to free on arena destruction, then
+ // set our pointer.
+ arena->Own(sub_message);
UnsafeArenaSetAllocatedMessage(message, sub_message, field);
+ } else {
+ // Case 2: all other cases. We need to make a copy. MutableMessage() will
+ // either get the existing message object, or instantiate a new one as
+ // appropriate w.r.t. our arena.
+ Message* sub_message_copy = MutableMessage(message, field);
+ sub_message_copy->CopyFrom(*sub_message);
}
}
diff --git a/src/google/protobuf/repeated_ptr_field.cc b/src/google/protobuf/repeated_ptr_field.cc
index 2afe3ad..929131c 100644
--- a/src/google/protobuf/repeated_ptr_field.cc
+++ b/src/google/protobuf/repeated_ptr_field.cc
@@ -97,10 +97,11 @@
template <typename F>
auto* RepeatedPtrFieldBase::AddInternal(F factory) {
- using Result = decltype(factory(GetArena()));
+ Arena* const arena = GetArena();
+ using Result = decltype(factory(arena));
if (tagged_rep_or_elem_ == nullptr) {
ExchangeCurrentSize(1);
- tagged_rep_or_elem_ = factory(GetArena());
+ tagged_rep_or_elem_ = factory(arena);
return static_cast<Result>(tagged_rep_or_elem_);
}
if (using_sso()) {
@@ -122,7 +123,7 @@
Rep* r = rep();
++r->allocated_size;
void*& result = r->elements[ExchangeCurrentSize(current_size_ + 1)];
- result = factory(GetArena());
+ result = factory(arena);
return static_cast<Result>(result);
}