精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從.Go文本文件到可執行文件

開發 前端
本文也只是蜻蜓點水般的過一遍,關于其中的一些細節我也并不太清楚,但是也讓我明白了一點道理:不管是多復雜多底層的系統,也都是通過分層來解耦、復用,并且也是不斷迭代優化來完成的。

Go 是一門編譯型語言,我們平時所編寫的 *.go 文本文件稱為源文件,源文件里面的內容就是我們的源代碼。

源代碼要想在目標機器上運行,就必須使用 Go compiler (縮寫 gc ,指代 Go 編譯器)將其先編譯成操作系統能夠直接識別的二進制機器碼文件,或說可執行文件。后續由操作系統加載該文件,并在 CPU 中直接運行機器碼。這也是編譯型語言運行效率高的主要原因。

Go compiler 是用什么實現的

編譯器本身也是一個程序,它的作用就是把一個以某種語言(源語言)編寫的程序 翻譯 成等價的另一個語言(目標語言)編寫的程序。

而編譯器這個程序本身的編寫與編程語言是沒有關系的,任何一種圖靈完備的語言都可以編寫任何一種形式語言的編譯器。

最開始的 Go compiler (Go 1.4 以及之前)是由 C 和匯編共同編寫的,等到 2015 年時 Google 開始公布實現 Go 1.5 自舉的計劃[1]。

首先使用 Go 語言編寫一個和之前用 C 語言編寫的 Go compiler 一樣功能的程序出來,再用之前用 C 語言實現好的 Go compiler 來編譯這個新寫的程序,這樣就得到一個用 Go 語言實現的 Go compiler 。后續的 Go 程序就都可以直接使用這個新的用 Go 語言實現的 Go compiler 來編譯了。

這種用源語言自身來實現源語言的編譯器的做法就叫自舉。所以在 Go 1.5 及之后的 Go compiler 就是用 Go 語言自身實現的了。

一個編譯器的結構

如果我們把編譯器這個黑盒稍微打開,根據完成的任務不同,可以將編譯器的組成部分劃分為前端(Front End)與后端(Back End)。

編譯前端負責分析(analysis)部分,把源程序分解為多個組成要素,并在這些要素之上加上語法結構,然后利用這個結構創建出源程序的中間表示形式,最后還將源程序的信息存放在一個稱為符號表的數據結構中并與中間表示形式一起傳送給綜合部分。

可見,如果我們編寫了一段語法錯誤的代碼,在前端就會被攔截下并給予提示了。這和我們 Web 開發中的參數校驗部分也有一點相似之處。

前端工作結束,則來到編譯后端,后端則負責綜合(synthesis)部分,根據前端傳送過來的中間表示和符號表中的信息來構造用戶期待的目標程序。

在編譯前端和后端之間,往往還存在著多個可選的、與機器無關的優化步驟,負責將中間表示形式進一步優化轉換,以便后續后端可以生成出更好的目標程序。

圖片

編譯器的結構

Go compiler 的多階段流程

以當前最新的穩定版本 Go 1.18.4 為例,Go compiler 的源碼位置在:https://github.com/golang/go/tree/go1.18.4/src/cmd/compile

后續的所有代碼示例和源碼引用也是基于此版本。

我們將編譯器的結構對應到 Go compiler 上,也可以將 Go compiler 的各階段流程劃分為編譯前端和編譯后端(優化器部分也放在了編譯后端)。

其中 Go compiler 的前端包括:詞法分析、語法分析、類型檢查。

后端包括:中間代碼生成、代碼優化、Walk 遍歷和替換、通用 SSA 生成、機器碼生成。

圖片

Go compiler 的多階段流程

詞法分析

編譯器的第一個步驟稱為詞法分析(lexical analysis)或掃描(scanning)。對應的源碼位置在 cmd/compile/internal/syntax/scanner.go 。其作用便是把我們的源代碼“翻譯”為詞法單元 token 。

token 在 go/token/token.go 中被定義為了一種枚舉值,實質就是用 iota 聲明的整數,好處便是在后續的操作中可以被更加高效地處理。

圖片

圖片

所有的 token 主要被分為四類:特殊類型、基礎類型、運算符和關鍵字。

若存在詞法錯誤,將統一返回 ILLEGAL ,簡化詞法分析時的錯誤處理。

其中以 _beg 和 _end 為后綴的私有常量,用來表示 token 的值域范圍。

最后所有的 token 都會被放進一個 var tokens = [...]string 數組中,做了一個下標(token 值)和 token 面值的映射。

圖片

值得一提的是,詞法分析除了在編譯器中使用,在 go 標準庫 go/scanner 中也提供了出來,我們可以用來測試看看一段源代碼翻譯成 token 后的樣子。

package main

import (
"fmt"
"go/scanner"
"go/token"
)

func main() {

// 需要翻譯的源程序
src := []byte(`package main

import "fmt"

func main() {
fmt.Println(1 + 1)
}
`)

// 初始化 scanner.
var s scanner.Scanner
fset := token.NewFileSet()
file := fset.AddFile("", fset.Base(), len(src))
s.Init(file, src, nil, scanner.ScanComments)

// 不斷地掃描并輸出翻譯成 token 的結果
fmt.Printf("%s\t%s\t%s\n", "行列", "token符號", "對應的原詞")
for {
pos, tok, lit := s.Scan()
if tok == token.EOF {
break
}
fmt.Printf("%s\t%s\t%q\n", fset.Position(pos), tok, lit)
}
}

翻譯成 token 后的輸出結果如下:

圖片

有個小細節的地方:當遇到 \n 換行符時,會翻譯成一個 ; 分號,這也是 Go 語言為什么不需要 ; 結尾。

語法分析

編譯器的第二個步驟稱為語法分析(syntax analysis)或解析(parsing)。語法分析將把第一步驟的 token 轉化成使用 AST 抽象語法樹(abstract syntax tree)來表示的程序語法結構。

語法分析的源碼位于 cmd/compile/internal/syntax/parser.go 。我們同樣可以借助標準庫 go/parser 來進行測試。

package main

import (
"go/ast"
"go/parser"
"go/token"
)

func main() {
// 需要翻譯的源程序
src := `package main

import "fmt"

func main() {
fmt.Println(1 + 1)
}
`

fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
panic(err)
}

err = ast.Print(fset, f)
if err != nil {
panic(err)
}
}

圖片

經過語法分析構建出來的每個語法樹都是相應源文件的精確表示,其節點對應于源文件的各種元素,例如表達式、聲明和語句。并且語法樹還會包括位置信息,用于錯誤報告和創建調試信息。

到目前階段為止,都還只是對源代碼進行字符串層面的處理。從源代碼到 token 再到 AST 。

類型檢查

在編譯原理中,完成 AST 的構建,就會來到語義分析(semantic analyzer)階段,主要包括類型檢查(type checking)和自動類型轉換(coercion)。

而在 Go compiler 中,這一階段被直接合稱為類型檢查,其源碼定義在 cmd/compile/internal/types2 。

在此階段,類型檢查會遍歷 AST 的節點,對每個節點的類型進行檢查,比如檢查每個運算符是否具有匹配的運算分量,數組的下標是否正整數等等。另外類型檢查階段也會進行類型推導,例如使用簡短變量聲明 i := 1 ,會自動推導出變量 i 的類型是 int。

總之,對類型系統的處理都是類型檢查階段完成的。

類型檢查的總體流程可以查看 cmd/compile/internal/types2/check.go :

圖片

中間代碼生成

一旦類型檢查階段完成,意味著編譯前端工作完成,到這里代碼已經沒有語法錯誤的問題了。按理是可以直接翻譯成機器碼了,但是在此之前,還需要先翻譯成介于源代碼和目標機器碼中間的中間代碼(IR, Intermediate Representation)。

使用中間代碼來銜接前、后端的好處很大。因為中間代碼不會包含與任何源代碼相關的信息,也不會包含與特定目標機器相關的信息,我們可以基于中間代碼來進行一些和機器無關的優化工作。

另外,有了中間代碼,后端編譯還可以得到復用,比如我現在想要創建一門新的語言,只需要編寫編譯器前端,構造出相同的中間代碼,編譯器后端就可以直接使用現成的了,不必重復構建。

其實這種做法就是平時我們程序設計常提到的解耦。

回到中間代碼生成本身,在這一階段中,會基于前面構造出的 AST 再生成一顆 IR Tree 。

因為我們是基于 Go 1.18.4 來分析,Go Team 在此已經增加了許多新的語言特性(包括泛型),以往的很多模塊也被重新重構,代碼結構更加清晰。但是難免還會關聯到之前一些舊版本的包(在之前 IR Tree 的生成與類型檢查是同時完成的)。

在 IR 生成階段,主要會涉及以下幾個目錄:

  • cmd/compile/internal/types
  • cmd/compile/internal/ir
  • cmd/compile/internal/typecheck
  • cmd/compile/internal/noder

IR 生成的入口位置在 cmd/compile/internal/noder/irgen.go :

圖片

func (g *irgen) generate(noders []*noder) 中的參數 noders 就是類型檢查的輸出結果 AST 。

到這里我們小結一下,編譯前端完成了 源代碼 -> token -> AST 的翻譯工作,而現在的中間代碼生成階段完成了 AST -> 基于 AST 的 IR Tree 的翻譯工作。所以為什么說編譯器的工作就是在翻譯。

代碼優化

終于來到了代碼優化,這個階段可謂是八股文的重災區。即使不懂編譯流程,也聽過了這些名詞:死代碼消除(dead code elimination)、函數內聯(function call inlining)、逃逸分析(escape analysis)。

以上這些便是對 IR 的進一步優化過程。其源碼位置分別在:

  • cmd/compile/internal/deadcode
  • cmd/compile/internal/inline
  • cmd/compile/internal/escape

代碼優化的目的就是讓代碼的執行效率更高,例如可能存在一些代碼,雖然具備語義上的價值,但程序在運行時可能永遠不會執行到,死代碼消除就會去除這些無用代碼(就像 if 里的條件為 true )。

如果程序中存在大量的小函數的調用,函數內聯就會直接用函數體替換掉函數調用來減少因為函數調用而造成的額外上下文切換開銷。

最后逃逸分析可以判斷變量應該使用棧內存還是堆內存,為 Go 的自動內存管理奠定基礎。

Walk 遍歷和替換

經歷過代碼優化的 IR ,將迎來它生命旅游的最后一站:Walk ,源碼在 cmd/compile/internal/walk。

Walk 會遍歷函數把復雜的語句分解為單獨的、更簡單的語句,并且還可能會引入臨時變量來對某些表達式和語句進行重新排序。還會將高層次的 Go 結構替換為更原始的結構。

例如, n += 2 將被替換為 n = n + 2 ;switch 選擇分支將替換為二分查找或跳轉表;map 和 chan 的 make 操作將替換為運行時調用的 makemap 和 makechan 等。

通用 SSA 生成

Walk 是基于 AST 的 IR 的最后一程,意味著來到這里,又要再次翻譯了。

而這次 IR 將被轉換為靜態單賦值(SSA)(Static Single Assignment)形式,這是一種具有特定屬性的較低級別的中間表示,可以更輕松地實現優化并最終生成機器代碼。

SSA 的規則定義在:cmd/compile/internal/ssa ,而 IR 轉換為 SSA 的代碼位于:cmd/compile/internal/ssagen 。

其翻譯的入口在 func Compile(fn *ir.Func, worker int) 函數。

圖片

我們可以通過在編譯過程加上 GOSSAFUNC=函數名 環境變量來查看 SSA 的生成過程。

還是以這段代碼為例:

package main

import "fmt"

func main() {
fmt.Println(1 + 1)
}
$ GOSSAFUNC=main go build hello.go
# runtime
dumped SSA to D:\Project\GoProject\awesome\ssa.html
# command-line-arguments
dumped SSA to .\ssa.html

根據提示,會生成 ssa.html 文件:

圖片

圖片

可以從中看到 SSA 為了盡最大可能地提升執行效率,會經歷 多輪轉換 后才生成最終的 SSA 。

機器碼生成

來到最后一步,也是從 .go 文本文件到可執行文件的最終謎團,把 SSA 翻譯成特定目標機器(目標 CPU 架構)的機器碼。

首先需要把 SSA 降級(lower),針對具體目標架構,進行 多輪轉換 來執行代碼優化,包括死代碼消除(和之前的代碼優化中的不同)、將數值移到離它們的用途更近的地方、刪除多余局部變量、寄存器分配等等。

這個降級操作最后的結果,其實就是我們上面的 ssa.html 文件最后的 genssa :

圖片

把 SSA 多輪轉換得到了 genssa 之后(此時已經很接近匯編了),會先繼續把 genssa 翻譯成匯編代碼(Plan9),然后才調用匯編器(cmd/internal/obj)將它們轉換為機器代碼并寫出最終的目標文件。目標文件中還會包含著反射數據、導出數據和調試信息。這一步就需要十分了解 CPU 指令集架構了。

最后程序如果使用了其他程序或庫,還需要使用靜態鏈接或動態鏈接引用進來。在沒有使用 CGO 時,Go 默認會使用靜態鏈接,當然也可以在 go build 時指定。

最后

編譯原理是一門十分復雜的系統,每一個階段單獨拎出來,其涉及的知識體系都夠嚇人的了。。。

本文也只是蜻蜓點水般的過一遍,關于其中的一些細節我也并不太清楚,但是也讓我明白了一點道理:不管是多復雜多底層的系統,也都是通過分層來解耦、復用,并且也是不斷迭代優化來完成的。

另外,知道了 Go 語言編譯過程中的代碼優化,也能讓我們在平時的代碼編寫中結合對應的特性編寫出更加高性能的代碼,例如盡量在棧上分配對象,減少變量逃逸到堆上也可以提高 GC 效率等。這些后面再單獨寫篇文章來介紹。

本文部分內容參考自經典龍書《編譯原理》以及《Golang 編譯器代碼淺析》[2] ,如果想要了解更多編譯領域的知識,推薦大家進行閱讀。

對于最后機器碼生成中提到的 Plan9 匯編可以閱讀曹大的《plan9 assembly 完全解析》[3]。

本文轉載自微信公眾號「gopher云原生」,可以通過以下二維碼關注。轉載本文請聯系gopher云原生公眾號。


責任編輯:武曉燕 來源: gopher云原生
相關推薦

2009-10-28 13:03:54

2024-05-06 00:00:00

Go文件瘦身代碼

2015-02-02 11:03:12

2012-01-05 10:37:40

Java

2010-02-22 18:04:27

CentOS mpla

2021-01-06 05:29:57

虛擬內存文件

2017-02-07 10:22:53

2021-01-12 10:10:41

shell腳本Linux命令

2021-01-08 08:06:19

腳本Shell文件

2011-08-09 10:24:19

可執行文件病毒病毒

2022-05-11 14:50:34

Python解包執行文件

2009-06-20 09:21:37

UNIXLINUX

2021-11-29 09:46:11

FileReaderJava開發

2024-08-12 16:42:50

二進制工具系統

2022-05-20 08:55:02

py文件exepython

2010-04-30 17:38:31

Unix文本

2022-09-29 10:01:05

Go編程語言文本文件

2024-05-21 12:01:39

.NET 6開發

2009-04-16 10:37:17

Javaexejar

2023-09-04 07:14:36

點贊
收藏

51CTO技術棧公眾號

中文字幕精品网| 欧美主播一区二区三区| 国产精品视频500部| 美女又爽又黄免费视频| 成人动漫免费在线观看| 日韩欧美国产一区在线观看| 浮妇高潮喷白浆视频| av在线女优影院| 成人性视频网站| 国产精品吹潮在线观看| 久草视频在线资源| 欧美综合另类| 日韩久久免费av| 韩国日本美国免费毛片| 日韩123区| 国产精品免费看片| 狠狠色噜噜狠狠色综合久| 久久国产香蕉视频| 一区二区日韩免费看| 久久九九有精品国产23| 亚洲国产欧美视频| 免费精品一区二区三区在线观看| 色综合网色综合| 少妇大叫太大太粗太爽了a片小说| 黄上黄在线观看| 成人久久视频在线观看| 91精品国产综合久久香蕉922| 西西44rtwww国产精品| 色综合久久一区二区三区| 亚洲激情在线观看视频免费| 亚洲一区二区三区三州| 亚洲四虎影院| 欧美性猛交xxxx免费看久久久| 成人av在线播放观看| 色网站免费在线观看| 久久久精品蜜桃| 精品高清视频| 风流老熟女一区二区三区| 久久国内精品自在自线400部| 欧洲美女7788成人免费视频| 国产无套粉嫩白浆内谢| 88国产精品视频一区二区三区| 国产午夜精品全部视频播放| 黄色工厂在线观看| 国产精品xxx在线观看| 欧美一卡在线观看| 992kp免费看片| 九九热这里有精品| 欧美日韩视频一区二区| 国产激情在线观看视频| 成人片免费看| 色综合久久久久综合| 国内自拍在线观看| 麻豆mv在线看| 欧美性极品xxxx做受| 波多野结衣综合网| 久久久男人天堂| 精品久久久久久久久国产字幕| 僵尸世界大战2 在线播放| 男男gaygays亚洲| 亚洲国产欧美在线| 亚洲中文字幕无码av永久| av小说在线播放| 天天综合色天天| 69堂免费视频| 亚洲伦理影院| 欧美系列亚洲系列| 女人高潮一级片| 国产麻豆精品| 日韩欧美一二三四区| 午夜福利三级理论电影| 国偷自产av一区二区三区| 亚洲精品国精品久久99热一| 色噜噜日韩精品欧美一区二区| 精品久久久亚洲| 久久精品国产一区二区电影| 欧美性猛交xxxxx少妇| 国产精品啊啊啊| 91国产精品91| 亚洲免费视频二区| 国产精品一区二区不卡| 国产v亚洲v天堂无码| 四虎在线免费观看| 欧美高清在线一区| 老司机av福利| а√天堂中文资源在线bt| 色婷婷av一区二区三区软件| 超碰人人草人人| 成人动漫视频| 亚洲欧美国产制服动漫| 色偷偷www8888| 亚洲香蕉网站| 国产精品福利无圣光在线一区| 国产美女精品视频国产| 成人免费毛片app| 日本一区免费看| 成人片在线看| 色综合天天做天天爱| 中文国产在线观看| 林ゆな中文字幕一区二区| 色婷婷av一区二区三区在线观看| 欧美日韩大片在线观看| 日韩精品一二区| 波多野结衣一区二区三区在线观看| 日韩精品视频在线观看一区二区三区| 国产精品久久久久桃色tv| 青草视频在线观看视频| 欧美色片在线观看| 亚洲精品在线网站| 成年人免费视频播放| 免费在线日韩av| 999国产视频| 成a人片在线观看www视频| 亚洲五码中文字幕| 中文字幕精品一区二区三区在线| 偷拍亚洲精品| 欧美丰满片xxx777| 亚洲一级av毛片| 久久久精品中文字幕麻豆发布| 国产精品视频网站在线观看| 国产精品99精品一区二区三区∴| 日韩精品视频在线| 九九热只有精品| 国产主播一区二区三区| 色播亚洲婷婷| 成人免费网站视频| 亚洲精品国产福利| 久久久综合久久| 国产一区二区三区精品视频| 色之综合天天综合色天天棕色| 日韩理论视频| 亚洲精品在线免费播放| 黄色一级片中国| 美女视频网站久久| 日本一区网站| 影视一区二区三区| 亚洲欧美另类自拍| xxxx.国产| 91女厕偷拍女厕偷拍高清| 国产91沈先生在线播放| 在线精品视频一区| 久久久999精品| 国产一区二区网站| 国产精品视频第一区| 色哟哟精品视频| 国产欧美一区| 国产精品高清网站| yourporn在线观看中文站| 欧美性猛交xxxx免费看| 中文字幕国产综合| 日韩av电影免费观看高清完整版| 日韩av电影免费播放| 姬川优奈av一区二区在线电影| 国产一区二区三区在线| 久久久久久亚洲av无码专区| 国产欧美日韩在线| 亚洲第一狼人区| 久久美女视频| 91在线视频一区| 神马午夜伦理不卡 | 久久久久国产精品熟女影院| 九色精品91| 国产精品久久精品| 欧美极品另类| 日韩欧美亚洲国产精品字幕久久久 | 波多野结衣一区二区在线| 久久久久久久性| 亚洲36d大奶网| 天天久久综合| 高清国产在线一区| 高清在线视频不卡| 亚洲人成电影网站色www| 国产主播第一页| 亚洲欧洲av另类| av在线天堂网| 亚洲免费影视| 亚洲午夜久久久影院伊人| 国产精品毛片aⅴ一区二区三区| 欧美成人免费小视频| 无码国产精品高潮久久99| 色婷婷综合五月| 日本一级片免费| www.亚洲色图.com| 日日噜噜噜噜久久久精品毛片| 在线免费观看日本欧美爱情大片| 国产三区精品| 嫩草伊人久久精品少妇av杨幂| 久久久国产一区| 五月色婷婷综合| 欧美日韩卡一卡二| 久久久久久久福利| 久久久www免费人成精品| 午夜av中文字幕| 亚洲一区免费| 99re99热| 亚洲电影一级片| 91视频网页| 东京一区二区| 欧美日韩第一视频| 黑人与亚洲人色ⅹvideos| 日韩欧美国产麻豆| 精品免费囯产一区二区三区| 亚洲精品免费在线| 国产 欧美 在线| 丁香六月综合激情| 亚洲高清免费在线观看| 日韩天堂av| 日韩欧美一级在线| 青青草91久久久久久久久| 国产欧美在线一区二区| 日日夜夜一区| 国产suv精品一区二区三区88区| 五月婷婷视频在线观看| 中文字幕欧美日韩va免费视频| 少妇精品视频一区二区 | 一级黄色片国产| 久久久国产亚洲精品| www.国产在线视频| 亚洲精品91| 日日噜噜噜噜夜夜爽亚洲精品| 成人激情自拍| 亚洲最大的网站| 亚洲高清国产拍精品26u| 日韩**中文字幕毛片| zzzwww在线看片免费| 欧美激情18p| 很黄的网站在线观看| 在线播放国产一区二区三区| 手机看片1024国产| 精品少妇一区二区三区日产乱码| 一级黄色片网站| 欧美无乱码久久久免费午夜一区| xxxx.国产| 欧美日韩国产丝袜另类| 国产真人真事毛片| 亚洲一区二区五区| 亚洲综合网在线| 亚洲精品伦理在线| 黑人巨大精品一区二区在线| 中文字幕亚洲不卡| 久久嫩草捆绑紧缚| 国产精品久久久久久福利一牛影视| 天堂久久精品忘忧草| 国产女人18毛片水真多成人如厕 | 国产精品丝袜一区二区三区| 97久久香蕉国产线看观看| 青草成人免费视频| 波多野结衣亚洲| 国产精品福利小视频| 成人黄色毛片| 成人av在线天堂| 中文成人在线| 91嫩草在线| 国内自拍欧美| 欧美日韩在线观看一区二区三区 | 成人黄色777网| 91性高潮久久久久久久| 国产成人一级电影| 精品人妻伦一二三区久| 91网站视频在线观看| 一级黄色片大全| 国产精品污网站| 性欧美疯狂猛交69hd| 亚洲色图一区二区三区| 欧美国产在线看| 亚洲va韩国va欧美va精品| 国偷自拍第113页| 欧美影视一区二区三区| 97成人在线观看| 精品国产乱码久久久久久浪潮| 色偷偷在线观看| 亚洲一品av免费观看| 国产精品扒开做爽爽爽的视频| 免费99精品国产自在在线| 超级白嫩亚洲国产第一| 国产精品电影久久久久电影网| 亚洲一区二区三区久久久| 岛国视频一区| 国产一区网站| 日韩精品第1页| 中文在线不卡| 亚洲这里只有精品| 成人免费视频视频| 国产最新精品视频| 一卡二卡三卡四卡| 欧美激情综合五月色丁香小说| 大地资源高清在线视频观看| 一区二区国产视频| 日韩在线 中文字幕| 制服丝袜av成人在线看| 手机av在线免费观看| 日韩在线一区二区三区免费视频| 三级网站视频在在线播放| 日本久久久久久久久| 成人激情久久| 欧美精品久久久| 亚洲蜜桃视频| 黄色一级免费大片| 国产激情91久久精品导航| 国产一二三四五区| 亚洲在线视频网站| 中文字幕777| 亚洲精品720p| a级网站在线播放| 国产盗摄xxxx视频xxx69| 欧州一区二区三区| 五月天婷亚洲天综合网鲁鲁鲁| 韩国亚洲精品| 午夜免费福利视频在线观看| 2021久久国产精品不只是精品 | 亚洲精品成人a在线观看| 六月丁香在线视频| 日韩一级免费观看| av小片在线| 日本一本a高清免费不卡| 亚洲精品影片| 亚洲一区二区三区加勒比 | 男同在线观看| 久久久久久久久久久免费| 九七电影院97理论片久久tvb| 蜜桃成人在线| 欧美欧美天天天天操| 可以看污的网站| 日本一区二区三区在线观看| 毛片毛片女人毛片毛片| 欧美v日韩v国产v| 超碰免费在线播放| 91精品久久久久久久久| 欧美一区2区| 午夜免费一区二区| 久久久高清一区二区三区| 国产精品21p| 日韩成人激情视频| av小说在线播放| 国产自产在线视频一区| 国产综合精品一区| 亚洲精品一二三四| 亚洲免费av网站| 国产视频第二页| 久久高清视频免费| 亚洲精品v亚洲精品v日韩精品| 可以在线看黄的网站| 国内成人免费视频| 日本黄色录像视频| 欧美一区二区三区影视| 国产一二区在线| 亚洲xxxxx电影| 欧美成人久久| 中文字幕乱妇无码av在线| 一区二区三区视频在线观看| 国产av无码专区亚洲av麻豆| 欧美成人免费在线观看| 亚洲国产精品免费视频| 奇米777四色影视在线看| 岛国精品在线观看| 日韩熟女精品一区二区三区| 日韩毛片在线看| 日韩不卡在线| 中文字幕剧情在线观看一区| 国产精品中文欧美| 精品深夜av无码一区二区老年| 亚洲国产精品va在线看黑人 | www.超碰97| 欧美色图在线视频| youjizz在线播放| 亚洲free性xxxx护士hd| 在线高清一区| 性欧美丰满熟妇xxxx性仙踪林| 91久久精品一区二区三| 视频免费一区| 国产精品jizz视频| 日韩中文欧美在线| 亚洲精品国产精品国自产网站| 欧美久久久久久蜜桃| 性欧美videos高清hd4k| 国产在线欧美日韩| 美女在线观看视频一区二区| 青花影视在线观看免费高清| 亚洲第一精品福利| 综合在线影院| 中文字幕在线乱| av在线播放不卡| 中文字幕人成人乱码亚洲电影| 色综合久久天天综线观看| 伊人成综合网yiren22| 国产一伦一伦一伦| 亚洲国产一区二区视频| 国产露出视频在线观看| 亚洲www在线| 久久久久久久欧美精品| 成人在线观看免费完整| 亚洲精品国产suv| 国产情侣一区在线| 无码人妻丰满熟妇区96| 中文字幕永久在线不卡| 婷婷视频在线观看| 成人日韩在线电影| 亚洲在线日韩| 欧美国产日韩在线观看成人| 亚洲精品日韩欧美|