DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_StupidAllocator_h
#define jit_StupidAllocator_h

#include "jit/RegisterAllocator.h"

// Simple register allocator that only carries registers within basic blocks.

namespace js {
namespace jit {

class StupidAllocator : public RegisterAllocator {
  static const uint32_t MAX_REGISTERS = AnyRegister::Total;
  static const uint32_t MISSING_ALLOCATION = UINT32_MAX;

  struct AllocatedRegister {
    AnyRegister reg;

    // The type of the value in the register.
    LDefinition::Type type;

    // Virtual register this physical reg backs, or MISSING_ALLOCATION.
    uint32_t vreg;

    // id of the instruction which most recently used this register.
    uint32_t age;

    // Whether the physical register is not synced with the backing stack slot.
    bool dirty;

    void set(uint32_t vreg, LInstruction* ins = nullptr, bool dirty = false) {
      this->vreg = vreg;
      this->age = ins ? ins->id() : 0;
      this->dirty = dirty;
    }
  };

  // Active allocation for the current code position.
  mozilla::Array<AllocatedRegister, MAX_REGISTERS> registers;
  uint32_t registerCount;

  // Type indicating an index into registers.
  typedef uint32_t RegisterIndex;

  // Information about each virtual register.
  Vector<LDefinition*, 0, SystemAllocPolicy> virtualRegisters;

 public:
  StupidAllocator(MIRGenerator* mir, LIRGenerator* lir, LIRGraph& graph)
      : RegisterAllocator(mir, lir, graph), registerCount(0) {}

  MOZ_MUST_USE bool go();

 private:
  MOZ_MUST_USE bool init();

  void syncForBlockEnd(LBlock* block, LInstruction* ins);
  void allocateForInstruction(LInstruction* ins);
  void allocateForDefinition(LInstruction* ins, LDefinition* def);

  LAllocation* stackLocation(uint32_t vreg);

  RegisterIndex registerIndex(AnyRegister reg);

  AnyRegister ensureHasRegister(LInstruction* ins, uint32_t vreg);
  RegisterIndex allocateRegister(LInstruction* ins, uint32_t vreg);

  void syncRegister(LInstruction* ins, RegisterIndex index);
  void evictRegister(LInstruction* ins, RegisterIndex index);
  void evictAliasedRegister(LInstruction* ins, RegisterIndex index);
  void loadRegister(LInstruction* ins, uint32_t vreg, RegisterIndex index,
                    LDefinition::Type type);

  RegisterIndex findExistingRegister(uint32_t vreg);

  bool allocationRequiresRegister(const LAllocation* alloc, AnyRegister reg);
  bool registerIsReserved(LInstruction* ins, AnyRegister reg);
};

}  // namespace jit
}  // namespace js

#endif /* jit_StupidAllocator_h */