summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/interpreter/JSStackInlines.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/interpreter/JSStackInlines.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/interpreter/JSStackInlines.h')
-rw-r--r--Source/JavaScriptCore/interpreter/JSStackInlines.h295
1 files changed, 0 insertions, 295 deletions
diff --git a/Source/JavaScriptCore/interpreter/JSStackInlines.h b/Source/JavaScriptCore/interpreter/JSStackInlines.h
deleted file mode 100644
index 5a2aff117..000000000
--- a/Source/JavaScriptCore/interpreter/JSStackInlines.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef JSStackInlines_h
-#define JSStackInlines_h
-
-#include "CallFrame.h"
-#include "CodeBlock.h"
-#include "JSStack.h"
-#include "VM.h"
-
-namespace JSC {
-
-inline Register* JSStack::getTopOfFrame(CallFrame* frame)
-{
- if (UNLIKELY(!frame))
- return getBaseOfStack();
- return frame->frameExtent();
-}
-
-inline Register* JSStack::getTopOfStack()
-{
- return getTopOfFrame(m_topCallFrame);
-}
-
-inline Register* JSStack::getStartOfFrame(CallFrame* frame)
-{
- CallFrame* callerFrame = frame->callerFrameSkippingVMEntrySentinel();
- return getTopOfFrame(callerFrame);
-}
-
-inline bool JSStack::entryCheck(class CodeBlock* codeBlock, int argsCount)
-{
- Register* oldEnd = getTopOfStack();
-
- // Ensure that we have enough space for the parameters:
- size_t paddedArgsCount = argsCount;
- if (codeBlock) {
- size_t numParameters = codeBlock->numParameters();
- if (paddedArgsCount < numParameters)
- paddedArgsCount = numParameters;
- }
-
- Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;
-
-#if ENABLE(DEBUG_JSSTACK)
- newCallFrameSlot -= JSStack::FenceSize;
-#endif
-
- Register* newEnd = newCallFrameSlot;
- if (!!codeBlock)
- newEnd += virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset();
-
- // Ensure that we have the needed stack capacity to push the new frame:
- if (!grow(newEnd))
- return false;
-
- return true;
-}
-
-inline CallFrame* JSStack::pushFrame(class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
-{
- ASSERT(!!scope);
- Register* oldEnd = getTopOfStack();
-
- // Ensure that we have enough space for the parameters:
- size_t paddedArgsCount = argsCount;
- if (codeBlock) {
- size_t numParameters = codeBlock->numParameters();
- if (paddedArgsCount < numParameters)
- paddedArgsCount = numParameters;
- }
-
- Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;
-
-#if ENABLE(DEBUG_JSSTACK)
- newCallFrameSlot -= JSStack::FenceSize;
-#endif
-
- Register* newEnd = newCallFrameSlot;
- if (!!codeBlock)
- newEnd += virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset();
-
- // Ensure that we have the needed stack capacity to push the new frame:
- if (!grow(newEnd))
- return 0;
-
- // Compute the address of the new VM sentinel frame for this invocation:
- CallFrame* newVMEntrySentinelFrame = CallFrame::create(newCallFrameSlot + paddedArgsCount + JSStack::CallFrameHeaderSize);
- ASSERT(!!newVMEntrySentinelFrame);
-
- // Compute the address of the new frame for this invocation:
- CallFrame* newCallFrame = CallFrame::create(newCallFrameSlot);
- ASSERT(!!newCallFrame);
-
- // The caller frame should always be the real previous frame on the stack,
- // and not a potential GlobalExec that was passed in. Point callerFrame to
- // the top frame on the stack.
- CallFrame* callerFrame = m_topCallFrame;
-
- // Initialize the VM sentinel frame header:
- newVMEntrySentinelFrame->initializeVMEntrySentinelFrame(callerFrame);
-
- // Initialize the callee frame header:
- newCallFrame->init(codeBlock, 0, scope, newVMEntrySentinelFrame, argsCount, callee);
-
- ASSERT(!!newCallFrame->scope());
-
- // Pad additional args if needed:
- // Note: we need to subtract 1 from argsCount and paddedArgsCount to
- // exclude the this pointer.
- for (size_t i = argsCount-1; i < paddedArgsCount-1; ++i)
- newCallFrame->setArgument(i, jsUndefined());
-
- installFence(newCallFrame, __FUNCTION__, __LINE__);
- validateFence(newCallFrame, __FUNCTION__, __LINE__);
- installTrapsAfterFrame(newCallFrame);
-
- // Push the new frame:
- m_topCallFrame = newCallFrame;
-
- return newCallFrame;
-}
-
-inline void JSStack::popFrame(CallFrame* frame)
-{
- validateFence(frame, __FUNCTION__, __LINE__);
-
- // Pop off the callee frame and the sentinel frame.
- CallFrame* callerFrame = frame->callerFrame()->vmEntrySentinelCallerFrame();
-
- // Pop to the caller:
- m_topCallFrame = callerFrame;
-
- // If we are popping the very first frame from the stack i.e. no more
- // frames before this, then we can now safely shrink the stack. In
- // this case, we're shrinking all the way to the beginning since there
- // are no more frames on the stack.
- if (!callerFrame)
- shrink(getBaseOfStack());
-
- installTrapsAfterFrame(callerFrame);
-}
-
-inline void JSStack::shrink(Register* newEnd)
-{
- if (newEnd >= m_end)
- return;
- updateStackLimit(newEnd);
- if (m_end == getBaseOfStack() && (m_commitEnd - getBaseOfStack()) >= maxExcessCapacity)
- releaseExcessCapacity();
-}
-
-inline bool JSStack::grow(Register* newEnd)
-{
- if (newEnd >= m_end)
- return true;
- return growSlowCase(newEnd);
-}
-
-inline void JSStack::updateStackLimit(Register* newEnd)
-{
- m_end = newEnd;
-#if USE(SEPARATE_C_AND_JS_STACK)
- m_vm.setJSStackLimit(newEnd);
-#endif
-}
-
-#if ENABLE(DEBUG_JSSTACK)
-inline JSValue JSStack::generateFenceValue(size_t argIndex)
-{
- unsigned fenceBits = 0xfacebad0 | ((argIndex+1) & 0xf);
- JSValue fenceValue = JSValue(fenceBits);
- return fenceValue;
-}
-
-// The JSStack fences mechanism works as follows:
-// 1. A fence is a number (JSStack::FenceSize) of JSValues that are initialized
-// with values generated by JSStack::generateFenceValue().
-// 2. When pushFrame() is called, the fence is installed after the max extent
-// of the previous topCallFrame and the last arg of the new frame:
-//
-// | ... |
-// |--------------------------------------|
-// | Frame Header of previous frame |
-// |--------------------------------------|
-// topCallFrame --> | |
-// | Locals of previous frame |
-// |--------------------------------------|
-// | *** the Fence *** |
-// |--------------------------------------|
-// | VM entry sentinel frame header |
-// |--------------------------------------|
-// | Args of new frame |
-// |--------------------------------------|
-// | Frame Header of new frame |
-// |--------------------------------------|
-// frame --> | Locals of new frame |
-// | |
-//
-// 3. In popFrame() and elsewhere, we can call JSStack::validateFence() to
-// assert that the fence contains the values we expect.
-
-inline void JSStack::installFence(CallFrame* frame, const char *function, int lineNo)
-{
- UNUSED_PARAM(function);
- UNUSED_PARAM(lineNo);
- Register* startOfFrame = getStartOfFrame(frame);
-
- // The last argIndex is at:
- size_t maxIndex = frame->argIndexForRegister(startOfFrame) + 1;
- size_t startIndex = maxIndex - FenceSize;
- for (size_t i = startIndex; i < maxIndex; ++i) {
- JSValue fenceValue = generateFenceValue(i);
- frame->setArgument(i, fenceValue);
- }
-}
-
-inline void JSStack::validateFence(CallFrame* frame, const char *function, int lineNo)
-{
- UNUSED_PARAM(function);
- UNUSED_PARAM(lineNo);
- ASSERT(!!frame->scope());
- Register* startOfFrame = getStartOfFrame(frame);
- size_t maxIndex = frame->argIndexForRegister(startOfFrame) + 1;
- size_t startIndex = maxIndex - FenceSize;
- for (size_t i = startIndex; i < maxIndex; ++i) {
- JSValue fenceValue = generateFenceValue(i);
- JSValue actualValue = frame->getArgumentUnsafe(i);
- ASSERT(fenceValue == actualValue);
- }
-}
-
-// When debugging the JSStack, we install bad values after the extent of the
-// topCallFrame at the end of pushFrame() and popFrame(). The intention is
-// to trigger crashes in the event that memory in this supposedly unused
-// region is read and consumed without proper initialization. After the trap
-// words are installed, the stack looks like this:
-//
-// | ... |
-// |-----------------------------|
-// | Frame Header of frame |
-// |-----------------------------|
-// topCallFrame --> | |
-// | Locals of frame |
-// |-----------------------------|
-// | *** Trap words *** |
-// |-----------------------------|
-// | Unused space ... |
-// | ... |
-
-inline void JSStack::installTrapsAfterFrame(CallFrame* frame)
-{
- Register* topOfFrame = getTopOfFrame(frame);
- const int sizeOfTrap = 64;
- int32_t* startOfTrap = reinterpret_cast<int32_t*>(topOfFrame);
- int32_t* endOfTrap = startOfTrap - sizeOfTrap;
- int32_t* endOfCommitedMemory = reinterpret_cast<int32_t*>(m_commitEnd);
-
- // Make sure we're not exceeding the amount of available memory to write to:
- if (endOfTrap < endOfCommitedMemory)
- endOfTrap = endOfCommitedMemory;
-
- // Lay the traps:
- int32_t* p = startOfTrap;
- while (p > endOfTrap)
- *p-- = 0xabadcafe; // A bad word to trigger a crash if deref'ed.
-}
-#endif // ENABLE(DEBUG_JSSTACK)
-
-} // namespace JSC
-
-#endif // JSStackInlines_h