memprof_mapping.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //===-- memprof_mapping.h --------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of MemProfiler, a memory profiler.
  10. //
  11. // Defines MemProf memory mapping.
  12. //===----------------------------------------------------------------------===//
  13. #ifndef MEMPROF_MAPPING_H
  14. #define MEMPROF_MAPPING_H
  15. #include "memprof_internal.h"
  16. static const u64 kDefaultShadowScale = 3;
  17. #define SHADOW_SCALE kDefaultShadowScale
  18. #define SHADOW_OFFSET __memprof_shadow_memory_dynamic_address
  19. #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)
  20. #define MEMPROF_ALIGNMENT 32
  21. namespace __memprof {
  22. extern uptr kHighMemEnd; // Initialized in __memprof_init.
  23. } // namespace __memprof
  24. #define SHADOW_ENTRY_SIZE 8
  25. // Size of memory block mapped to a single shadow location
  26. #define MEM_GRANULARITY 64ULL
  27. #define SHADOW_MASK ~(MEM_GRANULARITY - 1)
  28. #define MEM_TO_SHADOW(mem) \
  29. ((((mem) & SHADOW_MASK) >> SHADOW_SCALE) + (SHADOW_OFFSET))
  30. #define kLowMemBeg 0
  31. #define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)
  32. #define kLowShadowBeg SHADOW_OFFSET
  33. #define kLowShadowEnd (MEM_TO_SHADOW(kLowMemEnd) + SHADOW_ENTRY_SIZE - 1)
  34. #define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1 + SHADOW_ENTRY_SIZE - 1)
  35. #define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
  36. #define kHighShadowEnd (MEM_TO_SHADOW(kHighMemEnd) + SHADOW_ENTRY_SIZE - 1)
  37. // With the zero shadow base we can not actually map pages starting from 0.
  38. // This constant is somewhat arbitrary.
  39. #define kZeroBaseShadowStart 0
  40. #define kZeroBaseMaxShadowStart (1 << 18)
  41. #define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 : kZeroBaseShadowStart)
  42. #define kShadowGapEnd (kHighShadowBeg - 1)
  43. namespace __memprof {
  44. inline uptr MemToShadowSize(uptr size) { return size >> SHADOW_SCALE; }
  45. inline bool AddrIsInLowMem(uptr a) { return a <= kLowMemEnd; }
  46. inline bool AddrIsInLowShadow(uptr a) {
  47. return a >= kLowShadowBeg && a <= kLowShadowEnd;
  48. }
  49. inline bool AddrIsInHighMem(uptr a) {
  50. return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
  51. }
  52. inline bool AddrIsInHighShadow(uptr a) {
  53. return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
  54. }
  55. inline bool AddrIsInShadowGap(uptr a) {
  56. // In zero-based shadow mode we treat addresses near zero as addresses
  57. // in shadow gap as well.
  58. if (SHADOW_OFFSET == 0)
  59. return a <= kShadowGapEnd;
  60. return a >= kShadowGapBeg && a <= kShadowGapEnd;
  61. }
  62. inline bool AddrIsInMem(uptr a) {
  63. return AddrIsInLowMem(a) || AddrIsInHighMem(a) ||
  64. (flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));
  65. }
  66. inline uptr MemToShadow(uptr p) {
  67. CHECK(AddrIsInMem(p));
  68. return MEM_TO_SHADOW(p);
  69. }
  70. inline bool AddrIsInShadow(uptr a) {
  71. return AddrIsInLowShadow(a) || AddrIsInHighShadow(a);
  72. }
  73. inline bool AddrIsAlignedByGranularity(uptr a) {
  74. return (a & (SHADOW_GRANULARITY - 1)) == 0;
  75. }
  76. inline void RecordAccess(uptr a) {
  77. // If we use a different shadow size then the type below needs adjustment.
  78. CHECK_EQ(SHADOW_ENTRY_SIZE, 8);
  79. u64 *shadow_address = (u64 *)MEM_TO_SHADOW(a);
  80. (*shadow_address)++;
  81. }
  82. } // namespace __memprof
  83. #endif // MEMPROF_MAPPING_H