1 // Copyright 2018 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_DIRECT_MAP_EXTENT_H_ 6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_DIRECT_MAP_EXTENT_H_ 7 8 #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h" 9 #include "base/allocator/partition_allocator/partition_alloc_check.h" 10 #include "base/allocator/partition_allocator/partition_bucket.h" 11 #include "base/allocator/partition_allocator/partition_page.h" 12 13 namespace partition_alloc::internal { 14 15 template <bool thread_safe> 16 struct PartitionDirectMapExtent { 17 PartitionDirectMapExtent<thread_safe>* next_extent; 18 PartitionDirectMapExtent<thread_safe>* prev_extent; 19 PartitionBucket<thread_safe>* bucket; 20 // Size of the entire reservation, including guard pages, meta-data, 21 // padding for alignment before allocation, and padding for granularity at the 22 // end of the allocation. 23 size_t reservation_size; 24 // Padding between the first partition page (guard pages + meta-data) and 25 // the allocation. 26 size_t padding_for_alignment; 27 28 PA_ALWAYS_INLINE static PartitionDirectMapExtent<thread_safe>* FromSlotSpan( 29 SlotSpanMetadata<thread_safe>* slot_span); 30 }; 31 32 // Metadata page for direct-mapped allocations. 33 template <bool thread_safe> 34 struct PartitionDirectMapMetadata { 35 // |page| and |subsequent_page| are needed to match the layout of normal 36 // buckets (specifically, of single-slot slot spans), with the caveat that 37 // only the first subsequent page is needed (for SubsequentPageMetadata) and 38 // others aren't used for direct map. 39 PartitionPage<thread_safe> page; 40 PartitionPage<thread_safe> subsequent_page; 41 // The following fields are metadata specific to direct map allocations. All 42 // these fields will easily fit into the precalculated metadata region, 43 // because a direct map allocation starts no further than half way through the 44 // super page. 45 PartitionBucket<thread_safe> bucket; 46 PartitionDirectMapExtent<thread_safe> direct_map_extent; 47 48 PA_ALWAYS_INLINE static PartitionDirectMapMetadata<thread_safe>* FromSlotSpan( 49 SlotSpanMetadata<thread_safe>* slot_span); 50 }; 51 52 template <bool thread_safe> 53 PA_ALWAYS_INLINE PartitionDirectMapMetadata<thread_safe>* FromSlotSpan(SlotSpanMetadata<thread_safe> * slot_span)54PartitionDirectMapMetadata<thread_safe>::FromSlotSpan( 55 SlotSpanMetadata<thread_safe>* slot_span) { 56 PA_DCHECK(slot_span->bucket->is_direct_mapped()); 57 // |*slot_span| is the first field of |PartitionDirectMapMetadata|, just cast. 58 auto* metadata = 59 reinterpret_cast<PartitionDirectMapMetadata<thread_safe>*>(slot_span); 60 PA_DCHECK(&metadata->page.slot_span_metadata == slot_span); 61 return metadata; 62 } 63 64 template <bool thread_safe> 65 PA_ALWAYS_INLINE PartitionDirectMapExtent<thread_safe>* FromSlotSpan(SlotSpanMetadata<thread_safe> * slot_span)66PartitionDirectMapExtent<thread_safe>::FromSlotSpan( 67 SlotSpanMetadata<thread_safe>* slot_span) { 68 PA_DCHECK(slot_span->bucket->is_direct_mapped()); 69 return &PartitionDirectMapMetadata<thread_safe>::FromSlotSpan(slot_span) 70 ->direct_map_extent; 71 } 72 73 } // namespace partition_alloc::internal 74 75 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_DIRECT_MAP_EXTENT_H_ 76