Additional fixes for RelativePointer, FixupPointer, RelativeFixupPointer, PlainPointer
authorGleb Balykov <g.balykov@samsung.com>
Thu, 22 Jun 2017 16:28:32 +0000 (19:28 +0300)
committerGleb Balykov <g.balykov@samsung.com>
Mon, 10 Jul 2017 13:37:05 +0000 (16:37 +0300)
Commit migrated from https://github.com/dotnet/coreclr/commit/e8adb62978b887eda3617dff7eccec1fc7719d07

src/coreclr/src/inc/fixuppointer.h
src/coreclr/src/vm/ceeload.cpp
src/coreclr/src/vm/debughelp.cpp

index 20eb9d8..a711418 100644 (file)
@@ -214,15 +214,38 @@ public:
         return dac_cast<PTR_TYPE>(addr);
     }
 
+    // Returns value of the encoded pointer.
+    FORCEINLINE PTR_TYPE GetValueMaybeNull() const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        return GetValue();
+    }
+
+#ifndef DACCESS_COMPILE
     // Returns the pointer to the indirection cell.
     PTR_TYPE * GetValuePtr() const
     {
-        LIMITED_METHOD_DAC_CONTRACT;
+        LIMITED_METHOD_CONTRACT;
         TADDR addr = m_addr;
         if ((addr & FIXUP_POINTER_INDIRECTION) != 0)
-            return dac_cast<DPTR(PTR_TYPE)>(addr - FIXUP_POINTER_INDIRECTION);
+            return (PTR_TYPE *)(addr - FIXUP_POINTER_INDIRECTION);
         return (PTR_TYPE *)&m_addr;
     }
+#endif // !DACCESS_COMPILE
+
+    // Static version of GetValue. It is meant to simplify access to arrays of pointers.
+    FORCEINLINE static PTR_TYPE GetValueAtPtr(TADDR base)
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        return dac_cast<DPTR(FixupPointer<PTR_TYPE>)>(base)->GetValue();
+    }
+
+    // Static version of GetValueMaybeNull. It is meant to simplify access to arrays of pointers.
+    FORCEINLINE static PTR_TYPE GetValueMaybeNullAtPtr(TADDR base)
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        return dac_cast<DPTR(FixupPointer<PTR_TYPE>)>(base)->GetValueMaybeNull();
+    }
 
     // Returns value of the encoded pointer.
     // Allows the value to be tagged.
@@ -235,12 +258,20 @@ public:
         return addr;
     }
 
+#ifndef DACCESS_COMPILE
     void SetValue(PTR_TYPE addr)
     {
         LIMITED_METHOD_CONTRACT;
         m_addr = dac_cast<TADDR>(addr);
     }
 
+    void SetValueMaybeNull(PTR_TYPE addr)
+    {
+        LIMITED_METHOD_CONTRACT;
+        SetValue(addr);
+    }
+#endif // !DACCESS_COMPILE
+
 private:
     TADDR m_addr;
 };
@@ -270,9 +301,6 @@ public:
     RelativeFixupPointer<PTR_TYPE>& operator = (const RelativeFixupPointer<PTR_TYPE> &) =delete;
     RelativeFixupPointer<PTR_TYPE>& operator = (RelativeFixupPointer<PTR_TYPE> &&) =delete;
 
-    // Default constructor
-    RelativeFixupPointer<PTR_TYPE>() {}
-
     // Returns whether the encoded pointer is NULL.
     BOOL IsNull() const
     {
@@ -292,11 +320,12 @@ public:
     }
 
 #ifndef DACCESS_COMPILE
+    // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet.
+    // Does not need explicit base and thus can be used in non-DAC builds only.
     FORCEINLINE BOOL IsTagged() const
     {
         LIMITED_METHOD_CONTRACT;
-        TADDR base = (TADDR) this;
-        return IsTagged(base);
+        return IsTagged((TADDR)this);
     }
 #endif // !DACCESS_COMPILE
 
@@ -391,21 +420,14 @@ public:
     }
 #endif
 
-    // Returns the pointer to the indirection cell.
-    PTR_TYPE * GetValuePtr(TADDR base) const
-    {
-        LIMITED_METHOD_CONTRACT;
-        TADDR addr = base + m_delta;
-        _ASSERTE((addr & FIXUP_POINTER_INDIRECTION) != 0);
-        return dac_cast<DPTR(PTR_TYPE)>(addr - FIXUP_POINTER_INDIRECTION);
-    }
-
 #ifndef DACCESS_COMPILE
+    // Returns the pointer to the indirection cell.
     PTR_TYPE * GetValuePtr() const
     {
         LIMITED_METHOD_CONTRACT;
-        TADDR base = (TADDR) this;
-        return GetValuePtr(base);
+        TADDR addr = ((TADDR)this) + m_delta;
+        _ASSERTE((addr & FIXUP_POINTER_INDIRECTION) != 0);
+        return (PTR_TYPE *)(addr - FIXUP_POINTER_INDIRECTION);
     }
 #endif // !DACCESS_COMPILE
 
@@ -421,6 +443,48 @@ public:
         return addr;
     }
 
+    // Returns whether pointer is indirect. Assumes that the value is not NULL.
+    bool IsIndirectPtr(TADDR base) const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        PRECONDITION(!IsNull());
+
+        TADDR addr = base + m_delta;
+
+        return (addr & FIXUP_POINTER_INDIRECTION) != 0;
+    }
+
+#ifndef DACCESS_COMPILE
+    // Returns whether pointer is indirect. Assumes that the value is not NULL.
+    // Does not need explicit base and thus can be used in non-DAC builds only.
+    bool IsIndirectPtr() const
+    {
+        LIMITED_METHOD_CONTRACT;
+        return IsIndirectPtr((TADDR)this);
+    }
+#endif
+
+    // Returns whether pointer is indirect. The value can be NULL.
+    bool IsIndirectPtrMaybeNull(TADDR base) const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        if (m_delta == 0)
+            return false;
+
+        return IsIndirectPtr(base);
+    }
+
+#ifndef DACCESS_COMPILE
+    // Returns whether pointer is indirect. The value can be NULL.
+    // Does not need explicit base and thus can be used in non-DAC builds only.
+    bool IsIndirectPtrMaybeNull() const
+    {
+        LIMITED_METHOD_CONTRACT;
+        return IsIndirectPtrMaybeNull((TADDR)this);
+    }
+#endif
+
 private:
 #ifndef DACCESS_COMPILE
     Volatile<TADDR> m_delta;
@@ -453,10 +517,20 @@ public:
     }
 
     // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet.
+    BOOL IsTagged(TADDR base) const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+        return IsTagged();
+    }
+
+    // Returns whether the indirection cell contain fixup that has not been converted to real pointer yet.
     BOOL IsTagged() const
     {
         LIMITED_METHOD_DAC_CONTRACT;
-        return m_ptr & 1;
+        TADDR addr = m_ptr;
+        if ((addr & FIXUP_POINTER_INDIRECTION) != 0)
+             return (*PTR_TADDR(addr - FIXUP_POINTER_INDIRECTION) & 1) != 0;
+        return FALSE;
     }
 
     // Returns value of the encoded pointer.
@@ -466,12 +540,17 @@ public:
         return dac_cast<PTR_TYPE>(m_ptr);
     }
 
+#ifndef DACCESS_COMPILE
     // Returns the pointer to the indirection cell.
     PTR_TYPE * GetValuePtr() const
     {
-        LIMITED_METHOD_DAC_CONTRACT;
+        LIMITED_METHOD_CONTRACT;
+        TADDR addr = m_ptr;
+        if ((addr & FIXUP_POINTER_INDIRECTION) != 0)
+            return (PTR_TYPE *)(addr - FIXUP_POINTER_INDIRECTION);
         return (PTR_TYPE *)&m_ptr;
     }
+#endif // !DACCESS_COMPILE
 
     // Returns value of the encoded pointer. Assumes that the pointer is not NULL.
     PTR_TYPE GetValue(TADDR base) const
@@ -508,6 +587,42 @@ public:
         return dac_cast<DPTR(PlainPointer<PTR_TYPE>)>(base)->GetValueMaybeNull(base);
     }
 
+    // Returns whether pointer is indirect. Assumes that the value is not NULL.
+    bool IsIndirectPtr(TADDR base) const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        return (m_ptr & FIXUP_POINTER_INDIRECTION) != 0;
+    }
+
+#ifndef DACCESS_COMPILE
+    // Returns whether pointer is indirect. Assumes that the value is not NULL.
+    // Does not need explicit base and thus can be used in non-DAC builds only.
+    bool IsIndirectPtr() const
+    {
+        LIMITED_METHOD_CONTRACT;
+        return IsIndirectPtr((TADDR)this);
+    }
+#endif
+
+    // Returns whether pointer is indirect. The value can be NULL.
+    bool IsIndirectPtrMaybeNull(TADDR base) const
+    {
+        LIMITED_METHOD_DAC_CONTRACT;
+
+        return IsIndirectPtr(base);
+    }
+
+#ifndef DACCESS_COMPILE
+    // Returns whether pointer is indirect. The value can be NULL.
+    // Does not need explicit base and thus can be used in non-DAC builds only.
+    bool IsIndirectPtrMaybeNull() const
+    {
+        LIMITED_METHOD_CONTRACT;
+        return IsIndirectPtrMaybeNull((TADDR)this);
+    }
+#endif
+
 #ifndef DACCESS_COMPILE
     void SetValue(PTR_TYPE addr)
     {
index 857c67e..ff8c17e 100644 (file)
@@ -10248,11 +10248,11 @@ void Module::RestoreMethodTablePointer(RelativeFixupPointer<PTR_MethodTable> * p
 
     if (ppMT->IsTagged((TADDR)ppMT))
     {
-        RestoreMethodTablePointerRaw(ppMT->GetValuePtr((TADDR)ppMT), pContainingModule, level);
+        RestoreMethodTablePointerRaw(ppMT->GetValuePtr(), pContainingModule, level);
     }
     else
     {
-        ClassLoader::EnsureLoaded(ppMT->GetValue((TADDR)ppMT), level);
+        ClassLoader::EnsureLoaded(ppMT->GetValue(), level);
     }
 }
 
@@ -10387,7 +10387,7 @@ PTR_Module Module::RestoreModulePointerIfLoaded(DPTR(RelativeFixupPointer<PTR_Mo
         return ppModule->GetValue(dac_cast<TADDR>(ppModule));
 
 #ifndef DACCESS_COMPILE 
-    PTR_Module * ppValue = ppModule->GetValuePtr(dac_cast<TADDR>(ppModule));
+    PTR_Module * ppValue = ppModule->GetValuePtr();
 
     // Ensure that the compiler won't fetch the value twice
     TADDR fixup = VolatileLoadWithoutBarrier((TADDR *)ppValue);
@@ -10440,7 +10440,7 @@ void Module::RestoreModulePointer(RelativeFixupPointer<PTR_Module> * ppModule, M
     if (!ppModule->IsTagged((TADDR)ppModule))
         return;
 
-    PTR_Module * ppValue = ppModule->GetValuePtr((TADDR)ppModule);
+    PTR_Module * ppValue = ppModule->GetValuePtr();
 
     // Ensure that the compiler won't fetch the value twice
     TADDR fixup = VolatileLoadWithoutBarrier((TADDR *)ppValue);
@@ -10594,7 +10594,7 @@ void Module::RestoreTypeHandlePointer(RelativeFixupPointer<TypeHandle> * pHandle
 
     if (pHandle->IsTagged((TADDR)pHandle))
     {
-        RestoreTypeHandlePointerRaw(pHandle->GetValuePtr((TADDR)pHandle), pContainingModule, level);
+        RestoreTypeHandlePointerRaw(pHandle->GetValuePtr(), pContainingModule, level);
     }
     else
     {
@@ -10696,7 +10696,7 @@ void Module::RestoreMethodDescPointer(RelativeFixupPointer<PTR_MethodDesc> * ppM
 
     if (ppMD->IsTagged((TADDR)ppMD))
     {
-        RestoreMethodDescPointerRaw(ppMD->GetValuePtr((TADDR)ppMD), pContainingModule, level);
+        RestoreMethodDescPointerRaw(ppMD->GetValuePtr(), pContainingModule, level);
     }
     else
     {
index 376b88c..23443ce 100644 (file)
@@ -318,7 +318,7 @@ MethodDesc* AsMethodDesc(size_t addr)
                 // extra indirection if the address is tagged (the low bit is set).
                 // That could AV if we don't check it first.
 
-                if (!ppMT->IsTagged((TADDR)ppMT) || isMemoryReadable((TADDR)ppMT->GetValuePtr((TADDR)ppMT), sizeof(MethodTable*)))
+                if (!ppMT->IsTagged((TADDR)ppMT) || isMemoryReadable((TADDR)ppMT->GetValuePtr(), sizeof(MethodTable*)))
                 {
                     if (AsMethodTable((size_t)RelativeFixupPointer<PTR_MethodTable>::GetValueAtPtr((TADDR)ppMT)) != 0)
                     {