// Copyright 2009 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
// Maintains a per-v8thread stack area that can be used by irregexp // implementation for its backtracking stack. class V8_NODISCARD RegExpStackScope final { public: // Create and delete an instance to control the life-time of a growing stack.
// Initializes the stack memory area if necessary. explicit RegExpStackScope(Isolate* isolate);
~RegExpStackScope(); // Releases the stack if it has grown.
RegExpStackScope(const RegExpStackScope&) = delete;
RegExpStackScope& operator=(const RegExpStackScope&) = delete;
class RegExpStack final { public:
RegExpStack();
~RegExpStack();
RegExpStack(const RegExpStack&) = delete;
RegExpStack& operator=(const RegExpStack&) = delete;
#ifdefined(V8_TARGET_ARCH_PPC64) || defined(V8_TARGET_ARCH_S390X) static constexpr int kSlotSize = kSystemPointerSize; #else static constexpr int kSlotSize = kInt32Size; #endif // Number of allocated locations on the stack below the limit. No sequence of // pushes must be longer than this without doing a stack-limit check. static constexpr int kStackLimitSlackSlotCount = 32; static constexpr int kStackLimitSlackSize =
kStackLimitSlackSlotCount * kSlotSize;
// If the stack pointer gets below the limit, we should react and // either grow the stack or report an out-of-stack exception. // There is only a limited number of locations below the stack limit, // so users of the stack should check the stack limit during any // sequence of pushes longer that this.
Address* limit_address_address() { return &thread_local_.limit_; }
// Ensures that there is a memory area with at least the specified size. // If passing zero, the default/minimum size buffer is allocated.
Address EnsureCapacity(size_t size);
private: // Artificial limit used when the thread-local state has been destroyed. staticconst Address kMemoryTop = static_cast<Address>(static_cast<uintptr_t>(-1));
// In addition to dynamically-allocated, variable-sized stacks, we also have // a statically allocated and sized area that is used whenever no dynamic // stack is allocated. This guarantees that a stack is always available and // we can skip availability-checks later on. static constexpr size_t kStaticStackSize = 1 * KB; // It's at least double the slack size to ensure that we have a bit of // breathing room before NativeRegExpMacroAssembler::GrowStack must be // called.
static_assert(kStaticStackSize >= 2 * kStackLimitSlackSize);
static_assert(kStaticStackSize <= kMaximumStackSize);
uint8_t static_stack_[kStaticStackSize] = {0};
// A position-independent representation of the stack pointer.
ptrdiff_t sp_top_delta() const {
ptrdiff_t result = reinterpret_cast<intptr_t>(thread_local_.stack_pointer_) - reinterpret_cast<intptr_t>(thread_local_.memory_top_);
DCHECK_LE(result, 0); return result;
}
// Resets the buffer if it has grown beyond the default/minimum size and is // empty. void ResetIfEmpty() { thread_local_.ResetToStaticStackIfEmpty(this); }
// Whether the ThreadLocal storage has been invalidated. bool IsValid() const { return thread_local_.memory_ != nullptr; }
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.