@@ -8819,6 +8819,134 @@ bool Compiler::impTailCallRetTypeCompatible(bool allowWideni
88198819 return false ;
88208820}
88218821
8822+ // ------------------------------------------------------------------------
8823+ // impTryFindField: try to find and resolve the backing field of an auto property
8824+ //
8825+ // Arguments:
8826+ // methHnd - inline candidate
8827+ // pResolvedToken - resolved field info will be stored here
8828+ // opcode - opcode that was used against the field will be stored here
8829+ //
8830+ // Notes:
8831+ // Will update inlineResult with observations and possible failure
8832+ // status (if method cannot be inlined)
8833+ //
8834+ bool Compiler::impTryFindField (CORINFO_METHOD_HANDLE methHnd, CORINFO_RESOLVED_TOKEN* pResolvedToken, OPCODE* opcode)
8835+ {
8836+ // Either EE or JIT might throw exceptions below.
8837+ // If that happens, just don't inline the method.
8838+ //
8839+ struct Param
8840+ {
8841+ Compiler* pThis;
8842+ CORINFO_METHOD_HANDLE fncHandle;
8843+ CORINFO_CONTEXT_HANDLE exactContextHnd;
8844+ CORINFO_RESOLVED_TOKEN resolvedToken;
8845+ OPCODE opcode;
8846+ bool success;
8847+ } param;
8848+ memset (¶m, 0 , sizeof (param));
8849+
8850+ param.pThis = this ;
8851+ param.fncHandle = methHnd;
8852+ param.exactContextHnd = MAKE_METHODCONTEXT (methHnd);
8853+ param.opcode = CEE_ILLEGAL;
8854+ param.success = false ;
8855+
8856+ info.compCompHnd ->beginInlining (info.compMethodHnd , methHnd);
8857+
8858+ bool success = eeRunWithErrorTrap<Param>(
8859+ [](Param* pParam) {
8860+ // Cache some frequently accessed state.
8861+ //
8862+ Compiler* const compiler = pParam->pThis ;
8863+ COMP_HANDLE compCompHnd = compiler->info .compCompHnd ;
8864+ CORINFO_METHOD_HANDLE ftn = pParam->fncHandle ;
8865+
8866+ #ifdef DEBUG
8867+ if (JitConfig.JitNoInline ())
8868+ {
8869+ compCompHnd->reportInliningDecision (compiler->info .compMethodHnd , ftn, INLINE_FAIL, " JitNoInline is set" );
8870+ return ;
8871+ }
8872+ #endif
8873+
8874+ // Fetch method info. This may fail, if the method doesn't have IL.
8875+ //
8876+ CORINFO_METHOD_INFO methInfo;
8877+ if (!compCompHnd->getMethodInfo (pParam->fncHandle , &methInfo, pParam->exactContextHnd ))
8878+ {
8879+ compCompHnd->reportInliningDecision (compiler->info .compMethodHnd , ftn, INLINE_FAIL, " getMethodInfo failed" );
8880+ return ;
8881+ }
8882+
8883+ pParam->resolvedToken .tokenContext = pParam->exactContextHnd ;
8884+ pParam->resolvedToken .tokenScope = methInfo.scope ;
8885+ pParam->resolvedToken .tokenType = CORINFO_TOKENKIND_Field;
8886+
8887+ auto code = methInfo.ILCode ;
8888+ auto size = methInfo.ILCodeSize ;
8889+ // instance getter
8890+ if (size == 7 && code[0 ] == CEE_LDARG_0 && code[1 ] == CEE_LDFLD && code[6 ] == CEE_RET)
8891+ {
8892+ pParam->resolvedToken .token = getU4LittleEndian (&code[2 ]);
8893+ pParam->opcode = CEE_LDFLD;
8894+ }
8895+ // instance setter
8896+ else if (size == 8 && code[0 ] == CEE_LDARG_0 && code[1 ] == CEE_LDARG_1 && code[2 ] == CEE_STFLD &&
8897+ code[7 ] == CEE_RET)
8898+ {
8899+ pParam->resolvedToken .token = getU4LittleEndian (&code[3 ]);
8900+ pParam->opcode = CEE_STFLD;
8901+ }
8902+ else
8903+ {
8904+ compCompHnd->reportInliningDecision (compiler->info .compMethodHnd , ftn, INLINE_FAIL, " Not a property" );
8905+ return ;
8906+ }
8907+
8908+ // Speculatively check if initClass() can be done.
8909+ // If it can be done, we will try to inline the method.
8910+ CorInfoInitClassResult const initClassResult =
8911+ compCompHnd->initClass (nullptr /* field */ , ftn /* method */ , pParam->exactContextHnd /* context */ );
8912+
8913+ if (initClassResult & CORINFO_INITCLASS_DONT_INLINE)
8914+ {
8915+ compCompHnd->reportInliningDecision (compiler->info .compMethodHnd , ftn, INLINE_FAIL,
8916+ " InitClass reported don't inline" );
8917+ return ;
8918+ }
8919+
8920+ // Given the VM the final say in whether to inline or not.
8921+ // This should be last since for verifiable code, this can be expensive
8922+ // This will call reportInliningDecision for us if inlining is not allowed
8923+ CorInfoInline const vmResult = compCompHnd->canInline (compiler->info .compMethodHnd , ftn);
8924+ if (vmResult == INLINE_FAIL || vmResult == INLINE_NEVER)
8925+ {
8926+ return ;
8927+ }
8928+
8929+ compCompHnd->resolveToken (&pParam->resolvedToken );
8930+ pParam->success = true ;
8931+ },
8932+ ¶m);
8933+
8934+ if (success && param.success )
8935+ {
8936+ *opcode = param.opcode ;
8937+ *pResolvedToken = param.resolvedToken ;
8938+ info.compCompHnd ->reportInliningDecision (info.compMethodHnd , methHnd, INLINE_PASS,
8939+ " Trivial property backing field has been inlined" );
8940+ return true ;
8941+ }
8942+ if (!success)
8943+ {
8944+ info.compCompHnd ->reportInliningDecision (info.compMethodHnd , methHnd, INLINE_FAIL,
8945+ " Failed to inline trivial property" );
8946+ }
8947+ return false ;
8948+ }
8949+
88228950// ------------------------------------------------------------------------
88238951// impCheckCanInline: do more detailed checks to determine if a method can
88248952// be inlined, and collect information that will be needed later
0 commit comments