• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)54 PartitionDirectMapMetadata<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)66 PartitionDirectMapExtent<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