Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:06

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 #ifndef GOOGLE_PROTOBUF_ARENA_ALLOCATION_POLICY_H__
0009 #define GOOGLE_PROTOBUF_ARENA_ALLOCATION_POLICY_H__
0010 
0011 #include <cstddef>
0012 #include <cstdint>
0013 
0014 namespace google {
0015 namespace protobuf {
0016 namespace internal {
0017 
0018 // `AllocationPolicy` defines `Arena` allocation policies. Applications can
0019 // customize the initial and maximum sizes for arena allocation, as well as set
0020 // custom allocation and deallocation functions. `AllocationPolicy` is for
0021 // protocol buffer internal use only, and typically created from a user facing
0022 // public configuration class such as `ArenaOptions`.
0023 struct AllocationPolicy {
0024   static constexpr size_t kDefaultStartBlockSize = 256;
0025   static constexpr size_t kDefaultMaxBlockSize = 32 << 10;
0026 
0027   size_t start_block_size = kDefaultStartBlockSize;
0028   size_t max_block_size = kDefaultMaxBlockSize;
0029 
0030   void* (*block_alloc)(size_t) = nullptr;
0031   void (*block_dealloc)(void*, size_t) = nullptr;
0032 
0033   bool IsDefault() const {
0034     return start_block_size == kDefaultStartBlockSize &&
0035            max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr &&
0036            block_dealloc == nullptr;
0037   }
0038 };
0039 
0040 // Tagged pointer to an AllocationPolicy.
0041 class TaggedAllocationPolicyPtr {
0042  public:
0043   constexpr TaggedAllocationPolicyPtr() : policy_(0) {}
0044 
0045   explicit TaggedAllocationPolicyPtr(AllocationPolicy* policy)
0046       : policy_(reinterpret_cast<uintptr_t>(policy)) {}
0047 
0048   void set_policy(AllocationPolicy* policy) {
0049     auto bits = policy_ & kTagsMask;
0050     policy_ = reinterpret_cast<uintptr_t>(policy) | bits;
0051   }
0052 
0053   AllocationPolicy* get() {
0054     return reinterpret_cast<AllocationPolicy*>(policy_ & kPtrMask);
0055   }
0056   const AllocationPolicy* get() const {
0057     return reinterpret_cast<const AllocationPolicy*>(policy_ & kPtrMask);
0058   }
0059 
0060   AllocationPolicy& operator*() { return *get(); }
0061   const AllocationPolicy& operator*() const { return *get(); }
0062 
0063   AllocationPolicy* operator->() { return get(); }
0064   const AllocationPolicy* operator->() const { return get(); }
0065 
0066   bool is_user_owned_initial_block() const {
0067     return static_cast<bool>(get_mask<kUserOwnedInitialBlock>());
0068   }
0069   void set_is_user_owned_initial_block(bool v) {
0070     set_mask<kUserOwnedInitialBlock>(v);
0071   }
0072 
0073   uintptr_t get_raw() const { return policy_; }
0074 
0075  private:
0076   enum : uintptr_t {
0077     kUserOwnedInitialBlock = 1,
0078   };
0079 
0080   static constexpr uintptr_t kTagsMask = 7;
0081   static constexpr uintptr_t kPtrMask = ~kTagsMask;
0082 
0083   template <uintptr_t kMask>
0084   uintptr_t get_mask() const {
0085     return policy_ & kMask;
0086   }
0087   template <uintptr_t kMask>
0088   void set_mask(bool v) {
0089     if (v) {
0090       policy_ |= kMask;
0091     } else {
0092       policy_ &= ~kMask;
0093     }
0094   }
0095   uintptr_t policy_;
0096 };
0097 
0098 }  // namespace internal
0099 }  // namespace protobuf
0100 }  // namespace google
0101 
0102 #endif  // GOOGLE_PROTOBUF_ARENA_ALLOCATION_POLICY_H__