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

圖解 V8 執行 JS 的過程

開發 前端
本文來分享 V8 引擎執行 JavaScript 的過程和垃圾回收機制。在說V8的執行JavaScript代碼的機制之前,我們先來看看編譯型和解釋型語言的區別。

本文來分享 V8 引擎執行 JavaScript 的過程和垃圾回收機制。

1、JS 代碼執行過程

在說V8的執行JavaScript代碼的機制之前,我們先來看看編譯型和解釋型語言的區別。

(1)編譯型語言和解釋型語言

我們知道,機器是不能直接理解代碼的。所以,在執行程序之前,需要將代碼翻譯成機器能讀懂的機器語言。按語言的執行流程,可以把計算機語言劃分為編譯型語言和解釋型語言:

  • 編譯型語言:在代碼運行前編譯器直接將對應的代碼轉換成機器碼,運行時不需要再重新翻譯,直接可以使用編譯后的結果。
  • 解釋型語言:需要將代碼轉換成機器碼,和編譯型語言的區別在于運行時需要轉換。解釋型語言的執行速度要慢于編譯型語言,因為解釋型語言每次執行都需要把源碼轉換一次才能執行。

Java 和 C++ 等語言都是編譯型語言,而 JavaScript 是解釋性語言,它整體的執行速度會略慢于編譯型的語言。V8 是眾多瀏覽器的 JS 引擎中性能表現最好的一個,并且它是 Chrome 的內核,Node.js 也是基于 V8 引擎研發的。

編譯型語言和解釋器語言代碼執行的具體流程如下:

兩者的執行流程如下:

  • 在編譯型語言的編譯過程中,編譯器首先會依次對源代碼進行詞法分析、語法分析,生成抽象語法樹(AST),然后優化代碼,最后再生成處理器能夠理解的機器碼。如果編譯成功,將會生成一個可執行的文件。但如果編譯過程發生了語法或者其他的錯誤,那么編譯器就會拋出異常,最后的二進制文件也不會生成成功。
  • 在解釋型語言的解釋過程中,同樣解釋器也會對源代碼進行詞法分析、語法分析,并生成抽象語法樹(AST),不過它會再基于抽象語法樹生成字節碼,最后再根據字節碼來執行程序、輸出結果。

(2) V8 執行代碼過程

V8 在執行過程用到了解釋器和編譯器。 其執行過程如下:

  • Parse 階段:V8 引擎將 JS 代碼轉換成 AST(抽象語法樹)。
  • Ignition 階段:解釋器將 AST 轉換為字節碼,解析執行字節碼也會為下一個階段優化編譯提供需要的信息。
  • TurboFan 階段:編譯器利用上個階段收集的信息,將字節碼優化為可以執行的機器碼。
  • Orinoco 階段:垃圾回收階段,將程序中不再使用的內存空間進行回收。

這里前三個步驟是JavaScript的執行過程,最后一步是垃圾回收的過程。下面就先來看看V8 執行 JavaScript的過程。

生成抽象語法樹

這個過程就是將源代碼轉換為抽象語法樹(AST),并生成執行上下文,執行上下文就是代碼在執行過程中的環境信息。

將 JS 代碼解析成 AST主要分為兩個階段:

  • 詞法分析:這個階段會將源代碼拆成最小的、不可再分的詞法單元,稱為 token。比如代碼 var a = 1;通常會被分解成 var 、a、=、1、; 這五個詞法單元。代碼中的空格在 JavaScript 中是直接忽略的,簡單來說就是將 JavaScript 代碼解析成一個個令牌(Token)。
  • 語法分析:這個過程是將上一步生成的 token 數據,根據語法規則轉為 AST。如果源碼符合語法規則,這一步就會順利完成。如果源碼存在語法錯誤,這一步就會終止,并拋出一個語法錯誤,簡單來說就是將令牌組裝成一棵抽象的語法樹(AST)。

通過詞法分析會對代碼逐個字符進行解析,生成類似下面結構的令牌(Token),這些令牌類型各不相同,有關鍵字、標識符、符號、數字等。代碼 var a = 1;會轉化為下面這樣的令牌:

Keyword(var)
Identifier(name)
Punctuator(=)
Number(1)

語法分析階段會用令牌生成一棵抽象語法樹,生成樹的過程中會去除不必要的符號令牌,然后按照語法規則來生成。下面來看兩段代碼:

// 第一段代碼
var a = 1;
// 第二段代碼
function sum (a,b) {
  return a + b;
}

將這兩段代碼分別轉換成 AST 抽象語法樹之后返回的 JSON 如下:

  • 第一段代碼,編譯后的結果:
{
  "type": "Program",
  "start": 0,
  "end": 10,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 10,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 4,
          "end": 9,
          "id": {
            "type": "Identifier",
            "start": 4,
            "end": 5,
            "name": "a"
          },
          "init": {
            "type": "Literal",
            "start": 8,
            "end": 9,
            "value": 1,
            "raw": "1"
          }
        }
      ],
      "kind": "var"
    }
  ],
  "sourceType": "module"
}

它的結構大致如下:

  • 第二段代碼,編譯出來的結果:
{
  "type": "Program",
  "start": 0,
  "end": 38,
  "body": [
    {
      "type": "FunctionDeclaration",
      "start": 0,
      "end": 38,
      "id": {
        "type": "Identifier",
        "start": 9,
        "end": 12,
        "name": "sum"
      },
      "expression": false,
      "generator": false,
      "async": false,
      "params": [
        {
          "type": "Identifier",
          "start": 14,
          "end": 15,
          "name": "a"
        },
        {
          "type": "Identifier",
          "start": 16,
          "end": 17,
          "name": "b"
        }
      ],
      "body": {
        "type": "BlockStatement",
        "start": 19,
        "end": 38,
        "body": [
          {
            "type": "ReturnStatement",
            "start": 23,
            "end": 36,
            "argument": {
              "type": "BinaryExpression",
              "start": 30,
              "end": 35,
              "left": {
                "type": "Identifier",
                "start": 30,
                "end": 31,
                "name": "a"
              },
              "operator": "+",
              "right": {
                "type": "Identifier",
                "start": 34,
                "end": 35,
                "name": "b"
              }
            }
          }
        ]
      }
    }
  ],
  "sourceType": "module"
}

它的結構大致如下:

可以看到,AST 只是源代碼語法結構的一種抽象的表示形式,計算機也不會去直接去識別 JS 代碼,轉換成抽象語法樹也只是識別這一過程中的第一步。AST 的結構和代碼的結構非常相似,其實也可以把 AST 看成代碼的結構化的表示,編譯器或者解釋器后續的工作都需要依賴于 AST。

AST的應用場景:

AST 是一種很重要的數據結構,很多地方用到了AST。比如在 Babel 中,Babel 是一個代碼轉碼器,可以將 ES6 代碼轉為 ES5 代碼。Babel 的工作原理就是先將 ES6 源碼轉換為 AST,然后再將 ES6 語法的 AST 轉換為 ES5 語法的 AST,最后利用 ES5 的 AST 生成 JavaScript 源代碼。

除了 Babel 之外,ESLint 也使用到了 AST。ESLint 是一個用來檢查 JavaScript 編寫規范的插件,其檢測流程也是需要將源碼轉換為 AST,然后再利用 AST 來檢查代碼規范化的問題。

除了上述應用場景,AST 的應用場景還有很多:

  • JS 反編譯,語法解析。
  • 代碼高亮。
  • 關鍵字匹配。
  • 代碼壓縮。

生成字節碼

有了 抽象語法樹 AST 和執行上下文后,就輪到解釋器就登場了,它會根據 AST 生成字節碼,并解釋執行字節碼。

在 V8 的早期版本中,是通過 AST 直接轉換成機器碼的。將 AST 直接轉換為機器碼會存在一些問題:

  • 直接轉換會帶來內存占用過大的問題,因為將抽象語法樹全部生成了機器碼,而機器碼相比字節碼占用的內存多了很多;
  • 某些 JavaScript 使用場景使用解釋器更為合適,解析成字節碼,有些代碼沒必要生成機器碼,進而盡可能減少了占用內存過大的問題。

為了解決內存占用問題,就在 V8 引擎中引入了字節碼。那什么是字節碼呢?為什么引入字節碼就能解決內存占用問題呢?

字節碼就是介于 AST 和機器碼之間的一種代碼。 需要將其轉換成機器碼后才能執行,字節碼是對機器碼的一個抽象描述,相對于機器碼而言,它的代碼量更小,從而可以減少內存消耗。解釋器除了可以快速生成沒有優化的字節碼外,還可以執行部分字節碼。

生成機器碼

生成字節碼之后,就進入執行階段了,實際上,這一步就是將字節碼生成機器碼。

一般情況下,如果字節碼是第一次執行,那么解釋器就會逐條解釋執行。在執行字節碼過程中,如果發現有熱代碼(重復執行的代碼,運行次數超過某個閾值就被標記為熱代碼),那么后臺的編譯器就會把該段熱點的字節碼編譯為高效的機器碼,然后當再次執行這段被優化的代碼時,只需要執行編譯后的機器碼即可,這樣提升了代碼的執行效率。

字節碼配合解釋器和編譯器的技術就是 即時編譯(JIT)。在 V8 中就是指解釋器在解釋執行字節碼的同時,收集代碼信息,當它發現某一部分代碼變熱了之后,編譯器便閃亮登場,把熱點的字節碼轉換為機器碼,并把轉換后的機器碼保存起來,以備下次使用。

因為 V8 引擎是多線程的,編譯器的編譯線程和生成字節碼不會在同一個線程上,這樣可以和解釋器相互配合著使用,不受另一方的影響。下面是JIT技術的工作機制:

解釋器在得到 AST 之后,會按需進行解釋和執行。也就是說如果某個函數沒有被調用,則不會去解釋執行它。在這個過程中解釋器會將一些重復可優化的操作收集起來生成分析數據,然后將生成的字節碼和分析數據傳給編譯器,編譯器會依據分析數據來生成高度優化的機器碼。

優化后的機器碼的作用和緩存很類似,當解釋器再次遇到相同的內容時,就可以直接執行優化后的機器碼。當然優化后的代碼有時可能會無法運行(比如函數參數類型改變),那么會再次反優化為字節碼交給解釋器。

整個過程如下圖所示:

(3)執行過程優化

如果JavaScript代碼在執行前都要完全經過解析才能執行,那可能會面臨以下問題:

  • 代碼執行時間變長:一次性解析所有代碼會增加代碼的運行時間。
  • 消耗更多內存:解析完的 AST 以及根據 AST 編譯后的字節碼都會存放在內存中,會占用更多內存空間。
  • 占用磁盤空間:編譯后的代碼會緩存在磁盤上,占用磁盤空間。

所以,V8 引擎使用了延遲解析:在解析過程中,對于不是立即執行的函數,只進行預解析;只有當函數調用時,才對函數進行全量解析。

進行預解析時,只驗證函數語法是否有效、解析函數聲明、確定函數作用域,不生成 AST,而實現預解析的,就是 Pre-Parser 解析器。

以下面代碼為例:

function sum(a, b) {
    return a + b;
}
const a = 666;
const c = 996;
sum(1, 1);

V8 解析器是從上往下解析代碼的,當解析器遇到函數聲明 sum 時,發現它不是立即執行,所以會用 Pre-Parser 解析器對其預解析,過程中只會解析函數聲明,不會解析函數內部代碼,不會為函數內部代碼生成 AST。

之后解釋器會把 AST 編譯為字節碼并執行,解釋器會按照自上而下的順序執行代碼,先執行 const a = 666;  和 const c = 996; ,然后執行函數調用 sum(1, 1) ,這時 Parser 解析器才會繼續解析函數內的代碼、生成 AST,再交給解釋器編譯執行。

2、垃圾回收

(1)JS 內存管理機制

計算機程序語言都運行在對應的代碼引擎上,使用內存過程可以分為以下三個步驟:

  • 分配所需要的系統內存空間。
  • 使用分配到的內存進行讀或寫等操作。
  • 不需要使用內存時,將其空間釋放或者歸還。

在 JavaScript 中,當創建變量時,系統會自動給對象分配對應的內存,來看下面的例子:

var a = 123; // 給數值變量分配棧內存
var etf = "ARK"; // 給字符串分配棧內存
// 給對象及其包含的值分配堆內存
var obj = {
  name: 'tom',
  age: 13
}; 
// 給數組及其包含的值分配內存
var a = [1, null, "str"]; 
// 給函數分配內存
function sum(a, b){
  return a + b;
}

JavaScript 中的數據分為兩類:

  • 基本類型:這些類型在內存中會占據固定的內存空間,它們的值都保存在棧空間中,直接可以通過值來訪問這些;
  • 引用類型:由于引用類型值大小不固定,棧內存中存放地址指向堆內存中的對象,是通過引用來訪問的。

棧內存中的基本類型,可以通過操作系統直接處理;而堆內存中的引用類型,正是由于可以經常變化,大小不固定,因此需要 JavaScript 的引擎通過垃圾回收機制來處理。所謂的垃圾回收是指:JavaScript代碼運行時,需要分配內存空間來儲存變量和值。當變量不在參與運行時,就需要系統收回被占用的內存空間。 Javascript 具有自動垃圾回收機制,會定期對那些不再使用的變量、對象所占用的內存進行釋放,原理就是找到不再使用的變量,然后釋放掉其占用的內存。

JavaScript中存在兩種變量:局部變量和全局變量。全局變量的生命周期會持續要頁面卸載;而局部變量聲明在函數中,它的生命周期從函數執行開始,直到函數執行結束,在這個過程中,局部變量會在堆或棧中存儲它們的值,當函數執行結束后,這些局部變量不再被使用,它們所占有的空間就會被釋放。不過,當局部變量被外部函數使用時,其中一種情況就是閉包,在函數執行結束后,函數外部的變量依然指向函數內部的局部變量,此時局部變量依然在被使用,所以不會回收。

(2)V8 垃圾回收過程

先來看看 Chrome 瀏覽器的垃圾回收過程:

通過 GC Root 標記空間中活動對象和?活動對象

目前 V8 采用的可訪問性算法來判斷堆中的對象是否是活動對象。這個算法是將一些 GC Root 作為初始存活的對象的集合,從 GC Roots 對象出發,遍歷 GC Root 中所有對象:

  • 通過 GC Root 遍歷到的對象是可訪問的,必須保證這些對象應該在內存中保留,可訪問的對象稱為活動對象。
  • 通過 GC Roots 沒有遍歷到的對象是不可訪問的,這些不可訪問的對象就可能被回收,不可訪問的對象稱為非活動對象。

回收非活動對象所占據的內存

其實就是在所有的標記完成之后,統一清理內存中所有被標記為可回收的對象。

內存整理

一般來說,頻繁回收對象后,內存中就會存在大量不連續空間,這些不連續的內存空間稱為內存碎片。當內存中出現了大量的內存碎片之后,如果需要分配較大的連續內存時,就有可能出現內存不足的情況,所以最后一步需要整理這些內存碎片。這步其實是可選的,因為有的垃圾回收器不會產生內存碎片。

以上就是大致的垃圾回收流程。目前 V8 使用了兩個垃圾回收器:主垃圾回收器和副垃圾回收器。下面就來看看 V8 是如何實現垃圾回收的。

在 V8 中,會把堆分為新生代和老生代兩個區域,新生代中存放的是生存時間短的對象,老生代中存放生存時間久的對象:

新?代通常只?持 1~8M 的容量,而老生代支持的容量就大很多。對于這兩塊區域,V8分別使用兩個不同的垃圾回收器,以便更高效地實施垃圾回收:

  • 副垃圾回收器:負責新生代的垃圾回收。
  • 主垃圾回收器:負責老生代的垃圾回收。

副垃圾回收器(新生代)

副垃圾回收器主要負責新生代的垃圾回收。大多數的對象最開始都會被分配在新生代,該存儲空間相對較小,分為兩個空間:from 空間(對象區)和 to 空間(空閑區)。

新加入的對象都會存放到對象區域,當對象區域快被寫滿時,就需要執行一次垃圾清理操作:首先要對對象區域中的垃圾做標記,標記完成之后,就進入垃圾清理階段。副垃圾回收器會把這些存活的對象復制到空閑區域中,同時它還會把這些對象有序地排列起來。這個復制過程就相當于完成了內存整理操作,復制后空閑區域就沒有內存碎片了:

完成復制后,對象區域與空閑區域進行角色翻轉,也就是原來的對象區域變成空閑區域,原來的空閑區域變成了對象區域,這種算法稱之為 Scavenge 算法,這樣就完成了垃圾對象的回收操作。同時,這種角色翻轉的操作還能讓新生代中的這兩塊區域無限重復使用下去:

不過,副垃圾回收器每次執行清理操作時,都需要將存活的對象從對象區域復制到空閑區域,復制操作需要時間成本,如果新生區空間設置得太大了,那么每次清理的時間就會過久,所以為了執行效率,一般新生區的空間會被設置得比較小。 也正是因為新生區的空間不大,所以很容易被存活的對象裝滿整個區域,副垃圾回收器一旦監控對象裝滿了,便執行垃圾回收。同時,副垃圾回收器還會采用對象晉升策略,也就是移動那些經過兩次垃圾回收依然還存活的對象到老生代中。

主垃圾回收器(老生代)

主垃圾回收器主要負責老生代中的垃圾回收。除了新生代中晉升的對象,?些?的對象會直接被分配到老生代里。因此,老生代中的對象有兩個特點:

  • 對象占用空間大。
  • 對象存活時間間。

由于老生代的對象比較大,若要在老生代中使用 Scavenge 算法進行垃圾回收,復制這些大的對象將會花費較多時間,從而導致回收執行效率不高,同時還會浪費空間。所以,主垃圾回收器采用標記清除的算法進行垃圾回收。

這種方式分為標記和清除兩個階段:

  • 標記階段: 從一組根元素開始,遞歸遍歷這組根元素,在這個遍歷過程中,能到達的元素稱為活動對象,沒有到達的元素就可以判斷為垃圾數據。
  • 清除階段: 主垃圾回收器會直接將標記為垃圾的數據清理掉。

這兩個階段如圖所示:

對垃圾數據進行標記,然后清除,這就是標記清除算法,不過對一塊內存多次執?標記清除算法后,會產生大量不連續的內存碎片。而碎片過多會導致大對象無法分配到足夠的連續內存,于是又引入了另外一種算法——標記整理。

這個算法的標記過程仍然與標記清除算法里的是一樣的,先標記可回收對象,但后續步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,然后直接清理掉這一端之外的內存:

全停頓

我們知道,JavaScript 是單行線語言,運行在主線程上。一旦執行垃圾回收算法,都需要將正在執行的 JavaScript 腳本暫停下來,待垃圾回收完畢后再恢復腳本執行。這種行為叫做全停頓。

主垃圾回收器執行一次完整的垃圾回收流程如下圖所示:

在 V8 新生代的垃圾回收中,因其空間較小,且存活對象較少,所以全停頓的影響不大。但老生代中,如果在執行垃圾回收的過程中,占用主線程時間過久,主線程是不能做其他事情的,需要等待執行完垃圾回收操作才能做其他事情,這將就可能會造成頁面的卡頓現象。

為了降低老生代的垃圾回收而造成的卡頓,V8 將標記過程分為一個個的子標記過程,同時讓垃圾回收標記和 JavaScript 應用邏輯交替進行,直到標記階段完成,這個算法稱為增量標記算法。如下圖所示:

使用增量標記算法可以把一個完整的垃圾回收任務拆分為很多小的任務,這些小的任務執行時間比較短,可以穿插在其他的 JavaScript 任務中間執行,這樣當執行代碼時,就不會讓用戶因為垃圾回收任務而感受到頁面的卡頓了。

(3)減少垃圾回收

雖然瀏覽器可以進行垃圾自動回收,但是當代碼比較復雜時,垃圾回收所帶來的代價較大,所以應該盡量減少垃圾回收:

  • 對數組進行優化: 在清空一個數組時,最簡單的方法就是給其賦值為[ ],但是與此同時會創建一個新的空對象,可以將數組的長度設置為0,以此來達到清空數組的目的。
  • 對object進行優化: 對象盡量復用,對于不再使用的對象,就將其設置為null,盡快被回收。
  • 對函數進行優化: 在循環中的函數表達式,如果可以復用,盡量放在函數的外面。
責任編輯:姜華 來源: 前端充電寶
相關推薦

2022-09-16 08:32:25

JavaC++語言

2023-06-05 16:38:51

JavaScript編程語言V8

2022-06-02 12:02:12

V8C++JavaScript

2021-05-24 11:25:13

Node.js 16V8前端

2025-09-08 01:55:00

2010-07-20 16:35:52

V8JavaScript瀏覽器

2021-09-05 17:46:21

云計算No.jsio_uringJS

2023-03-02 23:09:53

Node.jsC++JS

2014-11-26 09:51:24

GithubGoogleV8

2010-08-31 11:42:03

DB2MDC

2022-04-29 08:00:51

V8垃圾回收

2020-10-12 14:59:31

V8引擎如何執行Jav

2021-05-28 05:30:55

HandleV8代碼

2021-10-05 20:12:57

No.jsV8 編碼

2023-02-28 07:56:07

V8內存管理

2011-10-19 13:47:57

ibmdwRationalWAS

2021-08-29 18:34:44

編譯V8C++

2016-10-18 15:18:48

JEECMS V*javaCMS系統

2022-02-25 08:32:07

nodemon搭Node.jsJavascript

2022-06-21 08:52:47

Node.js服務端JavaScript
點贊
收藏

51CTO技術棧公眾號

日韩黄色免费电影| 五月天亚洲一区| 亚洲人成网站影音先锋播放| 91精品婷婷国产综合久久蝌蚪| 丰满少妇被猛烈进入一区二区| 日韩欧美中文字幕一区二区三区| 天天av天天翘天天综合网色鬼国产| 欧美日韩精品不卡| 国产农村妇女毛片精品| 136国产福利精品导航网址| 亚洲色图第一页| 人妻换人妻仑乱| 精品国产第一福利网站| 亚洲精品成人天堂一二三| 精品一区二区日本| 夜夜躁狠狠躁日日躁av| 电影在线观看一区| 国产亲近乱来精品视频| 国产91aaa| 中文字幕一级片| 国产精品啊v在线| 中文字幕av一区二区| 又黄又色的网站| 另类一区二区三区| 精品美女久久久久久免费| 尤物国产精品| 国产精品麻豆一区二区三区| 大桥未久av一区二区三区中文| 国产精品av电影| 国产中文字幕免费| 68国产成人综合久久精品| 亚洲欧美激情一区| 稀缺小u女呦精品呦| 色综合.com| 欧美影视一区在线| 国产免费黄视频| 欧美1—12sexvideos| 成人欧美一区二区三区小说| 日本午夜精品一区二区| 天堂a中文在线| 国产suv精品一区二区三区| 成人国产亚洲精品a区天堂华泰| 免费看毛片网站| 香蕉久久夜色精品| 午夜精品一区二区三区在线视| 天天天天天天天天操| 久久五月天小说| 在线免费看av不卡| 日本精品久久久久中文| 精品国产一区一区二区三亚瑟| 亚洲久久久久久久久久| 亚洲制服丝袜在线播放| 精品网站aaa| 欧美精品一区二区在线播放| 亚洲成人激情小说| 日韩视频一区二区三区四区| 日韩三级视频中文字幕| 性生活一级大片| 亚洲91网站| 欧美成人三级在线| 无码任你躁久久久久久老妇| 99a精品视频在线观看| 欧美tickling网站挠脚心| 中文字幕一二三区| 久久九九热re6这里有精品| 亚洲成人黄色在线| 日本黄色动态图| 老牛精品亚洲成av人片| 亚洲精品福利免费在线观看| 欧美性xxxx图片| 视频一区中文| 日韩中文字幕在线看| 日韩视频中文字幕在线观看| 亚洲视频狠狠| 7777kkkk成人观看| 波多野结衣网站| 麻豆成人免费电影| 国产成人免费电影| 色哟哟在线观看| 中文字幕av一区二区三区| 亚洲一区3d动漫同人无遮挡| a黄色片在线观看| 亚洲免费成人在线视频| 亚洲欧美高清视频| 91视视频在线直接观看在线看网页在线看 | 欧日韩在线观看| 波多野结衣一区二区三区四区| 免费人成精品欧美精品| 91日韩久久| 欧美日韩视频精品二区| 亚洲欧洲成人精品av97| 亚洲 欧美 综合 另类 中字| 香蕉视频亚洲一级| 日韩一区二区在线免费观看| aaaa黄色片| 天天做天天爱天天综合网| 欧美激情亚洲自拍| 中国女人一级一次看片| 成人午夜免费电影| 亚洲春色在线视频| 国产又粗又大又爽| 国产91对白在线观看九色| 清纯唯美一区二区三区| 国产在线观看免费麻豆| 欧美日韩在线视频一区二区| www.亚洲高清| 神马日本精品| 久久综合久久美利坚合众国| 中文字幕激情小说| 国产成人精品一区二| 色999日韩自偷自拍美女| 久色国产在线| 欧美日韩精品高清| 欧美成人三级伦在线观看| 99久久夜色精品国产亚洲狼 | 国产一级一级片| 日本欧美大码aⅴ在线播放| 高清视频一区| 日本电影在线观看网站| 夜夜嗨av一区二区三区网页| 亚州精品一二三区| 亚洲精品播放| 午夜精品久久久久久99热| 91麻豆成人精品国产| 国产校园另类小说区| 国产精品久久久久7777| 国产精品久久久久久久久久辛辛| 亚洲欧美激情四射在线日| 日本熟妇毛茸茸丰满| 国产精品一区二区三区99| 亚洲一二三区在线| 欧美xxxx做受欧美护士| 亚洲伦理中文字幕| 特一级黄色大片| 成人午夜短视频| 国产日韩第一页| 日本午夜精品久久久久| 一区二区三区黄色| 亚洲精品一区二三区| 91在线精品一区二区| 久久综合久久网| xxxx日韩| 国内成人精品视频| 色丁香婷婷综合久久| 一区二区三区在线视频免费观看| 国产精品久久久久久9999| 欧美电影一区| 国产欧美久久一区二区| 中文字幕日本在线观看| 欧美男男青年gay1069videost| 我不卡一区二区| 蜜臀av性久久久久蜜臀aⅴ四虎 | 亚洲麻豆一区二区三区| 狠狠综合久久av一区二区老牛| 91手机在线播放| 污污视频在线| 欧美成va人片在线观看| 久久精品国产亚洲AV无码男同 | 成年人网站免费看| 久久大逼视频| 日本在线视频不卡| 国内自拍亚洲| 久久中文字幕一区| 亚洲欧美另类日韩| 欧美午夜宅男影院在线观看| 久久久久亚洲av成人无码电影| 日韩高清在线观看| 黄色www在线观看| 4438全国亚洲精品观看视频| 久久免费高清视频| 欧美人体大胆444www| 欧美性xxxxxxxx| 加勒比婷婷色综合久久| 成人午夜在线免费| 黄色一级免费大片| 99久久www免费| 国产精品麻豆免费版| 成人美女视频| 日韩中文字幕在线免费观看| 亚洲精品久久久狠狠狠爱 | 亚洲在线视频播放| 亚洲激情六月丁香| 人妻无码一区二区三区| 久久国产免费看| 久久av综合网| 国内成人自拍| 亚洲最大的网站| 欧美成人免费电影| 久久夜色精品国产亚洲aⅴ| 蜜桃在线一区二区| 欧美三级电影网| 国产性70yerg老太| 国产精品理论在线观看| 亚洲av无码专区在线播放中文| 久久国产精品久久久久久电车| 中文字幕人成一区| 色综合久久中文| 147欧美人体大胆444| 欧美电影免费观看网站| 九九热视频这里只有精品| 欧美伦理影视网| 日韩精品一区二区三区三区免费| 在线观看日本视频| 亚洲国产aⅴ成人精品无吗| 日韩女同一区二区三区| 成av人片一区二区| 可以看污的网站| 久久成人一区| 精品国偷自产一区二区三区| 99国内精品久久久久久久| 久久精品女人的天堂av| 成人午夜在线影视| 亚洲免费中文字幕| 精品久久人妻av中文字幕| 欧美午夜一区二区| 毛片视频网站在线观看| 亚洲精品水蜜桃| 欧美另类69xxxx| 久久综合九色综合97婷婷女人 | 91网站最新网址| 99热这里只有精品2| 免费在线欧美视频| 欧美成人免费高清视频| 黄色亚洲免费| 国产人妻人伦精品| 四季av一区二区三区免费观看| 久久综合给合久久狠狠色| 最新国产精品精品视频| 91精品一区二区| 97精品国产综合久久久动漫日韩| 欧美在线中文字幕| 国产在线观看www| 欧美国产亚洲视频| 女囚岛在线观看| 欧美成人午夜激情在线| 国产精品va在线观看视色| 自拍偷拍亚洲精品| 丝袜美腿美女被狂躁在线观看| 亚洲欧美日韩视频一区| 五月婷婷丁香六月| 亚洲精品按摩视频| 特级丰满少妇一级aaaa爱毛片| 精品国产乱码久久久久久影片| www黄色在线观看| 欧美成人女星排行榜| 亚洲国产综合网| 精品国产乱子伦一区| 免费av网站在线播放| 精品国产123| 四虎影院在线播放| 亚洲片在线资源| 成人在线观看一区| 中国日韩欧美久久久久久久久| 粉嫩av在线播放| 中文字幕欧美日韩精品| 在线激情免费视频| 中文字幕一区二区三区电影| 色哟哟免费在线观看| 久久久精品网站| 1区2区在线观看| 久久久久久国产免费| 高清毛片在线观看| 国产va免费精品高清在线观看 | 亚洲天堂偷拍| 国产91在线视频观看| 免费在线亚洲欧美| 奇米影音第四色| 国产精品一区二区三区99| 无码任你躁久久久久久老妇| 2020国产精品| 中文字幕乱码av| 一区二区三区高清不卡| 少妇一级淫片免费放中国| 日本乱码高清不卡字幕| 国产精品九九九九| 精品国产一区二区三区忘忧草| 五十路在线观看| 一区三区二区视频| 青草视频在线免费直播 | 黄色片网站在线免费观看| 色就色 综合激情| 国产视频手机在线| 日韩精品福利网站| 婷婷视频在线| 97免费视频在线| av在线播放一区| 国产精品免费看一区二区三区 | 亚洲区成人777777精品| 亚洲二区精品| 亚洲天堂2018av| 成人免费电影视频| 一级在线观看视频| 亚洲午夜久久久| 又污又黄的网站| 亚洲第一页中文字幕| 天堂地址在线www| 91chinesevideo永久地址| 日韩在线你懂得| 久久久久久久久久久久久9999| 欧美成人激情| 人妻有码中文字幕| 国产成人午夜精品影院观看视频 | 日韩欧美电影在线观看| 日韩少妇与小伙激情| 黄色软件视频在线观看| 91精品综合视频| 精品国产99| 国产日韩欧美精品在线观看| 毛片av一区二区三区| 久久偷拍免费视频| 亚洲午夜电影在线| 一级黄色片免费| 亚洲欧美日韩一区二区在线| 欧美性video| 国产主播精品在线| 国产真实有声精品录音| ww国产内射精品后入国产| 国产精品一区一区三区| 福利视频第一页| 色婷婷综合久久久久中文一区二区 | 国内精品国产三级国产a久久| 成人手机在线免费视频| 一区二区三区四区亚洲| 亚洲天堂中文在线| 亚洲欧美综合v| 亚洲欧美韩国| 久久婷婷人人澡人人喊人人爽| 欧美激情成人在线| www.欧美激情.com| 亚洲欧洲性图库| 艳妇乳肉豪妇荡乳av无码福利 | 国产三区视频在线观看| 国产福利视频一区二区| 精品在线网站观看| www.射射射| 大白屁股一区二区视频| 久久久久久国产精品视频| 欧美一二三区在线观看| av黄色在线| 91九色极品视频| 欧美一区二区三区免费看| 日韩av一卡二卡三卡| 国产精品久久福利| 国产视频一区二区三区四区五区| 久久精品成人动漫| 国产精品成人3p一区二区三区| 影音先锋亚洲视频| 国内精品视频666| 欧美日韩在线视频免费播放| 欧美成人性战久久| 成人在线高清免费| 久久66热这里只有精品| 99精品免费| 久久美女免费视频| 欧美性一区二区| 久久五月精品| 91丨九色丨国产| 夜夜嗨av一区二区三区网站四季av| 精品人妻伦一二三区久| 色综合一区二区三区| av在线播放免费| 91社区国产高清| 欧美三级免费| 久久久久国产精品区片区无码| 色综合色综合色综合色综合色综合 | 国产a视频精品免费观看| 国产主播在线观看| 亚洲欧美一区二区三区情侣bbw| 日本另类视频| 日本老太婆做爰视频| 成人高清视频免费观看| 日日骚av一区二区| zzjj国产精品一区二区| 亚洲精品国产九九九| 欧美日韩亚洲一| 国产精品久久久久久久久搜平片 | 国产又粗又硬又长| 成熟亚洲日本毛茸茸凸凹| 一级做a爰片久久毛片| 日韩一区二区av| 红杏aⅴ成人免费视频| 北条麻妃视频在线| 亚洲精品国产精品乱码不99| 天堂a中文在线| 成人免费看片视频| 99精品视频免费观看视频| аⅴ天堂中文在线网| 精品乱人伦一区二区三区| 超级碰碰久久| 中国黄色录像片| 26uuu色噜噜精品一区| 99这里有精品视频| 日韩美女免费线视频| 亚洲在线久久| 干b视频在线观看| 精品精品国产高清a毛片牛牛| 欧美日韩女优| 男女猛烈激情xx00免费视频| 国产精品久久国产精麻豆99网站| 天天操天天干天天爱|