class_createInstance函数源码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了class_createInstance函数源码相关的知识,希望对你有一定的参考价值。

参考技术A

/***********************************************************************


id
class_createInstance(Class cls, size_t extraBytes)

return _class_createInstanceFromZone(cls, extraBytes, nil);

/***********************************************************************

unsigned
class_createInstances(Class cls, size_t extraBytes,
id *results, unsigned num_requested)

return _class_createInstancesFromZone(cls, extraBytes, nil,
results, num_requested);

static BOOL classOrSuperClassesUseARR(Class cls)
while (cls)
if (_class_usesAutomaticRetainRelease(cls)) return true;
cls = cls->superclass;

return false;

static void arr_fixup_copied_references(id newObject, id oldObject)

// use ARR layouts to correctly copy the references from old object to new, both strong and weak.
Class cls = oldObject->ISA();
for ( ; cls; cls = cls->superclass)
if (_class_usesAutomaticRetainRelease(cls))
// FIXME: align the instance start to nearest id boundary. This currently handles the case where
// the the compiler folds a leading BOOL (char, short, etc.) into the alignment slop of a superclass.
size_t instanceStart = _class_getInstanceStart(cls);
const uint8_t *strongLayout = class_getIvarLayout(cls);
if (strongLayout)
id *newPtr = (id )((char )newObject + instanceStart);
unsigned char byte;
while ((byte = *strongLayout++))
unsigned skips = (byte >> 4);
unsigned scans = (byte & 0x0F);
newPtr += skips;
while (scans--)
// ensure strong references are properly retained.
id value = *newPtr++;
if (value) objc_retain(value);



const uint8_t *weakLayout = class_getWeakIvarLayout(cls);
// fix up weak references if any.
if (weakLayout)
id *newPtr = (id )((char )newObject + instanceStart), *oldPtr = (id )((char )oldObject + instanceStart);
unsigned char byte;
while ((byte = *weakLayout++))
unsigned skips = (byte >> 4);
unsigned weaks = (byte & 0x0F);
newPtr += skips, oldPtr += skips;
while (weaks--)
*newPtr = nil;
objc_storeWeak(newPtr, objc_loadWeak(oldPtr));
++newPtr, ++oldPtr;





Linux 内核 内存管理munmap 系统调用源码分析 ② ( do_munmap 函数执行流程 | do_munmap 函数源码 )

文章目录


munmap 系统调用函数 调用了 vm_munmap 函数 , 在 vm_munmap 函数 中 , 又调用了 do_munmap 函数 , do_munmap 函数 是 删除 内存映射 的 核心函数 ;





一、do_munmap 函数执行流程



do_munmap 函数执行流程 :

根据 unsigned long start 参数的起始地址 , 找到要删除的 第一个 虚拟内存区域 vm_area_struct 结构体实例 ,

int do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
	      struct list_head *uf)
	...
	struct vm_area_struct *vma, *prev, *last;
	...
	/* Find the first overlapping VMA */
	vma = find_vma(mm, start);
	if (!vma)
		return 0;
	...

如果不是删除整个 vam 内存区域 , 而只是删除部分内存 , 那么需要分裂 vm_area_struct *vma 指向的内存区域 ;

		error = __split_vma(mm, vma, start, 0);

根据 end 结束地址 , 找到 需要删除的 虚拟内存区域 的 最后一个 vm_area_struct *last 实例 ;

	/* Does it split the last one? */
	last = find_vma(mm, end);

如果不是删除整个 vam 内存区域 , 而只是删除部分内存 , 那么需要分裂 vm_area_struct *last 指向的内存区域 ;

	if (last && end > last->vm_start) 
		int error = __split_vma(mm, last, end, 1);
		if (error)
			return error;
	

如果 被删除的 内存区域 被锁定在 内存中 , 即 不允许换出到交换区 , 则调用 munlock_vma_pages_all 函数 解除 内存锁定 ;

	/*
	 * unlock any mlock()ed ranges before detaching vmas
	 */
	if (mm->locked_vm) 
		struct vm_area_struct *tmp = vma;
		while (tmp && tmp->vm_start < end) 
			if (tmp->vm_flags & VM_LOCKED) 
				mm->locked_vm -= vma_pages(tmp);
				munlock_vma_pages_all(tmp);
			
			tmp = tmp->vm_next;
		
	

调用 detach_vmas_to_be_unmapped 函数 , 将要删除的 " 虚拟内存区域 " 从 进程的 虚拟内存区域 链表 和 红黑树 数据结构中删除 ,

这些内存区域 单独放在一个临时链表中 ;

	/*
	 * Remove the vma's, and unmap the actual pages
	 */
	detach_vmas_to_be_unmapped(mm, vma, prev, end);

调用 unmap_region 函数 , 将 进程 的 页表中 的 " 被删除内存区域 对应的 映射 " 删除 , 从 处理器 页表缓存 中 也 删除对应 映射 ;

	unmap_region(mm, vma, prev, start, end);

调用 arch_unmap 函数 , 执行 该处理器架构 对应的 删除内存映射 的 处理操作 ;

	arch_unmap(mm, vma, start, end);

调用 remove_vma_list 函数 , 删除所有的虚拟内存区域 ;

	/* Fix up all other VM information */
	remove_vma_list(mm, vma);




二、do_munmap 函数源码



do_munmap 函数 , 定义在 Linux 内核源码 linux-4.12\\mm\\mmap.c#2620 位置 ;


do_munmap 函数源码如下 :

/* Munmap is split into 2 main parts -- this part which finds
 * what needs doing, and the areas themselves, which do the
 * work.  This now handles partial unmappings.
 * Jeremy Fitzhardinge <jeremy@goop.org>
 */
int do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
	      struct list_head *uf)

	unsigned long end;
	struct vm_area_struct *vma, *prev, *last;

	if ((offset_in_page(start)) || start > TASK_SIZE || len > TASK_SIZE-start)
		return -EINVAL;

	len = PAGE_ALIGN(len);
	if (len == 0)
		return -EINVAL;

	/* Find the first overlapping VMA */
	vma = find_vma(mm, start);
	if (!vma)
		return 0;
	prev = vma->vm_prev;
	/* we have  start < vma->vm_end  */

	/* if it doesn't overlap, we have nothing.. */
	end = start + len;
	if (vma->vm_start >= end)
		return 0;

	if (uf) 
		int error = userfaultfd_unmap_prep(vma, start, end, uf);

		if (error)
			return error;
	

源码路径 : linux-4.12\\mm\\mmap.c#2620

以上是关于class_createInstance函数源码的主要内容,如果未能解决你的问题,请参考以下文章

suricata源码笔记:main函数

源码分析:静态分析 C 程序函数调用关系图

C语言源码剖析与实现——strtok()系列函数实现

6C_宏定义与预处理函数与函数库

PHP源码PHP 函数调用

C语言实现三子棋(详解附源码)