From 1df4a9a289836afc957aee2aa095deda43588aaa Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 31 Mar 2015 00:25:37 -0700 Subject: [PATCH] Keep track of the first MSIL block. This addresses a couple of issues seen in the Roslyn bring-up. In `readerPrePass`, split the current block after the parameter stores and local allocas and other "run once on entry to the method" IR. The continuation block from this split is the block that corresponds to MSIL offset 0 and is also the target of branches back to offset 0. Remember this block and in `fgPrePhase` return it as the first block to use when expanding MSIL to IR. Implement the just my code hook, which requires a conditional branch in this "entry IR" sequence. Closes #272, closes #372. --- include/Reader/readerir.h | 1 + lib/Reader/readerir.cpp | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/Reader/readerir.h b/include/Reader/readerir.h index 489814e6624..a14719920b2 100644 --- a/include/Reader/readerir.h +++ b/include/Reader/readerir.h @@ -1187,6 +1187,7 @@ class GenIR : public ReaderBase { std::vector Arguments; std::vector ArgumentCorTypes; llvm::DenseMap ContinuationStoreMap; + FlowGraphNode *FirstMSILBlock; llvm::BasicBlock *UnreachableContinuationBlock; CorInfoType ReturnCorType; bool HasThis; diff --git a/lib/Reader/readerir.cpp b/lib/Reader/readerir.cpp index d3eab18e510..46e300e9cbf 100644 --- a/lib/Reader/readerir.cpp +++ b/lib/Reader/readerir.cpp @@ -336,15 +336,30 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) { throw NotYetImplementedException("synchronized method"); } - // TODO: support for JustMyCode hook if ((JitFlags & CORJIT_FLG_DEBUG_CODE) && !(JitFlags & CORJIT_FLG_IL_STUB)) { - + // Get the handle from the EE. bool IsIndirect = false; void *DebugHandle = getJustMyCodeHandle(getCurrentMethodHandle(), &IsIndirect); + // If the handle is non-null, insert the hook. if (DebugHandle != nullptr) { - throw NotYetImplementedException("just my code hook"); + const bool IsCallTarget = false; + IRNode *JustMyCodeFlagAddress = + handleToIRNode(mdtJMCHandle, DebugHandle, DebugHandle, IsIndirect, + IsIndirect, IsIndirect, IsCallTarget); + const bool IsVolatile = false; + const bool IsReadOnly = false; + IRNode *JustMyCodeFlag = + loadIndirNonNull(ReaderBaseNS::LdindI4, JustMyCodeFlagAddress, + Reader_AlignNatural, IsVolatile, IsReadOnly); + Value *Condition = LLVMBuilder->CreateIsNotNull(JustMyCodeFlag, "JMC"); + IRNode *Zero = loadConstantI4(0); + Type *Void = Type::getVoidTy(*JitContext->LLVMContext); + const bool CallReturns = true; + genConditionalHelperCall( + Condition, CorInfoHelpFunc::CORINFO_HELP_DBG_IS_JUST_MY_CODE, Void, + JustMyCodeFlag, Zero, CallReturns, "JustMyCodeHook"); } } @@ -355,6 +370,16 @@ void GenIR::readerPrePass(uint8_t *Buffer, uint32_t NumBytes) { if (InitClass) { insertClassConstructor(); } + + // Split the entry block at this point. The continuation will + // be the first block to hold the IR for MSIL opcodes and will be + // the target for MSIL offset 0 branches (and tail recursive calls). + + FlowGraphNode *CurrentFlowGraphNode = + (FlowGraphNode *)LLVMBuilder->GetInsertBlock(); + Instruction *CurrentInstruction = LLVMBuilder->GetInsertPoint(); + IRNode *CurrentIRNode = (IRNode *)CurrentInstruction; + FirstMSILBlock = fgSplitBlock(CurrentFlowGraphNode, CurrentIRNode); } void GenIR::readerMiddlePass() { return; } @@ -2080,7 +2105,7 @@ FlowGraphNode *GenIR::fgNodeGetNext(FlowGraphNode *FgNode) { } } -FlowGraphNode *GenIR::fgPrePhase(FlowGraphNode *Fg) { return Fg; } +FlowGraphNode *GenIR::fgPrePhase(FlowGraphNode *Fg) { return FirstMSILBlock; } void GenIR::fgPostPhase() { return; }