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

📄 jit.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2008, 2009 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.  */#include "config.h"#include "JIT.h"#if ENABLE(JIT)#include "CodeBlock.h"#include "JITInlineMethods.h"#include "JSArray.h"#include "JSFunction.h"#include "Interpreter.h"#include "ResultType.h"#include "SamplingTool.h"#ifndef NDEBUG#include <stdio.h>#endifusing namespace std;namespace JSC {#if COMPILER(GCC) && PLATFORM(X86)COMPILE_ASSERT(STUB_ARGS_code == 0x0C, STUB_ARGS_code_is_0x0C);COMPILE_ASSERT(STUB_ARGS_callFrame == 0x0E, STUB_ARGS_callFrame_is_0x0E);#if PLATFORM(DARWIN)#define SYMBOL_STRING(name) "_" #name#else#define SYMBOL_STRING(name) #name#endifasm(".globl " SYMBOL_STRING(ctiTrampoline) "\n"SYMBOL_STRING(ctiTrampoline) ":" "\n"    "pushl %ebp" "\n"    "movl %esp, %ebp" "\n"    "pushl %esi" "\n"    "pushl %edi" "\n"    "pushl %ebx" "\n"    "subl $0x1c, %esp" "\n"    "movl $512, %esi" "\n"    "movl 0x38(%esp), %edi" "\n" // Ox38 = 0x0E * 4, 0x0E = STUB_ARGS_callFrame (see assertion above)    "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = STUB_ARGS_code (see assertion above)    "addl $0x1c, %esp" "\n"    "popl %ebx" "\n"    "popl %edi" "\n"    "popl %esi" "\n"    "popl %ebp" "\n"    "ret" "\n");asm(".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"#if USE(JIT_STUB_ARGUMENT_VA_LIST)    "call " SYMBOL_STRING(_ZN3JSC8JITStubs12cti_vm_throwEPvz) "\n"#else#if USE(JIT_STUB_ARGUMENT_REGISTER)    "movl %esp, %ecx" "\n"#else // JIT_STUB_ARGUMENT_STACK    "movl %esp, 0(%esp)" "\n"#endif    "call " SYMBOL_STRING(_ZN3JSC8JITStubs12cti_vm_throwEPPv) "\n"#endif    "addl $0x1c, %esp" "\n"    "popl %ebx" "\n"    "popl %edi" "\n"    "popl %esi" "\n"    "popl %ebp" "\n"    "ret" "\n");    #elif COMPILER(GCC) && PLATFORM(X86_64)COMPILE_ASSERT(STUB_ARGS_code == 0x10, STUB_ARGS_code_is_0x10);COMPILE_ASSERT(STUB_ARGS_callFrame == 0x12, STUB_ARGS_callFrame_is_0x12);#if PLATFORM(DARWIN)#define SYMBOL_STRING(name) "_" #name#else#define SYMBOL_STRING(name) #name#endifasm(".globl " SYMBOL_STRING(ctiTrampoline) "\n"SYMBOL_STRING(ctiTrampoline) ":" "\n"    "pushq %rbp" "\n"    "movq %rsp, %rbp" "\n"    "pushq %r12" "\n"    "pushq %r13" "\n"    "pushq %r14" "\n"    "pushq %r15" "\n"    "pushq %rbx" "\n"    "subq $0x48, %rsp" "\n"    "movq $512, %r12" "\n"    "movq $0xFFFF000000000000, %r14" "\n"    "movq $0xFFFF000000000002, %r15" "\n"    "movq 0x90(%rsp), %r13" "\n" // Ox90 = 0x12 * 8, 0x12 = STUB_ARGS_callFrame (see assertion above)    "call *0x80(%rsp)" "\n" // Ox80 = 0x10 * 8, 0x10 = STUB_ARGS_code (see assertion above)    "addq $0x48, %rsp" "\n"    "popq %rbx" "\n"    "popq %r15" "\n"    "popq %r14" "\n"    "popq %r13" "\n"    "popq %r12" "\n"    "popq %rbp" "\n"    "ret" "\n");asm(".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"#if USE(JIT_STUB_ARGUMENT_REGISTER)    "movq %rsp, %rdi" "\n"    "call " SYMBOL_STRING(_ZN3JSC8JITStubs12cti_vm_throwEPPv) "\n"#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK#error "JIT_STUB_ARGUMENT configuration not supported."#endif    "addq $0x48, %rsp" "\n"    "popq %rbx" "\n"    "popq %r15" "\n"    "popq %r14" "\n"    "popq %r13" "\n"    "popq %r12" "\n"    "popq %rbp" "\n"    "ret" "\n");    #elif COMPILER(MSVC)extern "C" {        __declspec(naked) JSValueEncodedAsPointer* ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*)    {        __asm {            push ebp;            mov ebp, esp;            push esi;            push edi;            push ebx;            sub esp, 0x1c;            mov esi, 512;            mov ecx, esp;            mov edi, [esp + 0x38];            call [esp + 0x30]; // Ox30 = 0x0C * 4, 0x0C = STUB_ARGS_code (see assertion above)            add esp, 0x1c;            pop ebx;            pop edi;            pop esi;            pop ebp;            ret;        }    }        __declspec(naked) void ctiVMThrowTrampoline()    {        __asm {#if USE(JIT_STUB_ARGUMENT_REGISTER)            mov ecx, esp;#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK#error "JIT_STUB_ARGUMENT configuration not supported."#endif            call JSC::JITStubs::cti_vm_throw;            add esp, 0x1c;            pop ebx;            pop edi;            pop esi;            pop ebp;            ret;        }    }    }#endifvoid ctiSetReturnAddress(void** addressOfReturnAddress, void* newDestinationToReturnTo){    *addressOfReturnAddress = newDestinationToReturnTo;}void ctiPatchCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction){    returnAddress.relinkCallerToFunction(newCalleeFunction);}void ctiPatchNearCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction){    returnAddress.relinkNearCallerToFunction(newCalleeFunction);}JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)    : m_interpreter(globalData->interpreter)    , m_globalData(globalData)    , m_codeBlock(codeBlock)    , m_labels(codeBlock ? codeBlock->instructions().size() : 0)    , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfStructureStubInfos() : 0)    , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)    , m_lastResultBytecodeRegister(std::numeric_limits<int>::max())    , m_jumpTargetsPosition(0){}void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type){    unsigned dst = currentInstruction[1].u.operand;    unsigned src1 = currentInstruction[2].u.operand;    unsigned src2 = currentInstruction[3].u.operand;    emitGetVirtualRegisters(src1, regT0, src2, regT1);    // Jump to a slow case if either operand is a number, or if both are JSCell*s.    move(regT0, regT2);    orPtr(regT1, regT2);    addSlowCase(emitJumpIfJSCell(regT2));    addSlowCase(emitJumpIfImmediateNumber(regT2));    if (type == OpStrictEq)        set32(Equal, regT1, regT0, regT0);    else        set32(NotEqual, regT1, regT0, regT0);    emitTagAsBoolImmediate(regT0);    emitPutVirtualRegister(dst);}void JIT::emitTimeoutCheck(){    Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);    emitCTICall(JITStubs::cti_timeout_check);    move(regT0, timeoutCheckRegister);    skipTimeout.link(this);    killLastResultRegister();}#define NEXT_OPCODE(name) \    m_bytecodeIndex += OPCODE_LENGTH(name); \    break;#define CTI_COMPILE_BINARY_OP(name) \    case name: { \        emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \        emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2); \        emitCTICall(JITStubs::cti_##name); \        emitPutVirtualRegister(currentInstruction[1].u.operand); \        NEXT_OPCODE(name); \    }#define CTI_COMPILE_UNARY_OP(name) \    case name: { \        emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \        emitCTICall(JITStubs::cti_##name); \        emitPutVirtualRegister(currentInstruction[1].u.operand); \        NEXT_OPCODE(name); \    }#define RECORD_JUMP_TARGET(targetOffset) \   do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false)void JIT::privateCompileMainPass(){    Instruction* instructionsBegin = m_codeBlock->instructions().begin();    unsigned instructionCount = m_codeBlock->instructions().size();    unsigned propertyAccessInstructionIndex = 0;    unsigned globalResolveInfoIndex = 0;    unsigned callLinkInfoIndex = 0;    for (m_bytecodeIndex = 0; m_bytecodeIndex < instructionCount; ) {        Instruction* currentInstruction = instructionsBegin + m_bytecodeIndex;        ASSERT_WITH_MESSAGE(m_interpreter->isOpcode(currentInstruction->u.opcode), "privateCompileMainPass gone bad @ %d", m_bytecodeIndex);

⌨️ 快捷键说明

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