📄 jitstubs.cpp
字号:
JSGlobalData* globalData = ARG_globalData; TimeoutChecker& timeoutChecker = globalData->timeoutChecker; if (timeoutChecker.didTimeOut(ARG_callFrame)) { globalData->exception = createInterruptedExecutionException(globalData); VM_THROW_EXCEPTION_AT_END(); } return timeoutChecker.ticksUntilNextCheck();}void JITStubs::cti_register_file_check(STUB_ARGS){ BEGIN_STUB_FUNCTION(); if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->m_numCalleeRegisters))) return; // Rewind to the previous call frame because op_call already optimistically // moved the call frame forward. CallFrame* oldCallFrame = ARG_callFrame->callerFrame(); ARG_setCallFrame(oldCallFrame); throwStackOverflowError(oldCallFrame, ARG_globalData, oldCallFrame->returnPC(), STUB_RETURN_ADDRESS);}int JITStubs::cti_op_loop_if_less(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr src1 = ARG_src1; JSValuePtr src2 = ARG_src2; CallFrame* callFrame = ARG_callFrame; bool result = jsLess(callFrame, src1, src2); CHECK_FOR_EXCEPTION_AT_END(); return result;}int JITStubs::cti_op_loop_if_lesseq(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr src1 = ARG_src1; JSValuePtr src2 = ARG_src2; CallFrame* callFrame = ARG_callFrame; bool result = jsLessEq(callFrame, src1, src2); CHECK_FOR_EXCEPTION_AT_END(); return result;}JSObject* JITStubs::cti_op_new_object(STUB_ARGS){ BEGIN_STUB_FUNCTION(); return constructEmptyObject(ARG_callFrame);}void JITStubs::cti_op_put_by_id_generic(STUB_ARGS){ BEGIN_STUB_FUNCTION(); PutPropertySlot slot; ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot); CHECK_FOR_EXCEPTION_AT_END();}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_generic(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; Identifier& ident = *ARG_id2; JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(callFrame, ident, slot); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)void JITStubs::cti_op_put_by_id(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; Identifier& ident = *ARG_id2; PutPropertySlot slot; ARG_src1.put(callFrame, ident, ARG_src3, slot); ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_id_second)); CHECK_FOR_EXCEPTION_AT_END();}void JITStubs::cti_op_put_by_id_second(STUB_ARGS){ BEGIN_STUB_FUNCTION(); PutPropertySlot slot; ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot); tryCachePutByID(ARG_callFrame, ARG_callFrame->codeBlock(), STUB_RETURN_ADDRESS, ARG_src1, slot); CHECK_FOR_EXCEPTION_AT_END();}void JITStubs::cti_op_put_by_id_fail(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; Identifier& ident = *ARG_id2; PutPropertySlot slot; ARG_src1.put(callFrame, ident, ARG_src3, slot); CHECK_FOR_EXCEPTION_AT_END();}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; Identifier& ident = *ARG_id2; JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(callFrame, ident, slot); ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_second)); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_second(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; Identifier& ident = *ARG_id2; JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(callFrame, ident, slot); tryCacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_self_fail(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; Identifier& ident = *ARG_id2; JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(callFrame, ident, slot); CHECK_FOR_EXCEPTION(); if (baseValue.isCell() && slot.isCacheable() && !asCell(baseValue)->structure()->isDictionary() && slot.slotBase() == baseValue) { CodeBlock* codeBlock = callFrame->codeBlock(); StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); ASSERT(slot.slotBase().isObject()); PolymorphicAccessStructureList* polymorphicStructureList; int listIndex = 1; if (stubInfo->opcodeID == op_get_by_id_self) { ASSERT(!stubInfo->stubRoutine); polymorphicStructureList = new PolymorphicAccessStructureList(MacroAssembler::CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure); stubInfo->initGetByIdSelfList(polymorphicStructureList, 2); } else { polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList; listIndex = stubInfo->u.getByIdSelfList.listSize; stubInfo->u.getByIdSelfList.listSize++; } JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset()); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic)); } else { ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic)); } return JSValuePtr::encode(result);}static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex){ PolymorphicAccessStructureList* prototypeStructureList = 0; listIndex = 1; switch (stubInfo->opcodeID) { case op_get_by_id_proto: prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure); stubInfo->stubRoutine.reset(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; case op_get_by_id_chain: prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain); stubInfo->stubRoutine.reset(); stubInfo->initGetByIdProtoList(prototypeStructureList, 2); break; case op_get_by_id_proto_list: prototypeStructureList = stubInfo->u.getByIdProtoList.structureList; listIndex = stubInfo->u.getByIdProtoList.listSize; stubInfo->u.getByIdProtoList.listSize++; break; default: ASSERT_NOT_REACHED(); } ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE); return prototypeStructureList;}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_proto_list(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(callFrame, *ARG_id2, slot); CHECK_FOR_EXCEPTION(); if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) { ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail)); return JSValuePtr::encode(result); } Structure* structure = asCell(baseValue)->structure(); CodeBlock* codeBlock = callFrame->codeBlock(); StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS); ASSERT(slot.slotBase().isObject()); JSObject* slotBaseObject = asObject(slot.slotBase()); if (slot.slotBase() == baseValue) ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail)); else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) { // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. if (slotBaseObject->structure()->isDictionary()) slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure())); int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset()); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full)); } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) { int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, structure->prototypeChain(callFrame), count, slot.cachedOffset()); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full)); } else ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail)); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_proto_list_full(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_proto_fail(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_array_fail(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_string_fail(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr baseValue = ARG_src1; PropertySlot slot(baseValue); JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}#endifJSValueEncodedAsPointer* JITStubs::cti_op_instanceof(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; JSValuePtr value = ARG_src1; JSValuePtr baseVal = ARG_src2; JSValuePtr proto = ARG_src3; // at least one of these checks must have failed to get to the slow case ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell() || !value.isObject() || !baseVal.isObject() || !proto.isObject() || (asObject(baseVal)->structure()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance); if (!baseVal.isObject()) { CallFrame* callFrame = ARG_callFrame; CodeBlock* codeBlock = callFrame->codeBlock(); unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS); ARG_globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, vPCIndex, codeBlock); VM_THROW_EXCEPTION(); } if (!asObject(baseVal)->structure()->typeInfo().implementsHasInstance()) return JSValuePtr::encode(jsBoolean(false)); if (!proto.isObject()) { throwError(callFrame, TypeError, "instanceof called on an object with an invalid prototype property."); VM_THROW_EXCEPTION(); } if (!value.isObject()) return JSValuePtr::encode(jsBoolean(false)); JSValuePtr result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto)); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_del_by_id(STUB_ARGS){ BEGIN_STUB_FUNCTION(); CallFrame* callFrame = ARG_callFrame; JSObject* baseObj = ARG_src1.toObject(callFrame); JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, *ARG_id2)); CHECK_FOR_EXCEPTION_AT_END(); return JSValuePtr::encode(result);}JSValueEncodedAsPointer* JITStubs::cti_op_mul(STUB_ARGS){ BEGIN_STUB_FUNCTION(); JSValuePtr src1 = ARG_src1; JSValuePtr src2 = ARG_src2; double left; double right; if (src1.getNumber(left) && src2.getNumber(right)) return JSValuePtr::encode(jsNumber(ARG_globalData, left * right)); CallFrame* callFrame = ARG_callFrame;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -