From: Gleb Balykov Date: Thu, 22 Jun 2017 16:28:32 +0000 (+0300) Subject: Additional fixes for RelativePointer, FixupPointer, RelativeFixupPointer, PlainPointer X-Git-Tag: submit/tizen/20210909.063632~11030^2~6513^2~386^2~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=46d1b48ce4dfb293aa70da119eb61adf502c9d5f;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Additional fixes for RelativePointer, FixupPointer, RelativeFixupPointer, PlainPointer Commit migrated from https://github.com/dotnet/coreclr/commit/e8adb62978b887eda3617dff7eccec1fc7719d07 --- diff --git a/src/coreclr/src/inc/fixuppointer.h b/src/coreclr/src/inc/fixuppointer.h index 20eb9d8..a711418 100644 --- a/src/coreclr/src/inc/fixuppointer.h +++ b/src/coreclr/src/inc/fixuppointer.h @@ -214,15 +214,38 @@ public: return dac_cast(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(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)>(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)>(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(addr); } + void SetValueMaybeNull(PTR_TYPE addr) + { + LIMITED_METHOD_CONTRACT; + SetValue(addr); + } +#endif // !DACCESS_COMPILE + private: TADDR m_addr; }; @@ -270,9 +301,6 @@ public: RelativeFixupPointer& operator = (const RelativeFixupPointer &) =delete; RelativeFixupPointer& operator = (RelativeFixupPointer &&) =delete; - // Default constructor - RelativeFixupPointer() {} - // 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(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 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(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)>(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) { diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index 857c67e..ff8c17e 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -10248,11 +10248,11 @@ void Module::RestoreMethodTablePointer(RelativeFixupPointer * 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(RelativeFixupPointerGetValue(dac_cast(ppModule)); #ifndef DACCESS_COMPILE - PTR_Module * ppValue = ppModule->GetValuePtr(dac_cast(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 * 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 * 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 * ppM if (ppMD->IsTagged((TADDR)ppMD)) { - RestoreMethodDescPointerRaw(ppMD->GetValuePtr((TADDR)ppMD), pContainingModule, level); + RestoreMethodDescPointerRaw(ppMD->GetValuePtr(), pContainingModule, level); } else { diff --git a/src/coreclr/src/vm/debughelp.cpp b/src/coreclr/src/vm/debughelp.cpp index 376b88c..23443ce 100644 --- a/src/coreclr/src/vm/debughelp.cpp +++ b/src/coreclr/src/vm/debughelp.cpp @@ -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::GetValueAtPtr((TADDR)ppMT)) != 0) {