Path: blob/main/contrib/llvm-project/compiler-rt/lib/memprof/memprof_mapping.h
35236 views
//===-- memprof_mapping.h --------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is a part of MemProfiler, a memory profiler.9//10// Defines MemProf memory mapping.11//===----------------------------------------------------------------------===//12#ifndef MEMPROF_MAPPING_H13#define MEMPROF_MAPPING_H1415#include "memprof_internal.h"1617static const u64 kDefaultShadowScale = 3;18#define SHADOW_SCALE kDefaultShadowScale1920#define SHADOW_OFFSET __memprof_shadow_memory_dynamic_address2122#define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)23#define MEMPROF_ALIGNMENT 3224namespace __memprof {2526extern uptr kHighMemEnd; // Initialized in __memprof_init.2728} // namespace __memprof2930// Size of memory block mapped to a single shadow location31#define MEM_GRANULARITY 64ULL3233#define SHADOW_MASK ~(MEM_GRANULARITY - 1)3435#define MEM_TO_SHADOW(mem) \36((((mem) & SHADOW_MASK) >> SHADOW_SCALE) + (SHADOW_OFFSET))3738// Histogram shadow memory is laid different to the standard configuration:3940// 8 bytes41// +---+---+---+ +---+---+---+ +---+---+---+42// Memory | a | | b | | c |43// +---+---+---+ +---+---+---+ +---+---+---+4445// +---+ +---+ +---+46// Shadow | a | | b | | c |47// +---+ +---+ +---+48// 1 byte49//50// Where we have a 1 byte counter for each 8 bytes. HISTOGRAM_MEM_TO_SHADOW51// translates a memory address to the address of its corresponding shadow52// counter memory address. The same data is still provided in MIB whether53// histograms are used or not. Total access counts per allocations are54// computed by summing up all individual 1 byte counters. This can incur an55// accuracy penalty.5657#define HISTOGRAM_GRANULARITY 8U5859#define HISTOGRAM_MAX_COUNTER 255U6061#define HISTOGRAM_SHADOW_MASK ~(HISTOGRAM_GRANULARITY - 1)6263#define HISTOGRAM_MEM_TO_SHADOW(mem) \64((((mem) & HISTOGRAM_SHADOW_MASK) >> SHADOW_SCALE) + (SHADOW_OFFSET))6566#define SHADOW_ENTRY_SIZE (MEM_GRANULARITY >> SHADOW_SCALE)6768#define kLowMemBeg 069#define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)7071#define kLowShadowBeg SHADOW_OFFSET72#define kLowShadowEnd (MEM_TO_SHADOW(kLowMemEnd) + SHADOW_ENTRY_SIZE - 1)7374#define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1 + SHADOW_ENTRY_SIZE - 1)7576#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)77#define kHighShadowEnd (MEM_TO_SHADOW(kHighMemEnd) + SHADOW_ENTRY_SIZE - 1)7879// With the zero shadow base we can not actually map pages starting from 0.80// This constant is somewhat arbitrary.81#define kZeroBaseShadowStart 082#define kZeroBaseMaxShadowStart (1 << 18)8384#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 : kZeroBaseShadowStart)85#define kShadowGapEnd (kHighShadowBeg - 1)8687namespace __memprof {8889inline uptr MemToShadowSize(uptr size) { return size >> SHADOW_SCALE; }90inline bool AddrIsInLowMem(uptr a) { return a <= kLowMemEnd; }9192inline bool AddrIsInLowShadow(uptr a) {93return a >= kLowShadowBeg && a <= kLowShadowEnd;94}9596inline bool AddrIsInHighMem(uptr a) {97return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;98}99100inline bool AddrIsInHighShadow(uptr a) {101return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;102}103104inline bool AddrIsInShadowGap(uptr a) {105// In zero-based shadow mode we treat addresses near zero as addresses106// in shadow gap as well.107if (SHADOW_OFFSET == 0)108return a <= kShadowGapEnd;109return a >= kShadowGapBeg && a <= kShadowGapEnd;110}111112inline bool AddrIsInMem(uptr a) {113return AddrIsInLowMem(a) || AddrIsInHighMem(a) ||114(flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));115}116117inline uptr MemToShadow(uptr p) {118CHECK(AddrIsInMem(p));119return MEM_TO_SHADOW(p);120}121122inline bool AddrIsInShadow(uptr a) {123return AddrIsInLowShadow(a) || AddrIsInHighShadow(a);124}125126inline bool AddrIsAlignedByGranularity(uptr a) {127return (a & (SHADOW_GRANULARITY - 1)) == 0;128}129130inline void RecordAccess(uptr a) {131// If we use a different shadow size then the type below needs adjustment.132CHECK_EQ(SHADOW_ENTRY_SIZE, 8);133u64 *shadow_address = (u64 *)MEM_TO_SHADOW(a);134(*shadow_address)++;135}136137inline void RecordAccessHistogram(uptr a) {138CHECK_EQ(SHADOW_ENTRY_SIZE, 8);139u8 *shadow_address = (u8 *)HISTOGRAM_MEM_TO_SHADOW(a);140if (*shadow_address < HISTOGRAM_MAX_COUNTER) {141(*shadow_address)++;142}143}144145} // namespace __memprof146147#endif // MEMPROF_MAPPING_H148149150