四. go 内存管理之 编译原理

Go编译器首先进行词法语法分析,构建AST,然后进行类型检查。接着,应用静态单赋值(SSA)优化生成中间代码,进一步提升效率。最后,通过指令集转换为机器码,Go的链接器使其能在多种平台上运行。整个过程主要在`src/cmd/compile/internal/gc/main.go`中进行。
摘要由CSDN通过智能技术生成

一. 编译过程概述

抽象语法树

  1. 在编译一个go项目时,编译器首先读取到go文件,进行词法分析,根据变量,类型,运算符,流程语句,函数等关键字,每一个go文件都会被抽象成一棵多叉的抽象语法树, 最终将抽象后的信息封装到go/ast/ast.go文件中的一个File结构体中,所以又叫抽象ast树
type File struct {
	Doc        *CommentGroup   //保存了通过DOC生成的注释信息,associated documentation; or nil
	Package    token.Pos       // position of "package" keyword
	Name       *Ident          // 保存了包名称 package name
	Decls      []Decl          // 顶层代码块 top-level declarations; or nil
	Scope      *Scope          // 包的作用域(会保存当前编译的go文件中所有包作用域的变量) package scope (this file only)
	Imports    []*ImportSpec   // 导入语句 imports in this file
	Unresolved []*Ident        // unresolved identifiers in this file
	Comments   []*CommentGroup // 注释信息 list of all comments in the source file
}

静态单赋值SSA 生成中间代码

  1. 什么是静态单赋值SSA: 一种优化规则,要求
  1. 每个变量在使用前都需要被定义
  2. 每个变量被精确地赋值一次(使得一个变量的值与它在程序中的位置无关)
  1. 简单来说到这一步骤就是按照SSA要求: 变量在整个生命周期内仅被赋值一次的,对代码进行优化,如下,因为具有SSA特性的中间代码,会为编译器提供更多的优化空间
//源代码
y = 1
y = 2
x = y

//优化后(这样在优化的好处: 在后续优化时就可以忽略掉第一步骤y1的赋值,并且不影响最终结果)
y1 = 1
y2 = 2
x1 = y2

指令集

  1. 此时已经拿生成了中间代码,要通过汇编将中间代码翻译成机器码,这个过程中需要用的指令集,

二. Go 编译器执行主流程

  1. 首先编译时分为前端编辑,后端编译两部分
  2. 前端编译器执行,又分为两部分
  1. 词法语法分析, 例如去除重空格,无效符号等等
  2. 类型检查然后转换为AST语法树,在这个过程中会对语法糖进行翻译,例如将make转换为指定标准包中的函数
  1. 前端编译器执行总结一句话就是: 读取到go文件,进行词法语法分析,类型检查等将go文件转换成AST,也就是将每一个go文件都会被抽象成一棵多叉的抽象语法树, 最终将抽象后的信息封装到go/ast/ast.go文件中的一个File结构体中,所以又叫抽象ast树
type File struct {
	Doc        *CommentGroup   //保存了通过DOC生成的注释信息,associated documentation; or nil
	Package    token.Pos       // position of "package" keyword
	Name       *Ident          // 保存了包名称 package name
	Decls      []Decl          // 顶层代码块 top-level declarations; or nil
	Scope      *Scope          // 包的作用域(会保存当前编译的go文件中所有包作用域的变量) package scope (this file only)
	Imports    []*ImportSpec   // 导入语句 imports in this file
	Unresolved []*Ident        // unresolved identifiers in this file
	Comments   []*CommentGroup // 注释信息 list of all comments in the source file
}
  1. 然后后端编译器执行,也分为连个步骤:
  1. 进行SSA优化,生产中间代码
  2. 连接不同指令集,生成对应当前平台的机器码
  1. Go语言的代码可以直接输出为二进制可执行文件。而且Go语言拥有自己的链接器,连接不同指令集,不依赖任何系统提供的编译器和链接器。因此编译出的二进制可执行文件几乎可以运行在任何系统环境中
  2. 源码包,其中"src/cmd/compile/internal/gc/main.go"是编译器的入口,编译go项目的整个过程都是通过这个main.go文件发起的
  3. 参考博客
  1. B站搜索"golang 源码分析 - 编译原理必知必会"
  2. 添加链接描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值