<commit_before>#include "gc.hh"
#include "atomic.hh"
#include "radix.hh"
#include "cpputil.hh"
#include "hwvm.hh"
#include "uwq.hh"
#include "distref.hh"
#include "bit_spinlock.hh"
#include "radix_array.hh"
#include "kalloc.hh"
#include "page_info.hh"

struct padded_length;

using std::atomic;

// A virtual memory descriptor that maintains metadata for pages in an
// address space.  This plays a similar role to the more traditional
// "virtual memory area," but this does not know its size (it could
// represent a single page or the entire address space).
struct vmdesc
{
  enum {
    // Bit used for radix tree range locking
    FLAG_LOCK_BIT = 0,
    FLAG_LOCK = 1<<FLAG_LOCK_BIT,

    // Set if this virtual page frame has been mapped
    FLAG_MAPPED = 1<<1,

    // Set if this virtual page frame is copy-on-write.  A write fault
    // to this page frame should copy page and unset the COW bit.  A
    // read fault should map the existing page read-only.  This flag
    // should be zero if this VPF has no backing page.
    FLAG_COW = 1<<2,

    // Set if this page frame maps anonymous memory.  Cleared if this
    // page frame maps a file (in which case ip and start are used).
    FLAG_ANON = 1<<3,
  };

  // Flags
  u64 flags;

  // The physical page mapped in this frame, or null if no page has
  // been allocated for this frame.
  sref<class page_info> page;

  // XXX We could pack the following fields into a union if there's
  // anything we can overlap with them for anonymous memory.  However,
  // then we have to use C++11 unrestricted unions because of the
  // sref, so we'd have to define all of vmdesc's special methods
  // ourselves.

  // The file mapped at this page frame.
  sref<struct inode> inode;

  // If a file is mapped at this page frame, the virtual address of
  // that file's 0 byte.  For anonymous memory, this must be 0.  We
  // record this instead of the page frame's offset in the file so
  // that a range of page frames mapping a sequence of pages from a
  // file will be identical (and hence compressable in the radix
  // tree).
  intptr_t start;

  // Construct a descriptor for unmapped memory.
  vmdesc() : flags(0), start(0) { }

  // Construct a descriptor that maps the beginning of ip's file to
  // virtual address start (which may be negative).
  vmdesc(const sref<struct inode> &ip, intptr_t start)
    : flags(FLAG_MAPPED), inode(ip), start(start) { }

  // The anonymous memory descriptor.
  static struct vmdesc anon_desc;

  // Radix_array element methods

  bit_spinlock get_lock()
  {
    return bit_spinlock(&flags, FLAG_LOCK_BIT);
  }

  bool is_set() const
  {
    return flags & FLAG_MAPPED;
  }

private:
  constexpr vmdesc(u64 flags)
    : flags(flags), page(), inode(), start() { }
};

void to_stream(class print_stream *s, const vmdesc &vmd);

// An address space. This manages the mapping from virtual addresses
// to virtual memory descriptors.
struct vmap {
  struct radix vmas;

  static vmap* alloc();

  atomic<u64> ref;
  char *const kshared;

  void decref();
  void incref();

  // Copy this vmap's structure and share pages copy-on-write.
  vmap* copy(proc_pgmap* pgmap);

  // Map desc from virtual addresses start to start+len.
  long insert(const vmdesc &desc, uptr start, uptr len, proc_pgmap* pgmap,
              bool dotlb = true);

  // Unmap from virtual addresses start to start+len.
  int remove(uptr start, uptr len, proc_pgmap* pgmap);

  int pagefault(uptr va, u32 err, proc_pgmap* pgmap);

  // Map virtual address va in this address space to a kernel virtual<commit_msg>vm.hh tweaks for clang compatibility<commit_after>#include "gc.hh"
#include "atomic.hh"
#include "radix.hh"
#include "cpputil.hh"
#include "hwvm.hh"
#include "uwq.hh"
#include "distref.hh"
#include "bit_spinlock.hh"
#include "radix_array.hh"
#include "kalloc.hh"
#include "page_info.hh"

struct padded_length;

using std::atomic;

// A virtual memory descriptor that maintains metadata for pages in an
// address space.  This plays a similar role to the more traditional
// "virtual memory area," but this does not know its size (it could
// represent a single page or the entire address space).
struct vmdesc
{
  enum {
    // Bit used for radix tree range locking
    FLAG_LOCK_BIT = 0,
    FLAG_LOCK = 1<<FLAG_LOCK_BIT,

    // Set if this virtual page frame has been mapped
    FLAG_MAPPED = 1<<1,

    // Set if this virtual page frame is copy-on-write.  A write fault
    // to this page frame should copy page and unset the COW bit.  A
    // read fault should map the existing page read-only.  This flag
    // should be zero if this VPF has no backing page.
    FLAG_COW = 1<<2,

    // Set if this page frame maps anonymous memory.  Cleared if this
    // page frame maps a file (in which case ip and start are used).
    FLAG_ANON = 1<<3,
  };

  // Flags
  u64 flags;

  // The physical page mapped in this frame, or null if no page has
  // been allocated for this frame.
  sref<class page_info> page;

  // XXX We could pack the following fields into a union if there's
  // anything we can overlap with them for anonymous memory.  However,
  // then we have to use C++11 unrestricted unions because of the
  // sref, so we'd have to define all of vmdesc's special methods
  // ourselves.

  // The file mapped at this page frame.
  sref<struct inode> inode;

  // If a file is mapped at this page frame, the virtual address of
  // that file's 0 byte.  For anonymous memory, this must be 0.  We
  // record this instead of the page frame's offset in the file so
  // that a range of page frames mapping a sequence of pages from a
  // file will be identical (and hence compressable in the radix
  // tree).
  intptr_t start;

  // Construct a descriptor for unmapped memory.
  vmdesc() : flags(0), start(0) { }

  // Construct a descriptor that maps the beginning of ip's file to
  // virtual address start (which may be negative).
  vmdesc(const sref<struct inode> &ip, intptr_t start)
    : flags(FLAG_MAPPED), inode(ip), start(start) { }

  // The anonymous memory descriptor.
  static struct vmdesc anon_desc;

  // Radix_array element methods

  bit_spinlock get_lock()
  {
    return bit_spinlock(&flags, FLAG_LOCK_BIT);
  }

  bool is_set() const
  {
    return flags & FLAG_MAPPED;
  }

private:
  vmdesc(u64 flags)
    : flags(flags), page(), inode(), start() { }
};

void to_stream(class print_stream *s, const vmdesc &vmd);

// An address space. This manages the mapping from virtual addresses
// to virtual memory descriptors.
struct vmap {
  struct radix vmas;

  static vmap* alloc();

  atomic<u64> ref;
  char *const kshared;

  void decref();
  void incref();

  // Copy this vmap's structure and share pages copy-on-write.
  vmap* copy(proc_pgmap* pgmap);

  // Map desc from virtual addresses start to start+len.
  long insert(const vmdesc &desc, uptr start, uptr len, proc_pgmap* pgmap,
              bool dotlb = true);

  // Unmap from virtual addresses start to start+len.
  int remove(uptr start, uptr len, proc_pgmap* pgmap);

  int pagefault(uptr va, u32 err, proc_pgmap* pgmap);

  // Map virtual address va in this address space to a kernel virtual
{'fraction_non_alphanumeric': 0.09052866508578603, 'fraction_numerical': 0.006137536615985493, 'mean_word_length': 3.0994854202401374, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5153264', 'n_tokens_mistral': 2299, 'n_tokens_neox': 2168, 'n_words': 956}