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