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

R8疑難雜癥分析實戰(zhàn):外聯(lián)優(yōu)化設(shè)計缺陷引起的崩潰

開發(fā) 前端 Android
在Android開發(fā)中,即使是AGP、R8這樣的官方工具鏈升級,也要保持足夠的警惕。畢竟Android生態(tài)太過復(fù)雜,再加上開發(fā)者們千奇百怪的代碼寫法,不論多么完善的測試流程都無法規(guī)避這類特定場景的bug。

一、背景

二、復(fù)現(xiàn)問題

三、問題分析

    1. ApiModel外聯(lián)是什么?

    2. 為什么會多生成一個new-instance指令?

    3. R8是如何計算出API的版本?

    4. 為什么try-catch也會導(dǎo)致該問題?

    5. 為什么只升級AGP會導(dǎo)致R8功能出問題?

四、解決方案

    1. 禁用ApiModel

    2. 官方修復(fù)

    3. 自行修復(fù)

    4. 業(yè)務(wù)改造(推薦)

五、總結(jié)

一、背景

R8作為谷歌官方的編譯優(yōu)化工具,在編譯階段會對字節(jié)碼進行大規(guī)模修改,以追求包體優(yōu)化和性能提升。但是Android應(yīng)用開發(fā)者數(shù)量太過龐大,無論測試流程多么完善,終究難以避免在一些特定場景下出現(xiàn)問題。

近期我們在升級項目的AGP,遇到了一個指向系統(tǒng)SurfaceTexture類的native崩潰問題。經(jīng)反編譯分析發(fā)現(xiàn)問題最終指向了smali字節(jié)碼中多余的一行new-instance指令。

圖片圖片

圖片圖片

該指令創(chuàng)建了一個SurfaceTexture對象,但是并未調(diào)用其<init>方法,這意味著構(gòu)造方法沒有執(zhí)行,但是這個類重寫了finalize方法,后續(xù)被gc回收時會調(diào)用其中的nativeFinalize這個JNI方法,最終在native層執(zhí)行析構(gòu)函數(shù)時觸發(fā)了SIGNALL 11的內(nèi)存訪問錯誤.

圖片圖片

圖片圖片

二、復(fù)現(xiàn)問題

我們注意到多出來的new-instance指令下面緊接著的是對a0.e 類中的靜態(tài)方法 i() 的調(diào)用,其內(nèi)部實現(xiàn)就是SurfaceTexture的構(gòu)造方法。這是典型的代碼外聯(lián)操作,即一段相同的代碼在工程中多次出現(xiàn),則會被抽出來單獨作為一個靜態(tài)函數(shù),原先的調(diào)用點則替換成該函數(shù)的調(diào)用,這樣可以減小代碼體積,是常見的編碼思路。

例如:

class Activity{
    void onCreate(){
        // ...
        String a = xx.xxx();
        String b = xx.xxx();
        Log.e("log",a+b);
        //...
    }


    void onReusme(){
        // ...
        String a = xx.xxx();
        String b = xx.xxx();
        Log.e("log",a+b);
        //...
    }


}
class Activity{
    void onCreate(){
        // ...
        Activity$Outline.log();
        //...
    }


    void onReusme(){
        // ...
        Activity$Outline.log();
        //...
    }
}
//外聯(lián)生成的類
class Activity$Outline{
    public static void log(){
        String a = xx.xxx();
        String b = xx.xxx();
        Log.e("log",a+b);
    }
}

我們根據(jù)這個生成類的類名可以知道是R8中ApiModelOutline功能生成了這個類。

圖片圖片

我們進到R8工程中檢索下相關(guān)的關(guān)鍵字,再加上demo多次嘗試,可以確認滿足以下條件能夠必現(xiàn)該問題:

  1. 使用了高于當(dāng)前minSdkVersion的系統(tǒng)函數(shù)/變量(僅限系統(tǒng)類,自己寫的無效)
  2. 用synchronized或者try語句塊包裹了該調(diào)用,或者給該函數(shù)傳參時有任何計算行為(除了傳局部變量)。例如:
  1. new SurfaceTexture( getParmas() )
  2. new SurfaceTexture( if(enable) 1 : 2)
  3. new SurfaceTexture ( (boolean) enable )

三、問題分析

在確認復(fù)現(xiàn)條件之后,我們帶著幾個問題來逐個分析。

ApiModel外聯(lián)是什么?

R8中的優(yōu)化大多數(shù)跟包體優(yōu)化有關(guān),代碼外聯(lián)也是其中一種,但是外聯(lián)的前提是代碼重復(fù)的次數(shù)滿足一定閾值,但是ApiModel會對所有調(diào)用了高版本系統(tǒng)API的代碼做外聯(lián),包括只調(diào)用一次的場景。

ApiModel并非為了包體優(yōu)化,我們通過R8工程的issueTracker(https://issuetracker.google.com/issues/333477035)檢索到了相關(guān)的信息:

圖片圖片

譯:AGP新增的ApiModel功能是為了防止在低版本設(shè)備上不可能執(zhí)行的代碼引起類驗證錯誤,從而降低App啟動耗時。

從這篇介紹ART虛擬機類驗證的文檔(https://chromium.googlesource.com/chromium/src/+/HEAD/build/android/docs/class_verification_failures.md#chromium_s-solution)就能夠理解上面這句話的含義:

ART虛擬機會在APK安裝之后立刻執(zhí)行 AOT class verification,即對dex文件中所有的類進行驗證,如果驗證成功則后續(xù)運行時將不需要再進行驗證,反之若失敗,則該class會被ART打上RetryVerificationAtRuntime的標(biāo)記,后續(xù)運行時還得重新執(zhí)行類驗證。

同時這些失敗的類也將無法被dex2oat優(yōu)化成oat格式的優(yōu)化字節(jié)碼(oat字節(jié)碼的加載和執(zhí)行速度更快)。

圖片圖片

如果是在MainActivity,啟動任務(wù)中使用了這些高版本API,那么在低版本設(shè)備App啟動時就必須額外執(zhí)行一次類驗證(比較耗時,有的類能到8ms https://issues.chromium.org/issues/40574431),而ApiModel外聯(lián)則是相當(dāng)于將這些肯定驗證失敗的函數(shù)的調(diào)用單獨抽到一個生成類中,這樣運行時就能將類驗證失敗問題徹底隔離在生成類中,從而規(guī)避運行時的類驗證耗時。

//安裝apk后驗證失敗,運行時驗證失敗,但是能正常執(zhí)行
class MainActivity{
    void onCreate(){
        if(android.sdk > 26){
            new SurfaceTexture(false);
        }
    }
}

ApiModel后

class MainActivity{
    void onCreate(){
        if(android.sdk > 26){
            a0.b(); //這樣類驗證就能成功
        }
    }
}
//生成的外聯(lián)類,類驗證會失敗,但是運行時不可能走到,不影響
class a0{
    public static void b(){
        new SurfaceTexture(false);
    }
}

更多關(guān)于ApiModel的詳細介紹,見這篇文章:https://medium.com/androiddevelopers/mitigating-soft-verification-issues-in-r8-and-d8-7e9e06827dfd

為什么會多生成一個new-instance指令?

介紹完ApiModel之后,我們已經(jīng)知道了為什么<init>方法的調(diào)用被替換成了一個生成函數(shù)的調(diào)用,接下來我們再分析下導(dǎo)致崩潰的罪魁禍?zhǔn)?new-instance 指令是如何出現(xiàn)的。

我們先來了解下java文件在編譯過程中的格式轉(zhuǎn)換過程,因為ApiModel是基于IRCode格式(R8自定義的格式)來做外聯(lián)。

文件轉(zhuǎn)換

javac

javac將java文件編譯成class文件

值得一提的是sychronized語句塊在javac編譯之后會為其內(nèi)部代碼生成try-catch,這是為了確保在語句塊拋異常時能夠正常釋放鎖,因此和問題有關(guān)的是try-catch語句塊,和synchronized無關(guān)。

圖片圖片

D8

目前R8已經(jīng)整合D8,因此輸入class文件之后就會先通過D8轉(zhuǎn)為dex格式,并持有在內(nèi)存中。

轉(zhuǎn)換之后的指令基本和class字節(jié)碼基本類似。

圖片

IRcode

為了做進一步的優(yōu)化,會將dex格式的代碼轉(zhuǎn)化成R8自定義的IRcode格式,其特點是代碼分塊。

案例:

圖片圖片

問題根因

在R8工程里檢索ApiModel關(guān)鍵字,最終定位到針對構(gòu)造函數(shù)生成外聯(lián)函數(shù)和指令替換的代碼:

InstanceInitializerOutliner->rewriteCode

執(zhí)行此方法之前的指令如下:

java:
new SurfaceTexture(false);
dex:
: -1: NewInstance          v1 <-  android.graphics.SurfaceTexture
: -1: ConstNumber          v2(0) <-  0 (INT)
: -1: Invoke-Direct        v1, v2(0); method: void android.graphics.SurfaceTexture.<init>(boolean)
  • 對整個方法中所有的指令從上往下進行遍歷,第一次遍歷主要是:

檢索 <init>方法調(diào)用的指令

判斷該方法的androidApiLevel是否高于minSDK

生成包含完整構(gòu)造函數(shù)指令的外聯(lián)函數(shù),并替換<init>函數(shù)調(diào)用為外聯(lián)函數(shù)調(diào)用。

執(zhí)行完替換邏輯,就記錄信息到map中,key是<init>對應(yīng)的new-instance指令,value是前一步中替換的新指令。

經(jīng)過這一步,字節(jié)碼會變成這樣:

圖片圖片

具體替換邏輯如下(可以參考注釋理解):

圖片圖片

  • 第二次遍歷則是對new-instance指令的處理:

找到new-instance指令

查詢map,確認<init>方法已完成替換

根據(jù)canSkipClInit方法返回的結(jié)果分為兩種場景:

無類初始化邏輯:直接移除new-instance指令,不影響原代碼的語義。

圖片圖片

  • 有類初始化邏輯:生成外聯(lián)函數(shù),只包含該new-instance指令,和前一次遍歷一樣進行指令替換。

圖片圖片

具體替換邏輯:

圖片圖片

  • 問題重點就在于canSkipClInit這個函數(shù)的實現(xiàn)。

它會檢查 new-intance指令和invoke <init>指令之間是否存在任何局部變量聲明以外的指令,如果存在,他會認為這些指令是這個類初始化的邏輯,因此為了保留源代碼的執(zhí)行順序,這種情況下就是需要額外執(zhí)行一次new-instance指令來觸發(fā)類初始化。

圖片圖片

但是實際上,如果在調(diào)用這個構(gòu)造函數(shù)傳參時執(zhí)行了任何運算(和類加載無關(guān)),都會生成相關(guān)的指令插在中間,例如:


java寫法

new-intance和invoke <init>指令之間的指令

new SurfaceTexture( getParmas() )

invoke-virtual   v2 <-; method: void xx.xx.xx

new SurfaceTexture( if(enable) 1 : 2)

StaticGet            v3 <- ; field: boolean  xxx.xxx.xx

new SurfaceTexture ( (boolean) enable )

: -1: CheckCast            v5 <- v3; java.lang.Boolean

: -1: Invoke-Virtual       v6 <- v5; method: boolean java.lang.Boolean.booleanValue()

從作者留下的todo也能看出,后續(xù)準(zhǔn)備擴展這個方法,實現(xiàn)對這些夾在中間的指令的判斷,如果是對類初始化無影響的入?yún)⒂嬎氵壿嫞瑒t也將正常移除new-intance指令。

圖片圖片

值得一提的是,我們最終APK里 new-intance指令并沒有被外聯(lián),這是因為SurfaceTexture這個類本身在安卓21之前的版本就已經(jīng)存在,只是入?yún)閎ool類型的構(gòu)造方法是在安卓26新增的,所以他其實是被外聯(lián)之后又被內(nèi)聯(lián)回到了調(diào)用處,因此看起來像是沒有被外聯(lián)。

圖片圖片

小結(jié)

至此,我們就明白了多出來一個看似無用的new-intance指令,實際上是為了保全源代碼的語義,觸發(fā)類加載用的,但是作者沒有考慮到這些被優(yōu)化的類可能重寫了finalize方法來釋放一些本就不存在的資源。

而且不局限于調(diào)用native函數(shù),只要是重寫了finalize,并在里面訪問一些在構(gòu)造函數(shù)中初始化的成員變量,一樣可能造成NPE等崩潰。

R8是如何計算出API的版本?

圖片圖片

R83.3版本開始,它編譯時會下載一個.ser格式的數(shù)據(jù)庫文件,里面記錄了所有系統(tǒng)API、變量與安卓版本號的映射信息,在運行時通過行號和偏移量來尋找各自的版本號。

圖片圖片

為什么try-catch也會導(dǎo)致該問題?

前面解釋了在構(gòu)造函數(shù)入?yún)⒅刑砑雍瘮?shù)調(diào)用等寫法導(dǎo)致的字節(jié)碼異常原因,但是實際上這次我們遇到的崩潰場景是在sychronized里new了一個SurfaceTexture。

圖片圖片

前文中已經(jīng)解釋過,sychronized在編譯成class后會生成try-catch語句塊,這段代碼改成用try-catch語句塊包裹,一樣會復(fù)現(xiàn)崩潰,因此我們跟蹤try-catch在文件轉(zhuǎn)換過程中對字節(jié)碼的影響即可。

回到class文件轉(zhuǎn)dex文件的階段,我們發(fā)現(xiàn)try語句塊中的每一行指令,都會在其后生成一條FALLTHROUGH指令。

dex格式:

圖片圖片

FALLTHROUGH是什么指令,他是做什么的?

FALLTHROUGH指令表示指令自然流轉(zhuǎn),沒有實際含義,它主要是為了幫助優(yōu)化器識別哪些指令是可達的。

例如下面這種寫法,case1沒有寫break,這樣會接著執(zhí)行case2的代碼:

switch (value) {
            case 1:
                System.out.println("One");
                // 故意不寫break
            case 2:
                System.out.println("Two");
                break;
            case 3:
                System.out.println("Three");
                break;
        }

其字節(jié)碼如下:

正常有break的話,會對應(yīng)一條GOTO 指令跳轉(zhuǎn)到switch語句塊最后一行,但是沒寫break的話,就會出現(xiàn):

在12行執(zhí)行 goto 13 跳轉(zhuǎn)到13行的指令,這種指令毫無意義,且運行時會消耗性能,因此可以替換成FALLTHROUGH指令,這樣最終在生成dex文件時會被移除掉,從而避免浪費性能。

public static void switchWithFallthrough(int);
  Code:
    stack=2, locals=1, args_size=1


    // 加載參數(shù)
    0: iload_0


    // 檢查case 1
    1: iconst_1
    2: if_icmpne 13    // 如果不等于1,跳轉(zhuǎn)到case 2
    5: getstatic #2    // Field java/lang/System.out:Ljava/io/PrintStream;
    8: ldc #3          // String One
    10: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    12: goto 13


    // case 2 (fallthrough目標(biāo))
    13: iconst_2
    14: if_icmpne 28   // 如果不等于2,跳轉(zhuǎn)到case 3
    17: getstatic #2   // Field java/lang/System.out:Ljava/io/PrintStream;
    20: ldc #5         // String Two
    22: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    25: goto 40        // 跳轉(zhuǎn)到switch結(jié)束


    // case 3
    28: iconst_3
    29: if_icmpne 40   // 如果不等于3,跳轉(zhuǎn)到結(jié)束
    32: getstatic #2   // Field java/lang/System.out:Ljava/io/PrintStream;
    35: ldc #6         // String Three
    37: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V


    // switch結(jié)束
    40: return

既然沒用為什么還要加這個指令?

class文件是通過Exception table來指定異常處理的指令范圍,而dex文件則是通過為每一行可能產(chǎn)生throwable的指令后面添加FALLTHROUGH指令來實現(xiàn)try-catch。

這里會把每一行可能崩潰的指令都鏈接到catch指令所在的block中,確保任意位置的崩潰都能正常走到catch中。

圖片

問題根因

在R8 4.0.26版本,IRCode翻譯器新增了對FALLTHROUGH指令的處理,即新建一個block并生成一條GOTO指令指向新的block。

圖片圖片

根據(jù)前文的結(jié)論,GOTO指令一樣會被認為是類初始化相關(guān)的邏輯,因此try-catch語句塊一樣會導(dǎo)致最終多出來一個new-instance字節(jié)碼。

為什么只升級AGP會導(dǎo)致R8功能出問題?

我們在數(shù)個版本之前就已經(jīng)單獨升級了R8,正好涵蓋了ApiModel這個變更,但是直到近期才升級了AGP。

可以看到從AGP7.3-beta版本開始,才默認打開ApiModel功能,這就解釋了為什么升級AGP之后才出現(xiàn)此崩潰。

圖片

四、解決方案

禁用ApiModel

ApiModel通過犧牲些微包體,換來啟動階段類驗證耗時,但是從他覆蓋的類范圍來看,對啟動速度的收益微乎其微,因此可以直接通過配置開關(guān)關(guān)閉整個功能。

System.setProperty("com.android.tools.r8.disableApiModeling", "1")

雖說這是個實驗中的功能,且邏輯相對獨立,但是考慮到后續(xù)還有內(nèi)聯(lián)優(yōu)化等操作,貿(mào)然關(guān)閉整個功能無法評估影響面,潛在的穩(wěn)定性風(fēng)險較高。

官方修復(fù)

該問題反饋給R8團隊后,官方提供了臨時規(guī)避的方案,即確保高版本API在單獨的函數(shù)中調(diào)用。

https://issuetracker.google.com/issues/441137561

圖片圖片

隨后不久就提了MR針對SurfaceTexture這個類禁用了ApiModel,并未徹底解決此問題。https://r8-review.googlesource.com/c/r8/+/109044

圖片圖片

官方的修復(fù)方案比較權(quán)威,且影響面較小,但是并未徹底解決問題。

自行修復(fù)

如果要修復(fù)此問題,關(guān)鍵是要將多余的new-instance指令替換成一個合適的觸發(fā)類加載的指令,根據(jù)java官方文檔里的介紹,只有new對象,訪問靜態(tài)的成員變量或者函數(shù)的指令才能安全的觸發(fā)類加載,比較理想的方案是改成訪問靜態(tài)變量,但是很多類并沒有靜態(tài)變量,比如SurfaceTexture就沒有。

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5

圖片

因此我們可以考慮結(jié)合getStatic指令和掃描finalize的方式來解決該問題:

圖片圖片

雖說可以通過打印日志來約束此改動的影響面,但畢竟要自行修改并編譯R8的jar包,且需要自行長期維護,整體影響面還是偏大,對穩(wěn)定性要求高的App不建議采用該方案。

業(yè)務(wù)改造(推薦)

在前文中提到的外聯(lián)函數(shù)生成處打印日志,即可感知到工程中有哪些類受ApiModel影響,如果數(shù)量不多,分別讓業(yè)務(wù)改造其相關(guān)的寫法,確保傳參時是局部變量且無try-catch/synchronized語句塊即可。

圖片

考慮到App整體的穩(wěn)定性,最終我們采用了業(yè)務(wù)改造的方式繞過了此問題,并在R8異常代碼處添加了日志告警來預(yù)防后續(xù)增量問題,并仿照官方MR中的寫法補充了類的黑名單,用于應(yīng)對無法編輯的三方庫引入此問題的場景。

五、總結(jié)

在Android開發(fā)中,即使是AGP、R8這樣的官方工具鏈升級,也要保持足夠的警惕。畢竟Android生態(tài)太過復(fù)雜,再加上開發(fā)者們千奇百怪的代碼寫法,不論多么完善的測試流程都無法規(guī)避這類特定場景的bug。

這次的ApiModel外聯(lián)優(yōu)化問題就是一個很好的例子——它只在特定條件下才會暴露,但一旦出現(xiàn)就是必現(xiàn)的native崩潰。所以對于這種影響面無法評估的重大升級,還是需要經(jīng)過足夠長時間的獨立灰度驗證,才能合入主干分支。

責(zé)任編輯:武曉燕 來源: 得物技術(shù)
相關(guān)推薦

2012-11-26 10:23:08

醫(yī)療大數(shù)據(jù)R統(tǒng)計語言

2015-09-15 10:09:09

TCP網(wǎng)絡(luò)協(xié)議

2018-10-31 14:40:19

TCP協(xié)議ISO

2009-02-05 10:12:00

2022-07-17 12:58:43

Docke技巧

2022-04-06 13:55:22

DockerLinux

2009-04-29 14:46:15

ADSL寬帶掉線

2015-09-06 11:41:15

快碼眾包加速器

2009-01-11 09:29:00

局域網(wǎng)共享撥號

2022-01-20 22:05:19

ChromiumtransformCSS

2010-08-19 09:48:46

IE6

2010-08-26 09:03:05

IE6

2014-06-23 13:59:18

互聯(lián)網(wǎng)電商運營

2019-02-21 09:32:13

MQ中間件SQL

2022-07-28 14:29:38

機器學(xué)習(xí)技術(shù)

2016-08-19 12:59:06

醫(yī)療信息疑難雜癥

2018-11-20 09:25:00

2018-04-11 07:48:16

2021-11-04 15:17:59

網(wǎng)絡(luò)數(shù)據(jù)技術(shù)

2017-11-28 17:09:52

華為云
點贊
收藏

51CTO技術(shù)棧公眾號

天天操天天操天天干| 希岛爱理中文字幕| 黄色精品视频| 亚洲三级久久久| 国产一区二区免费电影| 无码人妻一区二区三区免费| 一个色综合网| 亚洲人成在线电影| 国产毛片久久久久久| 依依综合在线| 一区二区三区在线免费观看| 欧美日本韩国国产| www.成人精品| 日韩1区2区3区| 国语自产在线不卡| 黄色香蕉视频在线观看| 一个色免费成人影院| 日韩一级在线观看| 一区二区在线播放视频| 538在线视频| 亚洲欧美另类图片小说| 日本不卡高清视频一区| 国产77777| 国产一区二区三区观看| 国产精品久久久久久久久久久久久久| 久久久精品国产sm调教| 97人人精品| 亚洲午夜激情免费视频| 国产精品手机在线观看| 99久久香蕉| 欧美一区二区三级| 免费看污污网站| 激情开心成人网| 精品女同一区二区三区在线播放| 潘金莲一级淫片aaaaaa播放1| 国产小视频在线观看| 99久久免费国产| 成人在线观看91| 精品久久久久久亚洲综合网站| 日韩国产精品久久| 国产成人av在线播放| 欧美亚韩一区二区三区| 亚洲视频高清| 欧美激情中文网| 岛国毛片在线观看| 一本一道久久a久久精品蜜桃| 色婷婷久久一区二区| 99精品全国免费观看| 久久超碰99| 亚洲午夜激情免费视频| 亚洲午夜精品久久久久久高潮| 亚洲丝袜啪啪| 亚洲视频第一页| 日本一区二区视频在线播放| 国产综合久久久| 正在播放国产一区| 波多野结衣欲乱| 五月天久久网站| 欧美成人精品xxx| 欧美黄色免费在线观看| 亚洲婷婷在线| 欧美丰满老妇厨房牲生活 | 亚洲欧美日韩在线| 在线观看成人免费| av免费网站在线| 亚洲综合色区另类av| 日韩欧美不卡在线| 日韩伦理精品| 欧美四级电影网| а 天堂 在线| 999久久精品| 日韩精品在线免费观看| 国产视频三区四区| 艳女tv在线观看国产一区| 欧美国产日产韩国视频| 欧美一区二区三区四| 爽好多水快深点欧美视频| 国产精品久久中文| 国产99久一区二区三区a片 | 麻豆精品免费视频| 成人免费av| 欧美国产激情18| 国产一级片毛片| 麻豆精品视频在线观看免费| 亚洲一区免费网站| 亚洲三区在线播放| 国产精品视频麻豆| 精品人妻大屁股白浆无码| 日本不卡免费高清视频在线| 欧美色综合影院| 免费看91视频| 精品国产乱码久久久| 理论片在线不卡免费观看| 亚洲黄色一区二区| 激情综合五月天| 精品一区二区三区视频日产| 免费在线看黄| 色综合天天视频在线观看| 超碰超碰在线观看| 开心激情综合| 久久久国产精品免费| 男人的天堂一区| 国内精品久久久久影院一蜜桃| 好吊妞www.84com只有这里才有精品 | 精品123区| 精品少妇一区二区三区视频免付费 | 午夜激情av在线| 久久资源综合| 久久成人精品视频| av首页在线观看| 不卡的电视剧免费网站有什么| 亚洲五月六月| 欧美xo影院| 精品国产青草久久久久福利| 少妇太紧太爽又黄又硬又爽小说 | 国产又大又黄又粗又爽| 欧美色资源站| 欧美黑人性生活视频| 亚洲天堂手机版| 久久久国产午夜精品| 国产毛片视频网站| 99国内精品久久久久| 国产一区二区精品丝袜| 国产成人在线播放视频| 国产99精品视频| 天堂av免费看| 久久久久久一区二区三区四区别墅| 亚洲精品国产品国语在线| 欧美人与禽zozzo禽性配| 久久丁香综合五月国产三级网站| 日本不卡免费新一二三区| 少妇在线看www| 亚洲成人精品视频在线观看| 四虎免费在线视频| 狠狠色狠狠色综合| 亚洲视频sss| 国产精品久久久久久久久免费高清| 亚洲乱码国产乱码精品精| 亚洲国产综合久久| 成人国产精品免费观看视频| 日本福利视频网站| 亚洲精品在线a| 久久久久久国产免费| www.国产免费| 亚洲线精品一区二区三区八戒| 亚洲视频在线不卡| 亚洲欧美色图| av蓝导航精品导航| a级大胆欧美人体大胆666| 欧美成人免费网站| 久久婷婷一区二区| 不卡的av网站| 日本精品免费在线观看| 偷窥自拍亚洲色图精选| 人九九综合九九宗合| 精品亚洲成a人片在线观看| 色噜噜狠狠色综合中国 | 国产精品成人免费在线| 日韩av在线中文| 911久久香蕉国产线看观看| 91亚洲永久免费精品| 在线观看男女av免费网址| 精品国产污污免费网站入口| 天堂网av手机版| 久久久久久久久一| xxx国产在线观看| 亚洲欧美偷拍自拍| 国产精品国产一区二区| 日韩电影免费看| 伊人久久久久久久久久久久久| 一区二区自拍偷拍| 亚洲综合色丁香婷婷六月图片| 色呦呦一区二区| 日韩国产成人精品| 影音先锋成人资源网站| 国产亚洲成av人片在线观黄桃| 青草青草久热精品视频在线网站 | 亚洲免费伊人电影| 日本黄色动态图| 免费精品视频在线| 一卡二卡三卡视频| 精品国产网站| 91久久大香伊蕉在人线| 亚洲人成午夜免电影费观看| 最近2019中文字幕第三页视频 | 国产精品白丝jk白祙喷水网站| 少妇大叫太大太粗太爽了a片小说| 啪啪激情综合网| 成人www视频在线观看| wwww亚洲| 最近2019中文字幕mv免费看 | 久久影院午夜论| 亚洲天堂伊人网| 亚洲欧美日韩精品一区二区| 91社在线播放| 视频一区在线观看| 国产成人精品福利一区二区三区| 户外露出一区二区三区| 欧美另类69精品久久久久9999| 日本午夜在线视频| 日韩一区二区三区免费看| 国产精品一区无码| 亚洲一区在线看| 免费看的黄色录像| 99精品欧美一区二区蜜桃免费| 在线观看免费不卡av| 老鸭窝91久久精品色噜噜导演| 亚洲国产一二三精品无码| 在线看成人短视频| 国产精品免费区二区三区观看| 精品福利在线| 日本精品在线视频 | 99久久亚洲精品| 免费一区二区三区| 999精品视频在这里| 成人亚洲激情网| 精品三区视频| 日产精品99久久久久久| 川上优av中文字幕一区二区| 久久艹在线视频| 欧美高清视频| 中文字幕最新精品| 国产网站在线播放| 亚洲免费人成在线视频观看| 俄罗斯嫩小性bbwbbw| 7777精品伊人久久久大香线蕉的| 日本丰满少妇做爰爽爽| 一本大道av伊人久久综合| 日本一级淫片色费放| 亚洲自拍偷拍综合| 欧美视频www| 亚洲欧洲精品成人久久奇米网| 国产日韩精品中文字无码| 国产亚洲一区二区三区在线观看| 亚洲av无码一区二区三区网址| 国产美女av一区二区三区| 亚洲在线观看网站| 激情图片小说一区| 福利视频999| 精品在线观看免费| 午夜视频在线观| 国产一区二区三区四| 午夜天堂在线视频| 国内欧美视频一区二区| 性色av浪潮av| 国产不卡免费视频| 女人扒开腿免费视频app| 国产精品99久久久久久有的能看| 日本不卡一区二区在线观看| 精品一区二区久久久| 91丝袜超薄交口足| 国产一区二区三区黄视频 | 久久精品九色| 999视频在线观看| 在线精品国产亚洲| 国产一区精品在线| 天天躁日日躁狠狠躁欧美巨大小说| 久久久久久久久久久久久久一区 | 97精品国产91久久久久久| 黄频免费在线观看| 国产成人精品日本亚洲| 成人精品国产| 亚洲综合大片69999| 大型av综合网站| 日本精品一区| 国产精品麻豆久久| 男人天堂新网址| 亚洲深夜av| 午夜在线观看av| 国产成人自拍高清视频在线免费播放| 国产伦精品一区二区三区88av| jiyouzz国产精品久久| 性欧美精品中出| 亚洲欧洲日韩av| 日韩福利片在线观看| 在线观看亚洲精品视频| 国产精品欧美激情在线| 精品国产1区二区| 久蕉在线视频| 欧美另类交人妖| 黑人巨大精品| 91夜夜揉人人捏人人添红杏| 欧美理伦片在线播放| 亚洲乱码国产乱码精品天美传媒| 夜间精品视频| 少妇人妻互换不带套| 国产一区视频网站| 免费看污黄网站在线观看| 亚洲欧洲精品天堂一级| √资源天堂中文在线| 欧美放荡的少妇| 免费av在线电影| 欧美丰满片xxx777| 国精产品一区一区三区四川| 国产精品乱码一区二区三区| 狠狠综合久久av一区二区蜜桃| 91精品国产吴梦梦| 日韩av一区二| 日本少妇xxxx| 国产精品成人网| 五月天激情四射| 精品国产免费人成在线观看| 不卡在线视频| 2019最新中文字幕| 欧州一区二区三区| 亚洲欧美久久234| 亚洲免费网址| 日本一级大毛片a一| 国产精品白丝在线| 波多野结衣啪啪| 亚洲激情视频网站| 91网址在线观看| 国产精品美女主播| 一区二区三区视频免费观看| 99er在线视频| 国产精品亚洲综合一区在线观看| 少妇av片在线观看| 日韩欧美国产网站| 蜜臀久久99精品久久久| 久久精品国产99国产精品澳门| 日韩免费va| 久久亚洲精品欧美| 伊人影院久久| 日本泡妞xxxx免费视频软件| 日韩毛片高清在线播放| 成人小视频在线播放| 日韩精品在线看| 少妇视频在线观看| 精品国产综合久久| 亚洲精品国产日韩| 中国免费黄色片| 亚洲一区免费视频| 风流老熟女一区二区三区| 欧美大尺度激情区在线播放| 高清在线一区二区| 欧美三级午夜理伦三级老人| 蜜桃av噜噜一区| 又嫩又硬又黄又爽的视频| 欧美亚洲高清一区| wwwxxx在线观看| 91精品国产综合久久久久久久久| 成人羞羞视频在线看网址| 男人插女人下面免费视频| 久久精品人人做| 一级黄色在线观看| 一区二区欧美亚洲| 国产精品xxx| 亚洲AV无码成人精品一区| 精品一区二区三区香蕉蜜桃| 免费三级在线观看| 精品久久人人做人人爰| 24小时免费看片在线观看| 国产91免费视频| 亚洲一区欧美二区| 尤物视频最新网址| 欧美午夜精品久久久久久孕妇| 在线观看免费高清完整| 成人h视频在线| 一区在线免费观看| 亚洲一区二区三区四区五区六区| 色综合色综合色综合| √天堂资源地址在线官网| 91精品国产综合久久香蕉922| 亚洲国产一区二区在线观看| 日本wwww色| 欧美日韩一区二区三区| 春暖花开成人亚洲区| 成人免费福利在线| 精品成人久久| 国精产品一区二区三区| 欧美日韩激情一区| 欧美精品videossex少妇| 精品国产一区二区三区麻豆小说| 乱码第一页成人| 欧美视频一区二区在线| 精品毛片乱码1区2区3区| 伊人久久av| 免费久久久久久| 99精品欧美一区| 91成品人影院| 26uuu久久噜噜噜噜| 色喇叭免费久久综合网| 一级黄色大片免费看| 日韩欧美国产中文字幕| 自拍亚洲图区| 欧美精品与人动性物交免费看| 国产中文字幕一区| 日韩欧美一级视频| 爱福利视频一区| 日韩在线影视| 红桃视频一区二区三区免费| 色综合天天综合色综合av| 天堂av资源在线观看| 欧美在线3区| 成人h版在线观看| 伊人精品一区二区三区| 午夜剧场成人观在线视频免费观看| 日本欧美视频| 国产精品无码在线| 欧美一区二区三区在线观看视频|