⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jit.h

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 H
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2008 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 JIT_h#define JIT_h#include <wtf/Platform.h>#if ENABLE(JIT)#define WTF_USE_CTI_REPATCH_PIC 1#include "Interpreter.h"#include "JITCode.h"#include "JITStubs.h"#include "Opcode.h"#include "RegisterFile.h"#include "MacroAssembler.h"#include "Profiler.h"#include <bytecode/SamplingTool.h>#include <wtf/AlwaysInline.h>#include <wtf/Vector.h>#if PLATFORM(X86_64)#define STUB_ARGS_offset 0x10#else#define STUB_ARGS_offset 0x0C#endif#define STUB_ARGS_code (STUB_ARGS_offset)#define STUB_ARGS_registerFile (STUB_ARGS_offset + 1)#define STUB_ARGS_callFrame (STUB_ARGS_offset + 2)#define STUB_ARGS_exception (STUB_ARGS_offset + 3)#define STUB_ARGS_profilerReference (STUB_ARGS_offset + 4)#define STUB_ARGS_globalData (STUB_ARGS_offset + 5)#define ARG_callFrame static_cast<CallFrame*>(ARGS[STUB_ARGS_callFrame])#define ARG_registerFile static_cast<RegisterFile*>(ARGS[STUB_ARGS_registerFile])#define ARG_exception static_cast<JSValuePtr*>(ARGS[STUB_ARGS_exception])#define ARG_profilerReference static_cast<Profiler**>(ARGS[STUB_ARGS_profilerReference])#define ARG_globalData static_cast<JSGlobalData*>(ARGS[STUB_ARGS_globalData])#define ARG_setCallFrame(newCallFrame) (ARGS[STUB_ARGS_callFrame] = (newCallFrame))#define ARG_src1 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[1]))#define ARG_src2 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[2]))#define ARG_src3 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[3]))#define ARG_src4 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[4]))#define ARG_src5 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[5]))#define ARG_id1 static_cast<Identifier*>(ARGS[1])#define ARG_id2 static_cast<Identifier*>(ARGS[2])#define ARG_id3 static_cast<Identifier*>(ARGS[3])#define ARG_id4 static_cast<Identifier*>(ARGS[4])#define ARG_int1 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[1]))#define ARG_int2 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[2]))#define ARG_int3 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[3]))#define ARG_int4 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[4]))#define ARG_int5 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[5]))#define ARG_int6 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[6]))#define ARG_func1 static_cast<FuncDeclNode*>(ARGS[1])#define ARG_funcexp1 static_cast<FuncExprNode*>(ARGS[1])#define ARG_regexp1 static_cast<RegExp*>(ARGS[1])#define ARG_pni1 static_cast<JSPropertyNameIterator*>(ARGS[1])#define ARG_returnAddress2 static_cast<void*>(ARGS[2])#define ARG_codeBlock4 static_cast<CodeBlock*>(ARGS[4])#define STUB_RETURN_ADDRESS_SLOT (ARGS[-1])namespace JSC {    class CodeBlock;    class JSPropertyNameIterator;    class Interpreter;    class Register;    class RegisterFile;    class ScopeChainNode;    class SimpleJumpTable;    class StringJumpTable;    class StructureChain;    struct CallLinkInfo;    struct Instruction;    struct OperandTypes;    struct PolymorphicAccessStructureList;    struct StructureStubInfo;    typedef JSValueEncodedAsPointer* (JIT_STUB *CTIHelper_j)(STUB_ARGS);    typedef JSObject* (JIT_STUB *CTIHelper_o)(STUB_ARGS);    typedef JSPropertyNameIterator* (JIT_STUB *CTIHelper_p)(STUB_ARGS);    typedef void (JIT_STUB *CTIHelper_v)(STUB_ARGS);    typedef void* (JIT_STUB *CTIHelper_s)(STUB_ARGS);    typedef int (JIT_STUB *CTIHelper_b)(STUB_ARGS);    typedef VoidPtrPair (JIT_STUB *CTIHelper_2)(STUB_ARGS);    struct CallRecord {        MacroAssembler::Call from;        unsigned bytecodeIndex;        void* to;        CallRecord()        {        }        CallRecord(MacroAssembler::Call from, unsigned bytecodeIndex, void* to = 0)            : from(from)            , bytecodeIndex(bytecodeIndex)            , to(to)        {        }    };    struct JumpTable {        MacroAssembler::Jump from;        unsigned toBytecodeIndex;        JumpTable(MacroAssembler::Jump f, unsigned t)            : from(f)            , toBytecodeIndex(t)        {        }    };    struct SlowCaseEntry {        MacroAssembler::Jump from;        unsigned to;        unsigned hint;                SlowCaseEntry(MacroAssembler::Jump f, unsigned t, unsigned h = 0)            : from(f)            , to(t)            , hint(h)        {        }    };    struct SwitchRecord {        enum Type {            Immediate,            Character,            String        };        Type type;        union {            SimpleJumpTable* simpleJumpTable;            StringJumpTable* stringJumpTable;        } jumpTable;        unsigned bytecodeIndex;        unsigned defaultOffset;        SwitchRecord(SimpleJumpTable* jumpTable, unsigned bytecodeIndex, unsigned defaultOffset, Type type)            : type(type)            , bytecodeIndex(bytecodeIndex)            , defaultOffset(defaultOffset)        {            this->jumpTable.simpleJumpTable = jumpTable;        }        SwitchRecord(StringJumpTable* jumpTable, unsigned bytecodeIndex, unsigned defaultOffset)            : type(String)            , bytecodeIndex(bytecodeIndex)            , defaultOffset(defaultOffset)        {            this->jumpTable.stringJumpTable = jumpTable;        }    };    struct PropertyStubCompilationInfo {        MacroAssembler::Call callReturnLocation;        MacroAssembler::Label hotPathBegin;    };    struct StructureStubCompilationInfo {        MacroAssembler::DataLabelPtr hotPathBegin;        MacroAssembler::Call hotPathOther;        MacroAssembler::Call callReturnLocation;        MacroAssembler::Label coldPathOther;    };    extern "C" {        void ctiVMThrowTrampoline();    };    void ctiSetReturnAddress(void** addressOfReturnAddress, void* newDestinationToReturnTo);    void ctiPatchCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction);    void ctiPatchNearCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction);    class JIT : private MacroAssembler {        using MacroAssembler::Jump;        using MacroAssembler::JumpList;        using MacroAssembler::Label;        // NOTES:        //        // regT0 has two special meanings.  The return value from a stub        // call will always be in regT0, and by default (unless        // a register is specified) emitPutVirtualRegister() will store        // the value from regT0.        //        // tempRegister2 is has no such dependencies.  It is important that        // on x86/x86-64 it is ecx for performance reasons, since the        // MacroAssembler will need to plant register swaps if it is not -        // however the code will still function correctly.#if PLATFORM(X86_64)        static const RegisterID returnValueRegister = X86::eax;        static const RegisterID cachedResultRegister = X86::eax;        static const RegisterID firstArgumentRegister = X86::edi;        static const RegisterID timeoutCheckRegister = X86::r12;        static const RegisterID callFrameRegister = X86::r13;        static const RegisterID tagTypeNumberRegister = X86::r14;        static const RegisterID tagMaskRegister = X86::r15;        static const RegisterID regT0 = X86::eax;        static const RegisterID regT1 = X86::edx;        static const RegisterID regT2 = X86::ecx;        // NOTE: privateCompileCTIMachineTrampolines() relies on this being callee preserved; this should be considered non-interface.        static const RegisterID regT3 = X86::ebx;#elif PLATFORM(X86)        static const RegisterID returnValueRegister = X86::eax;        static const RegisterID cachedResultRegister = X86::eax;        // On x86 we always use fastcall conventions = but on        // OS X if might make more sense to just use regparm.        static const RegisterID firstArgumentRegister = X86::ecx;        static const RegisterID timeoutCheckRegister = X86::esi;        static const RegisterID callFrameRegister = X86::edi;        static const RegisterID regT0 = X86::eax;        static const RegisterID regT1 = X86::edx;        static const RegisterID regT2 = X86::ecx;        // NOTE: privateCompileCTIMachineTrampolines() relies on this being callee preserved; this should be considered non-interface.        static const RegisterID regT3 = X86::ebx;#else    #error "JIT not supported on this platform."#endif        static const int patchGetByIdDefaultStructure = -1;        // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler        // will compress the displacement, and we may not be able to fit a patched offset.        static const int patchGetByIdDefaultOffset = 256;#if USE(JIT_STUB_ARGUMENT_REGISTER)#if PLATFORM(X86_64)        static const int ctiArgumentInitSize = 6;#else        static const int ctiArgumentInitSize = 2;#endif#elif USE(JIT_STUB_ARGUMENT_STACK)        static const int ctiArgumentInitSize = 4;#else // JIT_STUB_ARGUMENT_VA_LIST        static const int ctiArgumentInitSize = 0;#endif#if PLATFORM(X86_64)        // These architecture specific value are used to enable patching - see comment on op_put_by_id.        static const int patchOffsetPutByIdStructure = 10;        static const int patchOffsetPutByIdPropertyMapOffset = 31;        // These architecture specific value are used to enable patching - see comment on op_get_by_id.        static const int patchOffsetGetByIdStructure = 10;        static const int patchOffsetGetByIdBranchToSlowCase = 20;        static const int patchOffsetGetByIdPropertyMapOffset = 31;        static const int patchOffsetGetByIdPutResult = 31;#if ENABLE(OPCODE_SAMPLING)        static const int patchOffsetGetByIdSlowCaseCall = 61 + ctiArgumentInitSize;#else        static const int patchOffsetGetByIdSlowCaseCall = 38 + ctiArgumentInitSize;#endif        static const int patchOffsetOpCallCompareToJump = 9;#else        // These architecture specific value are used to enable patching - see comment on op_put_by_id.        static const int patchOffsetPutByIdStructure = 7;        static const int patchOffsetPutByIdPropertyMapOffset = 22;        // These architecture specific value are used to enable patching - see comment on op_get_by_id.        static const int patchOffsetGetByIdStructure = 7;        static const int patchOffsetGetByIdBranchToSlowCase = 13;        static const int patchOffsetGetByIdPropertyMapOffset = 22;        static const int patchOffsetGetByIdPutResult = 22;#if ENABLE(OPCODE_SAMPLING)        static const int patchOffsetGetByIdSlowCaseCall = 31 + ctiArgumentInitSize;#else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -