Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/src/jit/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 5 kB image not shown  

Quelle  StackSlotAllocator.h

  Sprache: C
 

/* 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_StackSlotAllocator_h
#define jit_StackSlotAllocator_h

#include "jit/LIR.h"
#include "jit/Registers.h"

namespace js {
namespace jit {

class StackSlotAllocator {
  js::Vector<uint32_t, 4, SystemAllocPolicy> normalSlots;
  js::Vector<uint32_t, 4, SystemAllocPolicy> doubleSlots;
  js::Vector<uint32_t, 4, SystemAllocPolicy> quadSlots;
  uint32_t height_;

  [[nodiscard]] bool incrementHeight(uint32_t amount) {
    // See MaxBytes for why we don't need to check for overflow here.
    if (amount > MaxBytes || height_ + amount > MaxBytes) {
      return false;
    }
    height_ += amount;
    return true;
  }

  void freeSlot(uint32_t offset) { (void)normalSlots.append(offset); }
  void freeDoubleSlot(uint32_t offset) { (void)doubleSlots.append(offset); }
  void freeQuadSlot(uint32_t offset) { (void)quadSlots.append(offset); }

  [[nodiscard]] bool allocateSlot(uint32_t* slotOffset) {
    // Re-use a normal slot if we have one.
    if (!normalSlots.empty()) {
      *slotOffset = normalSlots.popCopy();
      return true;
    }

    // Otherwise split a double slot in half if we can.
    if (!doubleSlots.empty()) {
      uint32_t doubleSlotOffset = doubleSlots.popCopy();
      freeSlot(doubleSlotOffset - 4);
      *slotOffset = doubleSlotOffset;
      return true;
    }

    // Or else grow the stack by a word.
    if (!incrementHeight(4)) {
      return false;
    }
    *slotOffset = height_;
    return true;
  }

  [[nodiscard]] bool allocateDoubleSlot(uint32_t* slotOffset) {
    if (!doubleSlots.empty()) {
      *slotOffset = doubleSlots.popCopy();
      return true;
    }

    // Grow the stack, freeing the padding word for reuse if we need to align.
    if (height_ % 8 != 0) {
      if (!incrementHeight(4)) {
        return false;
      }
      freeSlot(height_);
    }
    if (!incrementHeight(8)) {
      return false;
    }
    *slotOffset = height_;
    return true;
  }

  [[nodiscard]] bool allocateQuadSlot(uint32_t* slotOffset) {
    if (!quadSlots.empty()) {
      *slotOffset = quadSlots.popCopy();
      return true;
    }

    // Grow the stack, freeing any padding for reuse if we need to align. This
    // relies on the fact that any architecture specific alignment of the stack
    // pointer is done a priori.
    if (height_ % 8 != 0) {
      if (!incrementHeight(4)) {
        return false;
      }
      freeSlot(height_);
    }
    if (height_ % 16 != 0) {
      if (!incrementHeight(8)) {
        return false;
      }
      freeDoubleSlot(height_);
    }
    if (!incrementHeight(16)) {
      return false;
    }
    *slotOffset = height_;
    return true;
  }

 public:
  StackSlotAllocator() : height_(0) {}

  // The maximum size we allow. This is a conservative value, even values this
  // low are very likely to hit stack overflows.
  static constexpr size_t MaxBytes = 2 * 1024 * 1024;
  // Check that as long as we keep height_ within MaxBytes and only add by up
  // to MaxBytes, that we cannot overflow. This is used in several places.
  static_assert(uint64_t(MaxBytes) + uint64_t(MaxBytes) <= UINT32_MAX);
  // Any offset we provide can be stored in LStackSlot.
  static_assert(MaxBytes <= LStackSlot::MAX_SLOT);

  [[nodiscard]] bool allocateStackArea(LStackArea* alloc) {
    uint32_t size = alloc->size();

    // Check that size is within MaxBytes so that we don't need to check for
    // overflow below when adding to height_.
    if (size > MaxBytes) {
      return false;
    }

    MOZ_ASSERT(size % 4 == 0);
    switch (alloc->alignment()) {
      case 8: {
        // Grow the stack, freeing the padding word for reuse if we need to
        // align.
        if ((height_ + size) % 8 != 0) {
          if (!incrementHeight(4)) {
            return false;
          }
          freeSlot(height_);
        }
        break;
      }
      default:
        MOZ_CRASH("unexpected stack results area alignment");
    }

    // See MaxBytes for why we don't need to check for overflow here.
    uint32_t areaSlotOffset = height_ + size;
    if (areaSlotOffset > MaxBytes) {
      return false;
    }
    MOZ_ASSERT(areaSlotOffset % alloc->alignment() == 0);

    alloc->setBase(areaSlotOffset);
    height_ = areaSlotOffset;
    return true;
  }

  [[nodiscard]] bool allocateSlot(LStackSlot::Width width,
                                  uint32_t* slotOffset) {
    switch (width) {
      case LStackSlot::Word:
        return allocateSlot(slotOffset);
      case LStackSlot::DoubleWord:
        return allocateDoubleSlot(slotOffset);
      case LStackSlot::QuadWord:
        return allocateQuadSlot(slotOffset);
    }
    MOZ_CRASH("Unknown slot width");
  }

  // This method is used by the Simple allocator to free stack slots so that
  // they can be reused. The Backtracking allocator doesn't call this.
  void freeSlot(LStackSlot::Width width, uint32_t slotOffset) {
    switch (width) {
      case LStackSlot::Word:
        freeSlot(slotOffset);
        return;
      case LStackSlot::DoubleWord:
        freeDoubleSlot(slotOffset);
        return;
      case LStackSlot::QuadWord:
        freeQuadSlot(slotOffset);
        return;
    }
    MOZ_CRASH("Unknown slot width");
  }

  uint32_t stackHeight() const { return height_; }
};

}  // namespace jit
}  // namespace js

#endif /* jit_StackSlotAllocator_h */

Messung V0.5 in Prozent
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.