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

📄 codeblock.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * 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. */#include "config.h"#include "CodeBlock.h"#include "JIT.h"#include "JSValue.h"#include "Interpreter.h"#include "Debugger.h"#include "BytecodeGenerator.h"#include <stdio.h>#include <wtf/StringExtras.h>#define DUMP_CODE_BLOCK_STATISTICS 0namespace JSC {#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)static UString escapeQuotes(const UString& str){    UString result = str;    int pos = 0;    while ((pos = result.find('\"', pos)) >= 0) {        result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);        pos += 4;    }    return result;}static UString valueToSourceString(ExecState* exec, JSValuePtr val){    if (val.isString()) {        UString result("\"");        result += escapeQuotes(val.toString(exec)) + "\"";        return result;    }     return val.toString(exec);}static CString registerName(int r){    if (r == missingThisObjectMarker())        return "<null>";    return (UString("r") + UString::from(r)).UTF8String();}static CString constantName(ExecState* exec, int k, JSValuePtr value){    return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();}static CString idName(int id0, const Identifier& ident){    return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();}static UString regexpToSourceString(RegExp* regExp){    UString pattern = UString("/") + regExp->pattern() + "/";    if (regExp->global())        pattern += "g";    if (regExp->ignoreCase())        pattern += "i";    if (regExp->multiline())        pattern += "m";    return pattern;}static CString regexpName(int re, RegExp* regexp){    return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String();}static UString pointerToSourceString(void* p){    char buffer[2 + 2 * sizeof(void*) + 1]; // 0x [two characters per byte] \0    snprintf(buffer, sizeof(buffer), "%p", p);    return buffer;}NEVER_INLINE static const char* debugHookName(int debugHookID){    switch (static_cast<DebugHookID>(debugHookID)) {        case DidEnterCallFrame:            return "didEnterCallFrame";        case WillLeaveCallFrame:            return "willLeaveCallFrame";        case WillExecuteStatement:            return "willExecuteStatement";        case WillExecuteProgram:            return "willExecuteProgram";        case DidExecuteProgram:            return "didExecuteProgram";        case DidReachBreakpoint:            return "didReachBreakpoint";    }    ASSERT_NOT_REACHED();    return "";}static int locationForOffset(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int offset){    return it - begin + offset;}static void printUnaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op){    int r0 = (++it)->u.operand;    int r1 = (++it)->u.operand;    printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str());}static void printBinaryOp(int location, Vector<Instruction>::const_iterator& it, const char* op){    int r0 = (++it)->u.operand;    int r1 = (++it)->u.operand;    int r2 = (++it)->u.operand;    printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str());}static void printConditionalJump(const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it, int location, const char* op){    int r0 = (++it)->u.operand;    int offset = (++it)->u.operand;    printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(r0).c_str(), offset, locationForOffset(begin, it, offset));}static void printGetByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op){    int r0 = (++it)->u.operand;    int r1 = (++it)->u.operand;    int id0 = (++it)->u.operand;    printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());    it += 4;}static void printPutByIdOp(int location, Vector<Instruction>::const_iterator& it, const Vector<Identifier>& m_identifiers, const char* op){    int r0 = (++it)->u.operand;    int id0 = (++it)->u.operand;    int r1 = (++it)->u.operand;    printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());    it += 4;}#if ENABLE(JIT)static bool isGlobalResolve(OpcodeID opcodeID){    return opcodeID == op_resolve_global;}static bool isPropertyAccess(OpcodeID opcodeID){    switch (opcodeID) {        case op_get_by_id_self:        case op_get_by_id_proto:        case op_get_by_id_chain:        case op_get_by_id_self_list:        case op_get_by_id_proto_list:        case op_put_by_id_transition:        case op_put_by_id_replace:        case op_get_by_id:        case op_put_by_id:        case op_get_by_id_generic:        case op_put_by_id_generic:        case op_get_array_length:        case op_get_string_length:            return true;        default:            return false;    }}static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instruction>& instructions, int nth, bool (*predicate)(OpcodeID)){    size_t i = 0;    while (i < instructions.size()) {        OpcodeID currentOpcode = exec->interpreter()->getOpcodeID(instructions[i].u.opcode);        if (predicate(currentOpcode)) {            if (!--nth)                return i;        }        i += opcodeLengths[currentOpcode];    }    ASSERT_NOT_REACHED();    return 0;}static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset){    printf("  [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).UTF8String().c_str());}static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset){    switch (stubInfo.opcodeID) {    case op_get_by_id_self:        printf("  [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str());        return;    case op_get_by_id_proto:        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str());        return;    case op_get_by_id_chain:        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str());        return;    case op_get_by_id_self_list:        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize);        return;    case op_get_by_id_proto_list:        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize);        return;    case op_put_by_id_transition:        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str());        return;    case op_put_by_id_replace:        printf("  [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str());        return;    case op_get_by_id:        printf("  [%4d] %s\n", instructionOffset, "get_by_id");        return;    case op_put_by_id:        printf("  [%4d] %s\n", instructionOffset, "put_by_id");        return;    case op_get_by_id_generic:        printf("  [%4d] %s\n", instructionOffset, "op_get_by_id_generic");        return;    case op_put_by_id_generic:        printf("  [%4d] %s\n", instructionOffset, "op_put_by_id_generic");        return;    case op_get_array_length:        printf("  [%4d] %s\n", instructionOffset, "op_get_array_length");        return;    case op_get_string_length:        printf("  [%4d] %s\n", instructionOffset, "op_get_string_length");        return;    default:        ASSERT_NOT_REACHED();    }}#endifvoid CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const{    unsigned instructionOffset = vPC - m_instructions.begin();    printf("  [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).UTF8String().c_str());}void CodeBlock::printStructures(const Instruction* vPC) const{    Interpreter* interpreter = m_globalData->interpreter;    unsigned instructionOffset = vPC - m_instructions.begin();    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) {        printStructure("get_by_id", vPC, 4);        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {        printStructure("get_by_id_self", vPC, 4);        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str());        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().c_str());        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structureChain).UTF8String().c_str());        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {        printStructure("put_by_id", vPC, 4);        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {        printStructure("put_by_id_replace", vPC, 4);        return;    }    if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {        printStructure("resolve_global", vPC, 4);        return;    }    // These m_instructions doesn't ref Structures.    ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));}void CodeBlock::dump(ExecState* exec) const{    if (m_instructions.isEmpty()) {        printf("No instructions available.\n");        return;    }    size_t instructionCount = 0;    for (size_t i = 0; i < m_instructions.size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(m_instructions[i].u.opcode)])        ++instructionCount;    printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",        static_cast<unsigned long>(instructionCount),        static_cast<unsigned long>(m_instructions.size() * sizeof(Instruction)),

⌨️ 快捷键说明

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