blob: 34889b2bcf18bfb8a0c23400b7204e498652ce0f [file]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PARTITION_ALLOC_PARTITION_DIRECT_MAP_EXTENT_H_
#define PARTITION_ALLOC_PARTITION_DIRECT_MAP_EXTENT_H_
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_bucket.h"
#include "partition_alloc/partition_page.h"
namespace partition_alloc::internal {
struct PartitionDirectMapExtent {
PartitionDirectMapExtent* next_extent;
PartitionDirectMapExtent* prev_extent;
PartitionBucket* bucket;
// Size of the entire reservation, including guard pages, meta-data,
// padding for alignment before allocation, and padding for granularity at the
// end of the allocation.
size_t reservation_size;
// Padding between the first partition page (guard pages + meta-data) and
// the allocation.
size_t padding_for_alignment;
PA_ALWAYS_INLINE static PartitionDirectMapExtent* FromSlotSpanMetadata(
SlotSpanMetadata* slot_span);
};
// Metadata page for direct-mapped allocations.
struct PartitionDirectMapMetadata {
// |page_metadata| and |second_page_metadata| are needed to match the
// layout of normal buckets (specifically, of single-slot slot spans), with
// the caveat that only the first subsequent page is needed (for
// SubsequentPageMetadata) and others aren't used for direct map.
PartitionPageMetadata page_metadata;
PartitionPageMetadata second_page_metadata;
// The following fields are metadata specific to direct map allocations. All
// these fields will easily fit into the precalculated metadata region,
// because a direct map allocation starts no further than half way through the
// super page.
PartitionBucket bucket;
PartitionDirectMapExtent direct_map_extent;
PA_ALWAYS_INLINE static PartitionDirectMapMetadata* FromSlotSpanMetadata(
SlotSpanMetadata* slot_span);
};
PA_ALWAYS_INLINE PartitionDirectMapMetadata*
PartitionDirectMapMetadata::FromSlotSpanMetadata(SlotSpanMetadata* slot_span) {
PA_DCHECK(slot_span->bucket->is_direct_mapped());
// |*slot_span| is the first field of |PartitionDirectMapMetadata|, just cast.
auto* metadata = reinterpret_cast<PartitionDirectMapMetadata*>(slot_span);
PA_DCHECK(&metadata->page_metadata.slot_span_metadata == slot_span);
return metadata;
}
PA_ALWAYS_INLINE PartitionDirectMapExtent*
PartitionDirectMapExtent::FromSlotSpanMetadata(SlotSpanMetadata* slot_span) {
PA_DCHECK(slot_span->bucket->is_direct_mapped());
return &PartitionDirectMapMetadata::FromSlotSpanMetadata(slot_span)
->direct_map_extent;
}
} // namespace partition_alloc::internal
#endif // PARTITION_ALLOC_PARTITION_DIRECT_MAP_EXTENT_H_