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

📄 jit.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            emitJumpSlowCaseIfNotImmediateInteger(regT1);#if USE(ALTERNATE_JSIMMEDIATE)            // This is technically incorrect - we're zero-extending an int32.  On the hot path this doesn't matter.            // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if            // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation            // size is always less than 4Gb).  As such zero extending wil have been correct (and extending the value            // to 64-bits is necessary since it's used in the address calculation.  We zero extend rather than sign            // extending since it makes it easier to re-tag the value in the slow case.            zeroExtend32ToPtr(regT1, regT1);#else            emitFastArithImmToInt(regT1);#endif            emitJumpSlowCaseIfNotJSCell(regT0);            addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));            // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff            loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);            addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));            // Get the value from the vector            loadPtr(BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_get_by_val);        }        case op_resolve_func: {            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));            emitPutJITStubArgConstant(ident, 1);            emitCTICall(JITStubs::cti_op_resolve_func);            emitPutVirtualRegister(currentInstruction[2].u.operand, regT1);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_resolve_func);        }        case op_sub: {            compileFastArith_op_sub(currentInstruction);            NEXT_OPCODE(op_sub);        }        case op_put_by_val: {            emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1);            emitJumpSlowCaseIfNotImmediateInteger(regT1);#if USE(ALTERNATE_JSIMMEDIATE)            // See comment in op_get_by_val.            zeroExtend32ToPtr(regT1, regT1);#else            emitFastArithImmToInt(regT1);#endif            emitJumpSlowCaseIfNotJSCell(regT0);            addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));            // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff            loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);            Jump inFastVector = branch32(Below, regT1, Address(regT0, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));            // No; oh well, check if the access if within the vector - if so, we may still be okay.            addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, FIELD_OFFSET(ArrayStorage, m_vectorLength))));            // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.            // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff.             addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));            // All good - put the value into the array.            inFastVector.link(this);            emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);            storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));            NEXT_OPCODE(op_put_by_val);        }        CTI_COMPILE_BINARY_OP(op_lesseq)        case op_loop_if_true: {            emitTimeoutCheck();            unsigned target = currentInstruction[2].u.operand;            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);            Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0())));            addJump(emitJumpIfImmediateInteger(regT0), target + 2);            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);            addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));            isZero.link(this);            NEXT_OPCODE(op_loop_if_true);        };        case op_resolve_base: {            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));            emitPutJITStubArgConstant(ident, 1);            emitCTICall(JITStubs::cti_op_resolve_base);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_resolve_base);        }        case op_negate: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);            emitCTICall(JITStubs::cti_op_negate);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_negate);        }        case op_resolve_skip: {            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));            emitPutJITStubArgConstant(ident, 1);            emitPutJITStubArgConstant(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain(), 2);            emitCTICall(JITStubs::cti_op_resolve_skip);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_resolve_skip);        }        case op_resolve_global: {            // Fast case            void* globalObject = currentInstruction[2].u.jsCell;            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));                        unsigned currentIndex = globalResolveInfoIndex++;            void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);            void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);            // Check Structure of global object            move(ImmPtr(globalObject), regT0);            loadPtr(structureAddress, regT1);            Jump noMatch = branchPtr(NotEqual, regT1, Address(regT0, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match            // Load cached property            loadPtr(Address(regT0, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), regT0);            load32(offsetAddr, regT1);            loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            Jump end = jump();            // Slow case            noMatch.link(this);            emitPutJITStubArgConstant(globalObject, 1);            emitPutJITStubArgConstant(ident, 2);            emitPutJITStubArgConstant(currentIndex, 3);            emitCTICall(JITStubs::cti_op_resolve_global);            emitPutVirtualRegister(currentInstruction[1].u.operand);            end.link(this);            NEXT_OPCODE(op_resolve_global);        }        CTI_COMPILE_BINARY_OP(op_div)        case op_pre_dec: {            compileFastArith_op_pre_dec(currentInstruction[1].u.operand);            NEXT_OPCODE(op_pre_dec);        }        case op_jnless: {            unsigned op1 = currentInstruction[1].u.operand;            unsigned op2 = currentInstruction[2].u.operand;            unsigned target = currentInstruction[3].u.operand;            if (isOperandConstantImmediateInt(op2)) {                emitGetVirtualRegister(op1, regT0);                emitJumpSlowCaseIfNotImmediateInteger(regT0);#if USE(ALTERNATE_JSIMMEDIATE)                int32_t op2imm = getConstantOperandImmediateInt(op2);#else                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));#endif                addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);            } else {                emitGetVirtualRegisters(op1, regT0, op2, regT1);                emitJumpSlowCaseIfNotImmediateInteger(regT0);                emitJumpSlowCaseIfNotImmediateInteger(regT1);                addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);            }            RECORD_JUMP_TARGET(target + 3);            NEXT_OPCODE(op_jnless);        }        case op_not: {            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);            addSlowCase(branchTestPtr(NonZero, regT0, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_not);        }        case op_jfalse: {            unsigned target = currentInstruction[2].u.operand;            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0()))), target + 2);            Jump isNonZero = emitJumpIfImmediateInteger(regT0);            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);            addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));            isNonZero.link(this);            RECORD_JUMP_TARGET(target + 2);            NEXT_OPCODE(op_jfalse);        };        case op_jeq_null: {            unsigned src = currentInstruction[1].u.operand;            unsigned target = currentInstruction[2].u.operand;            emitGetVirtualRegister(src, regT0);            Jump isImmediate = emitJumpIfNotJSCell(regT0);            // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);            addJump(branchTest32(NonZero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);            Jump wasNotImmediate = jump();            // Now handle the immediate cases - undefined & null            isImmediate.link(this);            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);                        wasNotImmediate.link(this);            RECORD_JUMP_TARGET(target + 2);            NEXT_OPCODE(op_jeq_null);        };        case op_jneq_null: {            unsigned src = currentInstruction[1].u.operand;            unsigned target = currentInstruction[2].u.operand;            emitGetVirtualRegister(src, regT0);            Jump isImmediate = emitJumpIfNotJSCell(regT0);            // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);            addJump(branchTest32(Zero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);            Jump wasNotImmediate = jump();            // Now handle the immediate cases - undefined & null            isImmediate.link(this);            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);            addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);                        wasNotImmediate.link(this);            RECORD_JUMP_TARGET(target + 2);            NEXT_OPCODE(op_jneq_null);        }        case op_post_inc: {            compileFastArith_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand);            NEXT_OPCODE(op_post_inc);        }        case op_unexpected_load: {            JSValuePtr v = m_codeBlock->unexpectedConstant(currentInstruction[2].u.operand);            move(ImmPtr(JSValuePtr::encode(v)), regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_unexpected_load);        }        case op_jsr: {            int retAddrDst = currentInstruction[1].u.operand;            int target = currentInstruction[2].u.operand;            DataLabelPtr storeLocation = storePtrWithPatch(Address(callFrameRegister, sizeof(Register) * retAddrDst));            addJump(jump(), target + 2);            m_jsrSites.append(JSRInfo(storeLocation, label()));            killLastResultRegister();            RECORD_JUMP_TARGET(target + 2);            NEXT_OPCODE(op_jsr);        }        case op_sret: {            jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand));            killLastResultRegister();            NEXT_OPCODE(op_sret);        }        case op_eq: {            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);            set32(Equal, regT1, regT0, regT0);            emitTagAsBoolImmediate(regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_eq);        }        case op_lshift: {            compileFastArith_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);            NEXT_OPCODE(op_lshift);        }        case op_bitand: {            compileFastArith_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);            NEXT_OPCODE(op_bitand);        }        case op_rshift: {            compileFastArith_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);            NEXT_OPCODE(op_rshift);        }        case op_bitnot: {            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);            emitJumpSlowCaseIfNotImmediateInteger(regT0);#if USE(ALTERNATE_JSIMMEDIATE)            not32(regT0);            emitFastArithIntToImmNoCheck(regT0, regT0);#else            xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0);#endif            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_bitnot);        }        case op_resolve_with_base: {            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));            emitPutJITStubArgConstant(ident, 1);            emitCTICall(JITStubs::cti_op_resolve_with_base);            emitPutVirtualRegister(currentInstruction[2].u.operand, regT1);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_resolve_with_base);        }        case op_new_func_exp: {            FuncExprNode* func = m_codeBlock->functionExpression(currentInstruction[2].u.operand);            emitPutJITStubArgConstant(func, 1);            emitCTICall(JITStubs::cti_op_new_func_exp);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_new_func_exp);        }        case op_mod: {            compileFastArith_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);            NEXT_OPCODE(op_mod);        }

⌨️ 快捷键说明

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