unsafe_arena_set_allcoated* and unsafe_arena_release* API are "unsafe" 
APIs, callers should know what they are doing.
Why not remove arena checking in all generated unsafe_arena_release*  code? 
This will make unsafe_arena* APIs work for both arena-allocated and heap 
allocated objects. It seems a straightforward change to me, arena checking 
in unsafe_arena_release*  does not always happen anyway.

On Tuesday, May 5, 2020 at 4:20:33 PM UTC-7, King Kong wrote:
>
> Thanks for your reply.
>
> Yes, I have been using arena, but I wanted to do better than batching heap 
> allocation, when possible. The "scoped leasing" use case I described above 
> achieve 0 heap allocation all the time. I guess my code could use 
> GetArena() at runtime to decide how the "leasing" object is created and 
> which set of set&release APIs to use.
>
> On Tuesday, May 5, 2020 at 2:25:05 PM UTC-7, Josh Haberman wrote:
>>
>> The documentation for unsafe_arena_release_foo() says:
>>
>> > This method should only be used when the parent message is on the arena 
>> and the submessage is on the same arena, or an arena with equivalent 
>> lifetime.
>>
>> The DCHECK() you highlighted is checking the first part of this 
>> requirement.
>>
>> Stack/heap-allocated messages must always uniquely own their 
>> sub-messages, which must always be on the heap. Protobuf doesn't support 
>> the use case you are describing, where a message temporarily points to a 
>> message it doesn't own. If we allowed that, protobuf itself would crash if 
>> a message in this state was ever destroyed.
>>
>> If you are trying to avoid heap allocation overhead, the recommended 
>> solution is arenas.
>>
>> On Tuesday, May 5, 2020 at 12:44:32 PM UTC-7, King Kong wrote:
>>>
>>> I am using unsafe_arena_set_allocated_* and unsafe_arena_release_* APIs 
>>> to avoid
>>> unnecessary allocations when the sub-objects are only used in a function 
>>> scope,
>>> unsafe_arena_release_* is always called before leaving the scope. At the 
>>> beginning,
>>>
>>> I chose to always use the arena versions of unsafe APIs because the 
>>> non-arena version 
>>>
>>> unsafe_release does extra allocation when the object is allocated on 
>>> arena, and the arena
>>>
>>> version does not check if the object is allocated in arena, based on 
>>> generated code like 
>>>
>>> the following:
>>>
>>>
>>> inline foo* outter1::unsafe_arena_release_foo() {
>>> foo* temp = foo_;
>>> foo_ = nullptr;
>>> return temp;
>>> }
>>>
>>>
>>> However, I later also saw the following the generated code with arena 
>>> check, it means it is not okay to call for heap-allocated objects.
>>>
>>> inline void outter2::unsafe_arena_set_allocated_bar(
>>> std::string* bar) {
>>> GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr);
>>> ... ...
>>> }
>>>
>>>
>>> So, why the discrepancy?
>>>
>>>
>>> The official documentation at 
>>> https://developers.google.com/protocol-buffers/docs/reference/arenas says 
>>> the correct set of APIs should be used
>>>
>>> according to how to the object is allocated, but having two different 
>>> sets of unsafe APIs makes it harder to use, and it makes the code less 
>>> robust to future changes. I am wondering if protobuf owners also realize 
>>> such an issue and start to remove arena checking gradually? It that the 
>>> case? I would like to hear how others think.
>>>
>>>
>>> Thanks.
>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/protobuf/5463ff7f-a519-44fb-9445-1971cd80d61e%40googlegroups.com.

Reply via email to