Inliner: small changes to inline xml
authorAndy Ayers <andya@microsoft.com>
Fri, 13 May 2016 07:39:14 +0000 (00:39 -0700)
committerAndy Ayers <andya@microsoft.com>
Wed, 18 May 2016 18:10:04 +0000 (11:10 -0700)
Emit the hash for callees, and check it during replay.

Capture the root method name, and do a simple Xml-safe conversion.

Add a missing newline to the banner message announcing that the replay
policy is in effect.

src/jit/inline.cpp
src/jit/inlinepolicy.cpp
src/jit/inlinepolicy.h

index 1acea8e..5898315 100644 (file)
@@ -479,11 +479,6 @@ void InlineContext::DumpXml(FILE* file, unsigned indent)
         m_Sibling->DumpXml(file, indent);
     }
 
-    Compiler* compiler = m_InlineStrategy->GetCompiler();
-
-    mdMethodDef calleeToken =
-        compiler->info.compCompHnd->getMethodDefFromMethod(m_Callee);
-
     const bool isRoot = m_Parent == nullptr;
     const bool hasChild = m_Child != nullptr;
     const char* inlineType = m_Success ? "Inline" : "FailedInline";
@@ -491,6 +486,13 @@ void InlineContext::DumpXml(FILE* file, unsigned indent)
 
     if (!isRoot)
     {
+        Compiler* compiler = m_InlineStrategy->GetCompiler();
+
+        mdMethodDef calleeToken =
+            compiler->info.compCompHnd->getMethodDefFromMethod(m_Callee);
+        unsigned calleeHash =
+            compiler->info.compCompHnd->getMethodHash(m_Callee);
+
         const char* inlineReason = InlGetObservationString(m_Observation);
 
         int offset = -1;
@@ -501,6 +503,7 @@ void InlineContext::DumpXml(FILE* file, unsigned indent)
 
         fprintf(file, "%*s<%s>\n", indent, "", inlineType);
         fprintf(file, "%*s<Token>%u</Token>\n", indent + 2, "", calleeToken);
+        fprintf(file, "%*s<Hash>%u</Hash>\n", indent + 2, "", calleeHash);
         fprintf(file, "%*s<Offset>%u</Offset>\n", indent + 2, "", offset);
         fprintf(file, "%*s<Reason>%s</Reason>\n", indent + 2, "", inlineReason);
         newIndent = indent + 2;
@@ -1331,9 +1334,40 @@ void InlineStrategy::DumpXml(FILE* file, unsigned indent)
         microsecondsSpentJitting = (unsigned) ((counts / countsPerSec) * 1000 * 1000);
     }
 
+    // Get method name just for root method, to make it a bit easier
+    // to search for things in the inline xml.
+    const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr);
+
+    // Cheap xml quoting for values. Only < and & are troublemakers,
+    // but change > for symmetry.
+    //
+    // Ok to truncate name, just ensure it's null terminated.
+    char buf[64];
+    strncpy(buf, methodName, sizeof(buf));
+    buf[sizeof(buf)-1] = 0;
+
+    for (int i = 0; i < sizeof(buf); i++)
+    {
+        switch (buf[i])
+        {
+        case '<':
+            buf[i] = '[';
+            break;
+        case '>':
+            buf[i] = ']';
+            break;
+        case '&':
+            buf[i] = '#';
+            break;
+        default:
+            break;
+        }
+    }
+
     fprintf(file, "%*s<Method>\n", indent, "");
     fprintf(file, "%*s<Token>%u</Token>\n", indent + 2, "", currentMethodToken);
     fprintf(file, "%*s<Hash>%u</Hash>\n", indent + 2, "", hash);
+    fprintf(file, "%*s<Name>%s</Name>\n", indent + 2, "", buf);
     fprintf(file, "%*s<InlineCount>%u</InlineCount>\n", indent + 2, "", m_InlineCount);
     fprintf(file, "%*s<HotSize>%u</HotSize>\n", indent + 2, "", info.compTotalHotCodeSize);
     fprintf(file, "%*s<ColdSize>%u</ColdSize>\n", indent + 2, "", info.compTotalColdCodeSize);
index deaa849..c251d14 100644 (file)
@@ -2078,7 +2078,7 @@ ReplayPolicy::ReplayPolicy(Compiler* compiler, InlineContext* inlineContext, boo
             // Nope, open it up.
             const wchar_t* replayFileName = JitConfig.JitInlineReplayFile();
             s_ReplayFile = _wfopen(replayFileName, W("r"));
-            fprintf(stderr, "*** %s inlines from %ws",
+            fprintf(stderr, "*** %s inlines from %ws\n",
                     s_ReplayFile == nullptr ? "Unable to replay" : "Replaying",
                     replayFileName);
             s_WroteReplayBanner = true;
@@ -2208,12 +2208,15 @@ bool ReplayPolicy::FindContext(InlineContext* context)
     // File pointer should be pointing at the parent context level.
     // See if we see an inline entry for this context.
     //
-    // Token we're looking for.
+    // Token and Hash we're looking for.
     mdMethodDef contextToken =
         m_RootCompiler->info.compCompHnd->getMethodDefFromMethod(
             context->GetCallee());
+    unsigned contextHash =
+        m_RootCompiler->info.compCompHnd->getMethodHash(
+            context->GetCallee());
 
-    return FindInline(contextToken);
+    return FindInline(contextToken, contextHash);
 }
 
 //------------------------------------------------------------------------
@@ -2221,6 +2224,7 @@ bool ReplayPolicy::FindContext(InlineContext* context)
 //
 // Arguments:
 //    token -- token describing the inline
+//    hash  -- hash describing the inline
 //
 // ReturnValue:
 //    true if the inline entry was found
@@ -2229,10 +2233,11 @@ bool ReplayPolicy::FindContext(InlineContext* context)
 //    Assumes file position has just been set by a successful call to
 //    FindMethod or FindContext.
 //
-//    Token will not be sufficiently unique to identify a particular
-//    inline, if there are multiple calls to the same method.
+//    Token and Hash will not be sufficiently unique to identify a
+//    particular inline, if there are multiple calls to the same
+//    method.
 
-bool ReplayPolicy::FindInline(unsigned token)
+bool ReplayPolicy::FindInline(unsigned token, unsigned hash)
 {
     char buffer[256];
     bool foundInline = false;
@@ -2308,13 +2313,29 @@ bool ReplayPolicy::FindInline(unsigned token)
         unsigned inlineToken = 0;
         int count = sscanf(buffer, " <Token>%u</Token> ", &inlineToken);
 
-        // Need a secondary check here for callsite
-        // ID... offset or similar. Hash would be nice too.
+        // Need a secondary check here for callsite.
+        // ...offset or similar.
         if ((count != 1) || (inlineToken != token))
         {
             continue;
         }
 
+        // Get next line
+        if (fgets(buffer, sizeof(buffer), s_ReplayFile) == nullptr)
+        {
+            break;
+        }
+
+        unsigned inlineHash = 0;
+        count = sscanf(buffer, " <Hash>%u</Hash> ", &inlineHash);
+
+        // Need a secondary check here for callsite ID
+        // ... offset or similar.
+        if ((count != 1) || (inlineHash != hash))
+        {
+            continue;
+        }
+
         // We're good!
         foundInline = true;
         break;
@@ -2342,11 +2363,13 @@ bool ReplayPolicy::FindInline(unsigned token)
 
 bool ReplayPolicy::FindInline(CORINFO_METHOD_HANDLE callee)
 {
-    // Token we're looking for
+    // Token and Hash we're looking for
     mdMethodDef calleeToken =
         m_RootCompiler->info.compCompHnd->getMethodDefFromMethod(callee);
+    unsigned calleeHash =
+        m_RootCompiler->info.compCompHnd->getMethodHash(callee);
 
-    bool foundInline = FindInline(calleeToken);
+    bool foundInline = FindInline(calleeToken, calleeHash);
 
     return foundInline;
 }
index 29e6af4..f8bb34a 100644 (file)
@@ -361,7 +361,7 @@ private:
     bool FindMethod();
     bool FindContext(InlineContext* context);
     bool FindInline(CORINFO_METHOD_HANDLE callee);
-    bool FindInline(unsigned token);
+    bool FindInline(unsigned token, unsigned hash);
 
     static bool    s_WroteReplayBanner;
     static FILE*   s_ReplayFile;