SuperPMI: Fix `getFieldType` (#25102)
authorCarol Eidt <carol.eidt@microsoft.com>
Wed, 12 Jun 2019 16:07:32 +0000 (09:07 -0700)
committerGitHub <noreply@github.com>
Wed, 12 Jun 2019 16:07:32 +0000 (09:07 -0700)
* SuperPMI: Fix `getFieldType`

The `structType` out parameter is optional (i.e. it may be null), but it's not used as a key, so we need to update the map if we've saved a null but encounter a non-null.

src/ToolBox/superpmi/superpmi-shared/lightweightmap.h
src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
src/jit/lclvars.cpp

index 069287c..cba843a 100644 (file)
@@ -299,7 +299,7 @@ public:
         return size;
     }
 
-    // its worth noting that the acutal order of insert here doesnt meet what you migth expect.  Its using memcmp, so
+    // It's worth noting that the actual order of insertion here doesnt meet what you might expect.  It's using memcmp, so
     // since we are on a little endian machine we'd use the lowest 8 bits as the first part of the key.  This is
     // a side effect of using the same code for large structs and DWORDS etc...
     bool Add(_Key key, _Item item)
@@ -366,6 +366,11 @@ public:
         return true;
     }
 
+    void Update(int index, _Item item)
+    {
+        pItems[index] = item;
+    }
+
     int GetIndex(_Key key)
     {
         AssertCodeMsg(this != nullptr, EXCEPTIONCODE_MC, "There is no such LWM (in GetIndex)");
index 96e95d1..d7d7ab0 100644 (file)
@@ -4353,6 +4353,7 @@ void MethodContext::recGetFieldType(CORINFO_FIELD_HANDLE  field,
     key.A = (DWORDLONG)field;
     key.B = (DWORDLONG)memberParent;
 
+    value.B = (DWORD)result;
     if (structType == nullptr)
     {
         value.A = 0;
@@ -4360,9 +4361,18 @@ void MethodContext::recGetFieldType(CORINFO_FIELD_HANDLE  field,
     else
     {
         value.A = (DWORDLONG)*structType;
-    }
-    value.B = (DWORD)result;
 
+        // If we had a previous call with null 'structType', we will not have captured the
+        // class handle (we use only 'field' and 'memberParent' as keys).
+        // Update the value in that case.
+        unsigned index = GetFieldType->GetIndex(key);
+        if ((index != -1) && (GetFieldType->GetItem(index).A == 0))
+        {
+            GetFieldType->Update(index, value);
+            DEBUG_REC(dmpGetFieldType(key, value));
+            return;
+        }
+    }
     GetFieldType->Add(key, value);
     DEBUG_REC(dmpGetFieldType(key, value));
 }
index 6b26b5d..2acbef2 100644 (file)
@@ -2055,7 +2055,7 @@ bool Compiler::StructPromotionHelper::TryPromoteStructField(lvaStructFieldInfo&
     if (fieldSize == 0 || fieldSize > TARGET_POINTER_SIZE || varTypeIsFloating(fieldVarType))
     {
         JITDUMP("Promotion blocked: struct contains struct field with one field,"
-                " but that field has invalid size or type");
+                " but that field has invalid size or type.\n");
         return false;
     }
 
@@ -2066,7 +2066,7 @@ bool Compiler::StructPromotionHelper::TryPromoteStructField(lvaStructFieldInfo&
         if ((outerFieldOffset % fieldSize) != 0)
         {
             JITDUMP("Promotion blocked: struct contains struct field with one field,"
-                    " but the outer struct offset %u is not a multiple of the inner field size %u",
+                    " but the outer struct offset %u is not a multiple of the inner field size %u.\n",
                     outerFieldOffset, fieldSize);
             return false;
         }
@@ -2078,7 +2078,7 @@ bool Compiler::StructPromotionHelper::TryPromoteStructField(lvaStructFieldInfo&
     if (fieldSize != innerStructSize)
     {
         JITDUMP("Promotion blocked: struct contains struct field with one field,"
-                " but that field is not the same size as its parent.");
+                " but that field is not the same size as its parent.\n");
         return false;
     }