Skip to content

Commit

Permalink
Keep track of the first MSIL block.
Browse files Browse the repository at this point in the history
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` skip over any blocks that come before it in the flow graph block list.

Implement the just my code hook, which requires a conditional branch in this "entry IR" sequence.

Closes dotnet#272, closes dotnet#372.
  • Loading branch information
AndyAyersMS committed Mar 31, 2015
1 parent 165bc97 commit 65c6461
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/Reader/readerir.h
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,7 @@ class GenIR : public ReaderBase {
std::vector<llvm::Value *> Arguments;
std::vector<CorInfoType> ArgumentCorTypes;
llvm::DenseMap<uint32_t, llvm::StoreInst *> ContinuationStoreMap;
FlowGraphNode *FirstMSILBlock;
llvm::BasicBlock *UnreachableContinuationBlock;
CorInfoType ReturnCorType;
bool HasThis;
Expand Down
38 changes: 34 additions & 4 deletions lib/Reader/readerir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
bool IsCallTarget = false;
IRNode *JustMyCodeFlagAddress =
handleToIRNode(mdtJMCHandle, DebugHandle, DebugHandle, IsIndirect,
IsIndirect, IsIndirect, IsCallTarget);
bool IsVolatile = false;
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);
bool CallReturns = true;
genConditionalHelperCall(
Condition, CorInfoHelpFunc::CORINFO_HELP_DBG_IS_JUST_MY_CODE, Void,
JustMyCodeFlag, Zero, CallReturns, "JustMyCodeHook");
}
}

Expand All @@ -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; }
Expand Down Expand Up @@ -2080,7 +2105,12 @@ FlowGraphNode *GenIR::fgNodeGetNext(FlowGraphNode *FgNode) {
}
}

FlowGraphNode *GenIR::fgPrePhase(FlowGraphNode *Fg) { return Fg; }
FlowGraphNode *GenIR::fgPrePhase(FlowGraphNode *Fg) {
while (Fg != FirstMSILBlock) {
Fg = fgNodeGetNext(Fg);
}
return Fg;
}

void GenIR::fgPostPhase() { return; }

Expand Down

0 comments on commit 65c6461

Please sign in to comment.