HTML5技术

CoreCLR源码探索(二) new是什么 - q303248153(5)

字号+ 作者:H5之家 来源:H5之家 2017-01-12 09:04 我要评论( )

OBJECTREF FastAllocatePrimitiveArray(MethodTable* pMT, DWORD cElements, BOOL bAllocateInLargeHeap){ // 省略部分代码...... // 检查元素数量不能大于一个硬性限制 SIZE_T componentSize = pMT-GetComponentSi

OBJECTREF FastAllocatePrimitiveArray(MethodTable* pMT, DWORD cElements, BOOL bAllocateInLargeHeap) { // 省略部分代码...... // 检查元素数量不能大于一个硬性限制 SIZE_T componentSize = pMT->GetComponentSize(); if (cElements > MaxArrayLength(componentSize)) ThrowOutOfMemory(); // 检查总大小不能溢出 S_SIZE_T safeTotalSize = S_SIZE_T(cElements) * S_SIZE_T(componentSize) + S_SIZE_T(pMT->GetBaseSize()); if (safeTotalSize.IsOverflow()) ThrowOutOfMemory(); size_t totalSize = safeTotalSize.Value(); // 省略部分代码...... // 调用gc的帮助函数分配内存 ArrayBase* orObject; if (bAllocateInLargeHeap) { orObject = (ArrayBase*) AllocLHeap(totalSize, FALSE, FALSE); } else { ArrayTypeDesc *pArrayR8TypeDesc = g_pPredefinedArrayTypes[ELEMENT_TYPE_R8]; if (DATA_ALIGNMENT < sizeof(double) && pArrayR8TypeDesc != NULL && pMT == pArrayR8TypeDesc->GetMethodTable() && totalSize < LARGE_OBJECT_SIZE - MIN_OBJECT_SIZE) { _ASSERTE(DATA_ALIGNMENT == sizeof(double)/2); _ASSERTE((MIN_OBJECT_SIZE % sizeof(double)) == DATA_ALIGNMENT); // used to change alignment _ASSERTE(pMT->GetComponentSize() == sizeof(double)); _ASSERTE(g_pObjectClass->GetBaseSize() == MIN_OBJECT_SIZE); _ASSERTE(totalSize < totalSize + MIN_OBJECT_SIZE); orObject = (ArrayBase*) Alloc(totalSize + MIN_OBJECT_SIZE, FALSE, FALSE); Object *orDummyObject; if((size_t)orObject % sizeof(double)) { orDummyObject = orObject; orObject = (ArrayBase*) ((size_t)orObject + MIN_OBJECT_SIZE); } else { orDummyObject = (Object*) ((size_t)orObject + totalSize); } _ASSERTE(((size_t)orObject % sizeof(double)) == 0); orDummyObject->SetMethodTable(g_pObjectClass); } else { orObject = (ArrayBase*) Alloc(totalSize, FALSE, FALSE); bPublish = (totalSize >= LARGE_OBJECT_SIZE); } } // 设置类型信息(MethodTable) // Initialize Object orObject->SetMethodTable( pMT ); _ASSERTE(orObject->GetMethodTable() != NULL); // 设置数组长度 orObject->m_NumComponents = cElements; // 省略部分代码...... return( ObjectToOBJECTREF((Object*)orObject) ); }

再看AllocateArrayEx函数,这个函数比起上面的函数多出了对多维数组的处理
JIT_NewArr1调用AllocateArrayEx时传了3个参数,剩下2个参数是可选参数
源代码:

OBJECTREF AllocateArrayEx(TypeHandle arrayType, INT32 *pArgs, DWORD dwNumArgs, BOOL bAllocateInLargeHeap DEBUG_ARG(BOOL bDontSetAppDomain)) { // 省略部分代码...... ArrayBase * orArray = NULL; (bAllocateInLargeHeap) { orArray = (ArrayBase *) AllocLHeap(totalSize, FALSE, pArrayMT->ContainsPointers()); // 设置类型信息(MethodTable) orArray->SetMethodTableForLargeObject(pArrayMT); } else { #ifdef FEATURE_64BIT_ALIGNMENT MethodTable *pElementMT = arrayDesc->GetTypeParam().GetMethodTable(); if (pElementMT->RequiresAlign8() && pElementMT->IsValueType()) { _ASSERTE(((pArrayMT->GetBaseSize() - SIZEOF_OBJHEADER) & 7) == 0); orArray = (ArrayBase *) AllocAlign8(totalSize, FALSE, pArrayMT->ContainsPointers(), FALSE); } else #endif { orArray = (ArrayBase *) Alloc(totalSize, FALSE, pArrayMT->ContainsPointers()); } // 设置类型信息(MethodTable) orArray->SetMethodTable(pArrayMT); } // 设置数组长度 // Initialize Object orArray->m_NumComponents = cElements; // 省略部分代码...... return ObjectToOBJECTREF((Object *) orArray); }

总结:
第二种new做的事情主要有

  • 调用JIT_NewArr1
  • 第三种new(对struct的new)做了什么

    对struct的new不会从GCHeap申请内存,也不会设置类型信息(MethodTable),所以可以直接进入总结

    总结:
    第三种new做的事情主要有

  • 在进入函数时统一从栈(Stack)分配内存
  • 分配的内存不会包含同步块索引(SyncBlock)和类型信息(MethodTable)
  • 调用构造函数
  • 验证第一种new(对class的new)

    打开VS反汇编和内存窗口,让我们来看看第一种new实际做了什么事情

    第一种new的反汇编结果如下,一共有两个call

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • CoreCLR源码探索(一) Object是什么 - q303248153

      CoreCLR源码探索(一) Object是什么 - q303248153

      2017-01-06 11:04

    • 升讯威ADO.NET增强组件(源码):送给喜欢原生ADO.NET的你 - sheng.chao

      升讯威ADO.NET增强组件(源码):送给喜欢原生ADO.NET的你 - sheng.c

      2016-12-20 11:01

    • html5 Sortable.js 拖拽排序源码分析 - qq281113270

      html5 Sortable.js 拖拽排序源码分析 - qq281113270

      2016-11-04 15:00

    • MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则) - 懒得安分

      MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)

      2016-11-03 18:00

    网友点评
    a