📄 codeblock.h
字号:
/* * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> * * 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. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 CodeBlock_h#define CodeBlock_h#include "EvalCodeCache.h"#include "Instruction.h"#include "JITCode.h"#include "JSGlobalObject.h"#include "JumpTable.h"#include "Nodes.h"#include "RegExp.h"#include "UString.h"#include <wtf/RefPtr.h>#include <wtf/Vector.h>#if ENABLE(JIT)#include "StructureStubInfo.h"#endifnamespace JSC { class ExecState; enum CodeType { GlobalCode, EvalCode, FunctionCode }; static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); } struct HandlerInfo { uint32_t start; uint32_t end; uint32_t target; uint32_t scopeDepth;#if ENABLE(JIT) MacroAssembler::CodeLocationLabel nativeCode;#endif };#if ENABLE(JIT) // The code, and the associated pool from which it was allocated. struct JITCodeRef { JITCode code;#ifndef NDEBUG unsigned codeSize;#endif RefPtr<ExecutablePool> executablePool; JITCodeRef() : code(0)#ifndef NDEBUG , codeSize(0)#endif { } JITCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool) : code(code)#ifndef NDEBUG , codeSize(0)#endif , executablePool(executablePool) { } };#endif struct ExpressionRangeInfo { enum { MaxOffset = (1 << 7) - 1, MaxDivot = (1 << 25) - 1 }; uint32_t instructionOffset : 25; uint32_t divotPoint : 25; uint32_t startOffset : 7; uint32_t endOffset : 7; }; struct LineInfo { uint32_t instructionOffset; int32_t lineNumber; }; // Both op_construct and op_instanceof require a use of op_get_by_id to get // the prototype property from an object. The exception messages for exceptions // thrown by these instances op_get_by_id need to reflect this. struct GetByIdExceptionInfo { unsigned bytecodeOffset : 31; bool isOpConstruct : 1; };#if ENABLE(JIT) struct CallLinkInfo { CallLinkInfo() : callee(0) { } unsigned bytecodeIndex; MacroAssembler::CodeLocationNearCall callReturnLocation; MacroAssembler::CodeLocationDataLabelPtr hotPathBegin; MacroAssembler::CodeLocationNearCall hotPathOther; MacroAssembler::CodeLocationLabel coldPathOther; CodeBlock* callee; unsigned position; void setUnlinked() { callee = 0; } bool isLinked() { return callee; } }; struct FunctionRegisterInfo { FunctionRegisterInfo(unsigned bytecodeOffset, int functionRegisterIndex) : bytecodeOffset(bytecodeOffset) , functionRegisterIndex(functionRegisterIndex) { } unsigned bytecodeOffset; int functionRegisterIndex; }; struct GlobalResolveInfo { GlobalResolveInfo(unsigned bytecodeOffset) : structure(0) , offset(0) , bytecodeOffset(bytecodeOffset) { } Structure* structure; unsigned offset; unsigned bytecodeOffset; }; // This structure is used to map from a call return location // (given as an offset in bytes into the JIT code) back to // the bytecode index of the corresponding bytecode operation. // This is then used to look up the corresponding handler. struct CallReturnOffsetToBytecodeIndex { CallReturnOffsetToBytecodeIndex(unsigned callReturnOffset, unsigned bytecodeIndex) : callReturnOffset(callReturnOffset) , bytecodeIndex(bytecodeIndex) { } unsigned callReturnOffset; unsigned bytecodeIndex; }; // valueAtPosition helpers for the binaryChop algorithm below. inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo) { return structureStubInfo->callReturnLocation.calleeReturnAddressValue(); } inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo) { return callLinkInfo->callReturnLocation.calleeReturnAddressValue(); } inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeIndex* pc) { return pc->callReturnOffset; } // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array, // compares result with key (KeyTypes should be comparable with '--', '<', '>'). // Optimized for cases where the array contains the key, checked by assertions. template<typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)> inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key) { // The array must contain at least one element (pre-condition, array does conatin key). // If the array only contains one element, no need to do the comparison. while (size > 1) { // Pick an element to check, half way through the array, and read the value. int pos = (size - 1) >> 1; KeyType val = valueAtPosition(&array[pos]); // If the key matches, success! if (val == key) return &array[pos]; // The item we are looking for is smaller than the item being check; reduce the value of 'size', // chopping off the right hand half of the array. else if (key < val) size = pos; // Discard all values in the left hand half of the array, up to and including the item at pos. else { size -= (pos + 1); array += (pos + 1); } // 'size' should never reach zero. ASSERT(size); } // If we reach this point we've chopped down to one element, no need to check it matches ASSERT(size == 1); ASSERT(key == valueAtPosition(&array[0])); return &array[0]; }#endif class CodeBlock { friend class JIT; public: CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset); ~CodeBlock(); void mark(); void refStructures(Instruction* vPC) const; void derefStructures(Instruction* vPC) const;#if ENABLE(JIT) void unlinkCallers();#endif static void dumpStatistics();#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING void dump(ExecState*) const; void printStructures(const Instruction*) const; void printStructure(const char* name, const Instruction*, int operand) const;#endif inline bool isKnownNotImmediate(int index) { if (index == m_thisRegister) return true; if (isConstantRegisterIndex(index)) return getConstant(index).isCell(); return false; } ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= m_numVars && index < m_numVars + m_numConstants; } ALWAYS_INLINE JSValuePtr getConstant(int index) { return m_constantRegisters[index - m_numVars].getJSValue(); } ALWAYS_INLINE bool isTemporaryRegisterIndex(int index) { return index >= m_numVars + m_numConstants; } HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset); int lineNumberForBytecodeOffset(CallFrame*, unsigned bytecodeOffset); int expressionRangeForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset); bool getByIdExceptionInfoForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, OpcodeID&);#if ENABLE(JIT) void addCaller(CallLinkInfo* caller) { caller->callee = this; caller->position = m_linkedCallerList.size(); m_linkedCallerList.append(caller); } void removeCaller(CallLinkInfo* caller) { unsigned pos = caller->position; unsigned lastPos = m_linkedCallerList.size() - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -