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

📄 jit.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        case op_jtrue: {            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);            RECORD_JUMP_TARGET(target + 2);            NEXT_OPCODE(op_jtrue);        }        CTI_COMPILE_BINARY_OP(op_less)        case op_neq: {            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);            set32(NotEqual, regT1, regT0, regT0);            emitTagAsBoolImmediate(regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_neq);        }        case op_post_dec: {            compileFastArith_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand);            NEXT_OPCODE(op_post_dec);        }        CTI_COMPILE_BINARY_OP(op_urshift)        case op_bitxor: {            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);            xorPtr(regT1, regT0);            emitFastArithReTagImmediate(regT0, regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_bitxor);        }        case op_new_regexp: {            RegExp* regExp = m_codeBlock->regexp(currentInstruction[2].u.operand);            emitPutJITStubArgConstant(regExp, 1);            emitCTICall(JITStubs::cti_op_new_regexp);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_new_regexp);        }        case op_bitor: {            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);            orPtr(regT1, regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_bitor);        }        case op_throw: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);            emitCTICall(JITStubs::cti_op_throw);            ASSERT(regT0 == returnValueRegister);#if PLATFORM(X86_64)            addPtr(Imm32(0x48), X86::esp);            pop(X86::ebx);            pop(X86::r15);            pop(X86::r14);            pop(X86::r13);            pop(X86::r12);            pop(X86::ebp);            ret();#else            addPtr(Imm32(0x1c), X86::esp);            pop(X86::ebx);            pop(X86::edi);            pop(X86::esi);            pop(X86::ebp);            ret();#endif            NEXT_OPCODE(op_throw);        }        case op_get_pnames: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);            emitCTICall(JITStubs::cti_op_get_pnames);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_get_pnames);        }        case op_next_pname: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);            unsigned target = currentInstruction[3].u.operand;            emitCTICall(JITStubs::cti_op_next_pname);            Jump endOfIter = branchTestPtr(Zero, regT0);            emitPutVirtualRegister(currentInstruction[1].u.operand);            addJump(jump(), target + 3);            endOfIter.link(this);            NEXT_OPCODE(op_next_pname);        }        case op_push_scope: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);            emitCTICall(JITStubs::cti_op_push_scope);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_push_scope);        }        case op_pop_scope: {            emitCTICall(JITStubs::cti_op_pop_scope);            NEXT_OPCODE(op_pop_scope);        }        CTI_COMPILE_UNARY_OP(op_typeof)        CTI_COMPILE_UNARY_OP(op_is_undefined)        CTI_COMPILE_UNARY_OP(op_is_boolean)        CTI_COMPILE_UNARY_OP(op_is_number)        CTI_COMPILE_UNARY_OP(op_is_string)        CTI_COMPILE_UNARY_OP(op_is_object)        CTI_COMPILE_UNARY_OP(op_is_function)        case op_stricteq: {            compileOpStrictEq(currentInstruction, OpStrictEq);            NEXT_OPCODE(op_stricteq);        }        case op_nstricteq: {            compileOpStrictEq(currentInstruction, OpNStrictEq);            NEXT_OPCODE(op_nstricteq);        }        case op_to_jsnumber: {            int srcVReg = currentInstruction[2].u.operand;            emitGetVirtualRegister(srcVReg, regT0);                        Jump wasImmediate = emitJumpIfImmediateInteger(regT0);            emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);            addSlowCase(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));                        wasImmediate.link(this);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_to_jsnumber);        }        CTI_COMPILE_BINARY_OP(op_in)        case op_push_new_scope: {            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));            emitPutJITStubArgConstant(ident, 1);            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);            emitCTICall(JITStubs::cti_op_push_new_scope);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_push_new_scope);        }        case op_catch: {            emitGetCTIParam(STUB_ARGS_callFrame, callFrameRegister);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_catch);        }        case op_jmp_scopes: {            unsigned count = currentInstruction[1].u.operand;            emitPutJITStubArgConstant(count, 1);            emitCTICall(JITStubs::cti_op_jmp_scopes);            unsigned target = currentInstruction[2].u.operand;            addJump(jump(), target + 2);            RECORD_JUMP_TARGET(target + 2);            NEXT_OPCODE(op_jmp_scopes);        }        case op_put_by_index: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);            emitCTICall(JITStubs::cti_op_put_by_index);            NEXT_OPCODE(op_put_by_index);        }        case op_switch_imm: {            unsigned tableIndex = currentInstruction[1].u.operand;            unsigned defaultOffset = currentInstruction[2].u.operand;            unsigned scrutinee = currentInstruction[3].u.operand;            // create jump table for switch destinations, track this switch statement.            SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex);            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate));            jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);            emitPutJITStubArgConstant(tableIndex, 2);            emitCTICall(JITStubs::cti_op_switch_imm);            jump(regT0);            NEXT_OPCODE(op_switch_imm);        }        case op_switch_char: {            unsigned tableIndex = currentInstruction[1].u.operand;            unsigned defaultOffset = currentInstruction[2].u.operand;            unsigned scrutinee = currentInstruction[3].u.operand;            // create jump table for switch destinations, track this switch statement.            SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex);            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character));            jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);            emitPutJITStubArgConstant(tableIndex, 2);            emitCTICall(JITStubs::cti_op_switch_char);            jump(regT0);            NEXT_OPCODE(op_switch_char);        }        case op_switch_string: {            unsigned tableIndex = currentInstruction[1].u.operand;            unsigned defaultOffset = currentInstruction[2].u.operand;            unsigned scrutinee = currentInstruction[3].u.operand;            // create jump table for switch destinations, track this switch statement.            StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);            emitPutJITStubArgConstant(tableIndex, 2);            emitCTICall(JITStubs::cti_op_switch_string);            jump(regT0);            NEXT_OPCODE(op_switch_string);        }        case op_del_by_val: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);            emitCTICall(JITStubs::cti_op_del_by_val);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_del_by_val);        }        case op_put_getter: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));            emitPutJITStubArgConstant(ident, 2);            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);            emitCTICall(JITStubs::cti_op_put_getter);            NEXT_OPCODE(op_put_getter);        }        case op_put_setter: {            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));            emitPutJITStubArgConstant(ident, 2);            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);            emitCTICall(JITStubs::cti_op_put_setter);            NEXT_OPCODE(op_put_setter);        }        case op_new_error: {            JSValuePtr message = m_codeBlock->unexpectedConstant(currentInstruction[3].u.operand);            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);            emitPutJITStubArgConstant(JSValuePtr::encode(message), 2);            emitPutJITStubArgConstant(m_bytecodeIndex, 3);            emitCTICall(JITStubs::cti_op_new_error);            emitPutVirtualRegister(currentInstruction[1].u.operand);            NEXT_OPCODE(op_new_error);        }        case op_debug: {            emitPutJITStubArgConstant(currentInstruction[1].u.operand, 1);            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);            emitPutJITStubArgConstant(currentInstruction[3].u.operand, 3);            emitCTICall(JITStubs::cti_op_debug);            NEXT_OPCODE(op_debug);        }        case op_eq_null: {            unsigned dst = currentInstruction[1].u.operand;            unsigned src1 = currentInstruction[2].u.operand;            emitGetVirtualRegister(src1, regT0);            Jump isImmediate = emitJumpIfNotJSCell(regT0);            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);            setTest32(NonZero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);            Jump wasNotImmediate = jump();            isImmediate.link(this);            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);            setPtr(Equal, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);            wasNotImmediate.link(this);            emitTagAsBoolImmediate(regT0);            emitPutVirtualRegister(dst);            NEXT_OPCODE(op_eq_null);        }        case op_neq_null: {            unsigned dst = currentInstruction[1].u.operand;            unsigned src1 = currentInstruction[2].u.operand;            emitGetVirtualRegister(src1, regT0);            Jump isImmediate = emitJumpIfNotJSCell(regT0);            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);            setTest32(Zero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);            Jump wasNotImmediate = jump();            isImmediate.link(this);            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);            setPtr(NotEqual, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);            wasNotImmediate.link(this);            emitTagAsBoolImmediate(regT0);            emitPutVirtualRegister(dst);            NEXT_OPCODE(op_neq_null);        }        case op_enter: {            // Even though CTI doesn't use them, we initialize our constant            // registers to zap stale pointers, to avoid unnecessarily prolonging            // object lifetime and increasing GC pressure.

⌨️ 快捷键说明

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