diff options
author | Vladimir Sadov <vsadov@microsoft.com> | 2019-06-27 10:48:47 -0700 |
---|---|---|
committer | 이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com> | 2019-09-11 19:18:27 +0900 |
commit | 20c5704585f4f7bf4533f15165b2e8ca5cedafba (patch) | |
tree | 1d0ee0cb70c82a2e6a9c44429062489754a4ced5 /src | |
parent | f7e66a5a4f291b36c91d623013e4124cac13aac8 (diff) | |
download | coreclr-20c5704585f4f7bf4533f15165b2e8ca5cedafba.tar.gz coreclr-20c5704585f4f7bf4533f15165b2e8ca5cedafba.tar.bz2 coreclr-20c5704585f4f7bf4533f15165b2e8ca5cedafba.zip |
Fix SIGSEGV in GC when dealing with large double[] on ARM32 (#25403)
* Fix for #25252
* revert to special casing 8-alignement for double[] in GC helpers for x86
Diffstat (limited to 'src')
-rw-r--r-- | src/vm/gchelpers.cpp | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/vm/gchelpers.cpp b/src/vm/gchelpers.cpp index 07429a070a..0dcebd5e17 100644 --- a/src/vm/gchelpers.cpp +++ b/src/vm/gchelpers.cpp @@ -473,6 +473,11 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS } #endif + if (totalSize >= g_pConfig->GetGCLOHThreshold()) + { + bAllocateInLargeHeap = TRUE; + } + flags |= (pArrayMT->ContainsPointers() ? GC_ALLOC_CONTAINS_REF : GC_ALLOC_NO_FLAGS); ArrayBase* orArray = NULL; @@ -483,7 +488,22 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS } else { - if ((DATA_ALIGNMENT < sizeof(double)) && (elemType == ELEMENT_TYPE_R8)) +#ifdef FEATURE_64BIT_ALIGNMENT + MethodTable* pElementMT = pArrayMT->GetApproxArrayElementTypeHandle().GetMethodTable(); + if (pElementMT->RequiresAlign8() && pElementMT->IsValueType()) + { + // This platform requires that certain fields are 8-byte aligned (and the runtime doesn't provide + // this guarantee implicitly, e.g. on 32-bit platforms). Since it's the array payload, not the + // header that requires alignment we need to be careful. However it just so happens that all the + // cases we care about (single and multi-dim arrays of value types) have an even number of DWORDs + // in their headers so the alignment requirements for the header and the payload are the same. + _ASSERTE(((pArrayMT->GetBaseSize() - SIZEOF_OBJHEADER) & 7) == 0); + orArray = (ArrayBase*)AllocAlign8(totalSize, flags); + } + else +#else + if ((DATA_ALIGNMENT < sizeof(double)) && (elemType == ELEMENT_TYPE_R8) && + (totalSize < g_pConfig->GetGCLOHThreshold() - MIN_OBJECT_SIZE)) { // Creation of an array of doubles, not in the large object heap. // We want to align the doubles to 8 byte boundaries, but the GC gives us pointers aligned @@ -517,24 +537,10 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS orDummyObject->SetMethodTable(g_pObjectClass); } else +#endif // FEATURE_64BIT_ALIGNMENT + { -#ifdef FEATURE_64BIT_ALIGNMENT - MethodTable* pElementMT = pArrayMT->GetApproxArrayElementTypeHandle().GetMethodTable(); - if (pElementMT->RequiresAlign8() && pElementMT->IsValueType()) - { - // This platform requires that certain fields are 8-byte aligned (and the runtime doesn't provide - // this guarantee implicitly, e.g. on 32-bit platforms). Since it's the array payload, not the - // header that requires alignment we need to be careful. However it just so happens that all the - // cases we care about (single and multi-dim arrays of value types) have an even number of DWORDs - // in their headers so the alignment requirements for the header and the payload are the same. - _ASSERTE(((pArrayMT->GetBaseSize() - SIZEOF_OBJHEADER) & 7) == 0); - orArray = (ArrayBase*)AllocAlign8(totalSize, flags); - } - else -#endif - { - orArray = (ArrayBase*)Alloc(totalSize, flags); - } + orArray = (ArrayBase*)Alloc(totalSize, flags); } orArray->SetArrayMethodTable(pArrayMT); } @@ -544,8 +550,7 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS bool bProfilerNotifyLargeAllocation = false; - if (bAllocateInLargeHeap || - (totalSize >= g_pConfig->GetGCLOHThreshold())) + if (bAllocateInLargeHeap) { GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orArray); bProfilerNotifyLargeAllocation = TrackLargeAllocations(); @@ -739,6 +744,11 @@ OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, } #endif + if (totalSize >= g_pConfig->GetGCLOHThreshold()) + { + bAllocateInLargeHeap = TRUE; + } + flags |= (pArrayMT->ContainsPointers() ? GC_ALLOC_CONTAINS_REF : GC_ALLOC_NO_FLAGS); if (bAllocateInLargeHeap) @@ -773,8 +783,7 @@ OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, bool bProfilerNotifyLargeAllocation = false; - if (bAllocateInLargeHeap || - (totalSize >= g_pConfig->GetGCLOHThreshold())) + if (bAllocateInLargeHeap) { GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orArray); bProfilerNotifyLargeAllocation = TrackLargeAllocations(); |