tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StackSlotAllocator.h (3416B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef jit_StackSlotAllocator_h
      8 #define jit_StackSlotAllocator_h
      9 
     10 #include "jit/LIR.h"
     11 #include "jit/Registers.h"
     12 
     13 namespace js {
     14 namespace jit {
     15 
     16 class StackSlotAllocator {
     17  js::Vector<uint32_t, 4, SystemAllocPolicy> normalSlots;
     18  js::Vector<uint32_t, 4, SystemAllocPolicy> doubleSlots;
     19  js::Vector<uint32_t, 4, SystemAllocPolicy> quadSlots;
     20  uint32_t height_;
     21 
     22  void addAvailableSlot(uint32_t index) {
     23    // Ignoring OOM here (and below) is fine; it just means the stack slot
     24    // will be unused.
     25    (void)normalSlots.append(index);
     26  }
     27  void addAvailableDoubleSlot(uint32_t index) {
     28    (void)doubleSlots.append(index);
     29  }
     30  void addAvailableQuadSlot(uint32_t index) { (void)quadSlots.append(index); }
     31 
     32  uint32_t allocateQuadSlot() {
     33    // This relies on the fact that any architecture specific
     34    // alignment of the stack pointer is done a priori.
     35    if (!quadSlots.empty()) {
     36      return quadSlots.popCopy();
     37    }
     38    if (height_ % 8 != 0) {
     39      addAvailableSlot(height_ += 4);
     40    }
     41    if (height_ % 16 != 0) {
     42      addAvailableDoubleSlot(height_ += 8);
     43    }
     44    return height_ += 16;
     45  }
     46  uint32_t allocateDoubleSlot() {
     47    if (!doubleSlots.empty()) {
     48      return doubleSlots.popCopy();
     49    }
     50    if (height_ % 8 != 0) {
     51      addAvailableSlot(height_ += 4);
     52    }
     53    return height_ += 8;
     54  }
     55  uint32_t allocateSlot() {
     56    if (!normalSlots.empty()) {
     57      return normalSlots.popCopy();
     58    }
     59    if (!doubleSlots.empty()) {
     60      uint32_t index = doubleSlots.popCopy();
     61      addAvailableSlot(index - 4);
     62      return index;
     63    }
     64    return height_ += 4;
     65  }
     66 
     67 public:
     68  StackSlotAllocator() : height_(0) {}
     69 
     70  void allocateStackArea(LStackArea* alloc) {
     71    uint32_t size = alloc->size();
     72 
     73    MOZ_ASSERT(size % 4 == 0);
     74    switch (alloc->alignment()) {
     75      case 8:
     76        if ((height_ + size) % 8 != 0) {
     77          addAvailableSlot(height_ += 4);
     78        }
     79        break;
     80      default:
     81        MOZ_CRASH("unexpected stack results area alignment");
     82    }
     83    MOZ_ASSERT((height_ + size) % alloc->alignment() == 0);
     84 
     85    height_ += size;
     86    alloc->setBase(height_);
     87  }
     88 
     89  uint32_t allocateSlot(LStackSlot::Width width) {
     90    switch (width) {
     91      case LStackSlot::Word:
     92        return allocateSlot();
     93      case LStackSlot::DoubleWord:
     94        return allocateDoubleSlot();
     95      case LStackSlot::QuadWord:
     96        return allocateQuadSlot();
     97    }
     98    MOZ_CRASH("Unknown slot width");
     99  }
    100 
    101  // This method is used by the Simple allocator to free stack slots so that
    102  // they can be reused. The Backtracking allocator doesn't call this.
    103  void freeSlot(LStackSlot::Width width, uint32_t slot) {
    104    switch (width) {
    105      case LStackSlot::Word:
    106        addAvailableSlot(slot);
    107        return;
    108      case LStackSlot::DoubleWord:
    109        addAvailableDoubleSlot(slot);
    110        return;
    111      case LStackSlot::QuadWord:
    112        addAvailableQuadSlot(slot);
    113        return;
    114    }
    115    MOZ_CRASH("Unknown slot width");
    116  }
    117 
    118  uint32_t stackHeight() const { return height_; }
    119 };
    120 
    121 }  // namespace jit
    122 }  // namespace js
    123 
    124 #endif /* jit_StackSlotAllocator_h */