999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

一種基于ARM7的嵌入式Java虛擬機(jī)性能優(yōu)化技術(shù)研究

2007-01-01 00:00:00周明天

摘要:分析了Java字節(jié)碼的解釋執(zhí)行和基于解釋執(zhí)行的Direct Threaded Interpreter性能優(yōu)化技術(shù)。以Direct Threaded Interpreter為基礎(chǔ),提出并實(shí)現(xiàn)了一種針對(duì)ARM7平臺(tái)的嵌入式Java虛擬機(jī)解釋器性能優(yōu)化方案。對(duì)嵌入式Java虛擬機(jī)的參考實(shí)現(xiàn)、Direct Threaded Interpreter優(yōu)化方案和新優(yōu)化方案在ARM7平臺(tái)上的性能比較表明,所提出的方案優(yōu)于前兩者。

關(guān)鍵詞:嵌入式Java虛擬機(jī);ARM7;Java字節(jié)碼;直接線索化解釋器

中圖分類號(hào):TP391.9文獻(xiàn)標(biāo)志碼:A

文章編號(hào):1001-3695(2007)05-0097-04

Sun公司于2000年公布的J2ME/MIDP參考實(shí)現(xiàn),采用解釋執(zhí)行字節(jié)碼的Java虛擬機(jī)。與編譯執(zhí)行相比,解釋執(zhí)行的JVM在移動(dòng)通信設(shè)備上具有顯著的優(yōu)點(diǎn):①虛擬機(jī)占用移動(dòng)通信設(shè)備非易失性存儲(chǔ)空間比較??;②虛擬機(jī)運(yùn)行時(shí)占用RAM空間比較小;③解釋執(zhí)行核心代碼量??;④字節(jié)碼占用RAM空間比較小;⑤實(shí)現(xiàn)難度低、可移植性好?,F(xiàn)有的具有J2ME/MIDP支持的移動(dòng)通信設(shè)備大多是基于該參考實(shí)現(xiàn)。

目前針對(duì)Java虛擬機(jī)有多種性能優(yōu)化技術(shù),如基于編譯運(yùn)行的優(yōu)化技術(shù)、基于解釋運(yùn)行的優(yōu)化技術(shù)以及一些針對(duì)內(nèi)存管理與垃圾回收方面的改良算法等。而基于解釋運(yùn)行的優(yōu)化技術(shù)在保持了解釋型虛擬機(jī)結(jié)構(gòu)簡單、可移植性好的優(yōu)點(diǎn)的同時(shí),也有效地提高了解釋型虛擬機(jī)的性能。

基于目前最常用的低功耗32位處理器ARM7及16位總線結(jié)構(gòu)的主流手機(jī)平臺(tái),本文提出并實(shí)現(xiàn)了一個(gè)基于解釋執(zhí)行的嵌入式Java虛擬機(jī)性能優(yōu)化方案。

1Java字節(jié)碼的解釋執(zhí)行

Java字節(jié)碼(Bytecode)在文獻(xiàn)[1]中也被稱為Java虛擬機(jī)指令集(Java Virtual Machine Instruction Set)。與具體的CPU指令集類似,Java字節(jié)碼就是運(yùn)行于Java虛擬機(jī)上的指令集。Java源程序在被執(zhí)行之前,要先被編譯成Java字節(jié)碼,再運(yùn)行于Java虛擬機(jī)上。每條Java字節(jié)碼長度為一個(gè)字節(jié)(8 bits),因此被稱為字節(jié)碼。字節(jié)碼之后可能存在一個(gè)或多個(gè)字節(jié)的操作數(shù)。文獻(xiàn)[2]詳細(xì)定義了所有的標(biāo)準(zhǔn)Java字節(jié)碼。

在Java虛擬機(jī)內(nèi)部,采用了一個(gè)Interpreter來解釋每個(gè)Bytecode的意義。如圖1所示,Interpreter是個(gè)大循環(huán),它一直不停地從PC所指到的內(nèi)存空間抓取Bytecode,翻譯成各種不同作業(yè)平臺(tái)上相對(duì)應(yīng)的操作,并執(zhí)行這些操作。

字節(jié)碼的執(zhí)行流程如下:①為程序計(jì)數(shù)器pc賦初值,進(jìn)入解釋循環(huán)。②Switch指令取出pc指向的字節(jié)碼,將pc加1;根據(jù)字節(jié)碼的值跳轉(zhuǎn)到對(duì)應(yīng)的Case語句。③Case語句后的解釋程序執(zhí)行字節(jié)碼對(duì)應(yīng)的操作。④回到循環(huán)的開頭,如果程序沒有結(jié)束,則進(jìn)行下一次Switch-Case解釋過程。

需要指出,Java字節(jié)碼中大部分堆棧訪問和運(yùn)算指令所執(zhí)行的操作是比較簡單的。這些字節(jié)碼所對(duì)應(yīng)的解釋程序通常只有1~5條C語句,對(duì)應(yīng)的機(jī)器指令通常也只有幾條到十幾條。在這種情況下,Switch-Case的解釋執(zhí)行過程所增加的額外開銷相當(dāng)可觀。從機(jī)器指令的角度來看,Switch-Case的開銷包括:①一次訪存操作,讀入pc指向的字節(jié)碼;②pc加1 操作;③對(duì)字節(jié)碼的值進(jìn)行邊界檢查;④一次訪存操作,查找字節(jié)碼在Switch-Case跳轉(zhuǎn)表中對(duì)應(yīng)的程序段入口;⑤一次跳轉(zhuǎn)操作到對(duì)應(yīng)的Case程序段;⑥在Case程序段執(zhí)行完畢后,再進(jìn)行一次跳轉(zhuǎn)操作,回到循環(huán)開頭??梢钥闯觯琒witch-Case的開銷甚至超過了某些字節(jié)碼解釋程序自身的開銷。這種開銷累積起來,對(duì)執(zhí)行效率的影響相當(dāng)大。

2適合移動(dòng)通信設(shè)備的Direct Threaded Interpreter優(yōu)化技術(shù)

基于解釋運(yùn)行的優(yōu)化技術(shù)主要包括Threaded Interpre-ter[3]、Direct Threaded Interpreter[4]和Inlined Threaded Interpre-ter[5]。有實(shí)驗(yàn)表明[5]:Threaded Interpreter與Switch-Case解釋器相比性能有一定提高,但提高幅度有限,約7%~10%;Inlined Threaded Interpreter與Switch-Case解釋器相比性能有很大提高,約150%~300%,但內(nèi)存占用太大;而Direct Threaded Interpreter較折中,與Switch-Case解釋器相比,性能提高約40%~100%,同時(shí)保持較少的內(nèi)存占用。因此,本文主要考慮Direct Threaded Interpreter。

Threaded可譯為線索化,是指解釋器對(duì)相鄰字節(jié)碼的解釋執(zhí)行過程,通過一定的線索直接聯(lián)系在一起,而不像Switch-Case那樣,每解釋完一條字節(jié)碼都要重新經(jīng)過由Switch進(jìn)行解釋分發(fā)。Direct Threaded Interpreter可以被譯為直接線索化解釋器。

Direct Threaded Interpreter的核心思想為:解釋器在運(yùn)行字節(jié)碼之前把字節(jié)碼數(shù)組翻譯為直接包含字節(jié)碼對(duì)應(yīng)解釋程序入口的Threaded Code數(shù)組。在解釋運(yùn)行時(shí)不再訪問原來的字節(jié)碼數(shù)組,而是直接訪問這個(gè)Threaded Code數(shù)組,只讀入對(duì)應(yīng)的處理程序入口地址。

從字節(jié)碼數(shù)組到Threaded Code數(shù)組的翻譯過程如圖2所示。變換時(shí),在Threaded Code數(shù)組中,將字節(jié)碼操作碼變換成對(duì)應(yīng)處理程序的入口標(biāo)號(hào)地址,操作數(shù)直接復(fù)制。其中,BYTECODE_LABEL表示對(duì)Bytecode對(duì)應(yīng)的解釋程序入口標(biāo)號(hào)BYTECODE_LABEL尋址。

Direct Threaded Interpreter的工作過程為:一個(gè)字節(jié)碼解釋執(zhí)行完畢后,使pc指針指向Threaded Code數(shù)組中下一條字節(jié)碼解釋程序入口標(biāo)號(hào)地址。使用goto *pc語句直接跳轉(zhuǎn)到下一條字節(jié)碼對(duì)應(yīng)解釋程序入口處執(zhí)行,執(zhí)行完后使pc指針指向再下一條。如此往復(fù),直到程序結(jié)束。Direct Threaded Interpreter工作過程的偽碼如下:

與Switch-Case相比,Direct Threaded Interpreter省掉了以下的操作:①每條字節(jié)碼解釋完畢后,到Switch的跳轉(zhuǎn)指令;②讀入pc指向的字節(jié)碼;③Switch在查找跳轉(zhuǎn)表之前對(duì)字節(jié)碼的值進(jìn)行邊界檢查的指令。

考慮到許多常用字節(jié)碼本身的解釋程序就很短(甚至不到10條機(jī)器指令),Direct Threaded Interpreter的優(yōu)化效果是相當(dāng)明顯的。文獻(xiàn)[5]的實(shí)驗(yàn)結(jié)果表明,Direct Threaded Interpre-ter的速度比Switch-Case快40%~100%。不過,由于需要額外的內(nèi)存空間來存放解釋程序的地址數(shù)組,Direct Threaded Interpreter的內(nèi)存開銷要大于Switch-Case(需要約四倍于字節(jié)碼自身大小的內(nèi)存空間)。

3針對(duì)ARM7平臺(tái)的優(yōu)化方案

針對(duì)目前手機(jī)常用的32位CPU——ARM7和16位總線平臺(tái)的特點(diǎn),對(duì)Direct Threaded Interpreter結(jié)構(gòu)進(jìn)行改造;同時(shí)采用一些其他優(yōu)化技術(shù)提出新的優(yōu)化方案,即16 bits Direct Thread Interpreter。本文選擇Sun公司開放源碼的CLDC參考實(shí)現(xiàn)(以下簡稱CLDC RI)作為基礎(chǔ)代碼,在此基礎(chǔ)上實(shí)現(xiàn)本文的優(yōu)化方案。

在32位CPU上,標(biāo)號(hào)地址(類型為void*)長度為32位,占用4 Bytes的存儲(chǔ)器。所以,無論是操作碼還是操作數(shù),在翻譯后都要占用4 Bytes的存儲(chǔ)空間,即Threaded Code是以4 Bytes(32 bits)為一個(gè)單元的。從Direct Threaded Interpreter實(shí)現(xiàn)原理中可以看到,一個(gè)Bytecode單元(8 bits)與一個(gè)Threaded Code單元(32 bits)一一對(duì)應(yīng)。使用Threaded Code,內(nèi)存占用擴(kuò)大為原來的四倍;而且對(duì)于16位總線結(jié)構(gòu)的硬件平臺(tái),每取得一個(gè)單元數(shù)據(jù),均需要兩次訪存。特別對(duì)于操作數(shù),每個(gè)Threaded Code單元只有最后八位是有意義的,其他部分都浪費(fèi)掉了;使用時(shí),還需要數(shù)據(jù)重組。

在字節(jié)碼操作碼方面,Sun公司Java虛擬機(jī)總共包含大約230條字節(jié)碼指令。一條字節(jié)碼所對(duì)應(yīng)的解釋程序本身很短,通常只有1~5條C語句,對(duì)應(yīng)的機(jī)器指令也就只有幾條到十幾條。字節(jié)碼解釋程序入口地址間的跨度不大。實(shí)驗(yàn)表明:16位的整數(shù)足以表示任意兩條字節(jié)碼解釋程序入口標(biāo)號(hào)地址間的偏移量。操作數(shù)方面,可以考慮在翻譯過程中,將操作數(shù)的若干個(gè)字節(jié)碼合并在一條Threaded Code單元中。這樣既節(jié)約空間,又能避免使用時(shí)的數(shù)據(jù)重組,提高了效率。

綜上所述,針對(duì)所采用的ARM7平臺(tái)特點(diǎn),改進(jìn)Direct Threaded Interpreter,制定出一個(gè)16bits Direct Threaded Interpreter優(yōu)化方案。

16 bits Direct Threaded Interpreter中,每一個(gè)Threaded Code單元是16位的。其變換原則為:①將偏移所用的32位基地址保存在一個(gè)寄存器中。②在Threaded Code數(shù)組中,將字節(jié)碼變換成對(duì)應(yīng)處理程序入口標(biāo)號(hào)地址相對(duì)于基地址的偏移量。③操作數(shù)的翻譯:8 bits的操作數(shù)直接翻譯為一個(gè)16 bits的數(shù)保存;16 bits的操作數(shù)整合為一個(gè)16 bits的數(shù)保存;高16位一定為0的32位操作數(shù)整合為一個(gè)16 bits的數(shù)保存;其他32位操作數(shù),整合為兩個(gè)16 bits的數(shù)保存。在解釋運(yùn)行時(shí),直接訪問16 bits Threaded Code數(shù)組,不再訪問字節(jié)碼數(shù)組。通過指向16 bits Threaded Code數(shù)組的tc_pc指針,讀入對(duì)應(yīng)的處理程序入口地址的偏移量,再與寄存器中的基地址相加得到該處理程序入口地址,賦給pc指針。使用goto*pc語句,解釋器跳轉(zhuǎn)到字節(jié)碼對(duì)應(yīng)的解釋程序執(zhí)行。每個(gè)字節(jié)碼解釋執(zhí)行完畢后,tc_pc指針指向Threaded Code數(shù)組中下一條字節(jié)碼解釋程序入口地址的偏移量。翻譯解釋過程如圖3所示。

與Direct Threaded Interpreter相比,16 bits Direct Threaded Interpreter有如下兩個(gè)優(yōu)點(diǎn):①提高效率。取得32位地址,以前需要兩次訪存操作, 現(xiàn)在僅需要一次訪存和一次CPU操作。顯然,訪存操作所用時(shí)間遠(yuǎn)遠(yuǎn)大于CPU操作時(shí)間,在效率上有較大提高。②節(jié)約空間。每個(gè)操作碼的內(nèi)存占用由原來的32 bits減少為16 bits;8 bits的操作數(shù)僅擴(kuò)展為16 bits,減少了16 bits的空間浪費(fèi);16 bits和32 bits的操作數(shù)都不再有空間的浪費(fèi)。內(nèi)存占用只擴(kuò)大了不到兩倍。

以下的偽碼簡單表示了16 bits Direct Threaded Interpreter的翻譯過程:

/*初始化地址偏移量表*/

opcode_entrie_offsets[OPCODE_1] = OPCODE_1_LABEL - base;

opcode_entrie_offsets[OPCODE_2] = OPCODE_2_LABEL - base;

opcode_entrie_offsets[OPCODE_3] = OPCODE_3_LABEL - base;

…

/*將字節(jié)碼翻譯為16 bits Threaded Code */

uint8*pc = bytecodes[];

int bytecodes_length = length of bytecodes;

short*tc_pc = threadedCodes[];

while (bytecodes_length—) {

if (IS_OPCODE(*pc)) { /* 該字節(jié)是操作碼*/

swith(*pc){

case OPCODE_NO_OPERAND :

/* 屬于無操作數(shù)的字節(jié)碼操作碼 */

*tc_pc = opcode_entrie_offsets[*pc];

/* 操作碼翻譯為解釋程序入口地址偏移量*/

tc_pc++; /*調(diào)整指針 */

pc++;

break;

case OPCODE_1_OPERAND:

/* 屬于有1 Byte操作數(shù)的字節(jié)碼操作碼 */

*tc_pc = opcode_entrie_offsets[*pc];

/* 操作碼翻譯為解釋程序入口地址偏移量*/

*(tc_pc + 1) =*(pc + 1);

/* 處理操作數(shù),一個(gè)8 bits操作數(shù),直接拷貝 */

bytecodes_length—;

tc_pc += 2; /* 調(diào)整指針 */

pc += 2;

break;

case OPCODE_2_OPERAND :

/*屬于有2 Bytes操作數(shù)的字節(jié)碼操作碼 */

*tc_pc = opcode_entrie_offsets[*pc];

*(tc_pc + 1) = ((unsigned short)(*(pc + 1)) << 8) | ((unsigned short)(*(pc + 2)));

/* 處理操作數(shù),一個(gè)16 bits操作數(shù),整合*/

bytecodes_length-= 2;

tc_pc +=2;/* 調(diào)整指針*/

pc +=3;

break;

case OPCODE_3_OPERAND:

/*屬于有3 Bytes操作數(shù)的字節(jié)碼操作碼 */

...

case OPCODE_N_OPERAND:

/*屬于有N Bytes操作數(shù)的字節(jié)碼操作碼 */

…

}

} else {

…/* 該字節(jié)非操作碼的參數(shù)*/

}

}

翻譯程序按順序讀入每一個(gè)字節(jié)碼,查找其對(duì)應(yīng)的解釋程序入口地址偏移量,再將偏移量寫入Threaded Code數(shù)組中,并處理后續(xù)操作數(shù)。

顯而易見,本文的翻譯對(duì)操作數(shù)進(jìn)行合并處理,使得字節(jié)碼數(shù)組與Threaded Code數(shù)組的下標(biāo)不再具有一一對(duì)應(yīng)關(guān)系。對(duì)順序執(zhí)行的字節(jié)碼而言,這種變化沒有影響,但對(duì)于進(jìn)行相對(duì)地址跳轉(zhuǎn)的字節(jié)碼而言,情況就發(fā)生了變化。以圖3為例,假設(shè)字節(jié)碼數(shù)組中下標(biāo)為2的OPCODE_2是一條跳轉(zhuǎn)指令,其后的操作數(shù)是相對(duì)地址,值為8,則OPCODE_2的執(zhí)行結(jié)果為跳轉(zhuǎn)到下標(biāo)為10的指令處。而在Threaded Code中,OPCODE_2的解釋程序則應(yīng)該跳轉(zhuǎn)到對(duì)應(yīng)的指令,即下標(biāo)為7的Threaded Code處。因此,在對(duì)跳轉(zhuǎn)指令進(jìn)行翻譯時(shí),必須對(duì)操作數(shù)進(jìn)行調(diào)整。

這里采取的方法是兩次掃描,即通過兩次掃描實(shí)現(xiàn)字節(jié)碼到Threaded Code的翻譯。第一次掃描將Java字節(jié)碼指令翻譯為Threaded Code,并將字節(jié)碼偏移量與Threaded Code偏移量的對(duì)應(yīng)關(guān)系保存在一個(gè)數(shù)組中;第二次掃描則根據(jù)該偏移量對(duì)應(yīng)關(guān)系數(shù)組來處理Threaded Code中的分支和跳轉(zhuǎn)地址。圖4表示了第一次翻譯過程的結(jié)果,圖中深色背景的單元格表示數(shù)組下標(biāo)。tcode_offset[]數(shù)組中保存了字節(jié)碼數(shù)組和Threaded Code數(shù)組的下標(biāo)對(duì)應(yīng)關(guān)系,tcode_offset[m]=n表示字節(jié)碼中偏移量為m的指令對(duì)應(yīng)Threaded Code中偏移量為n的指令。

第二次掃描過程尋找Threaded Code中的跳轉(zhuǎn)指令,根據(jù)tcode_offset[]數(shù)組保存的對(duì)應(yīng)關(guān)系來修改分支轉(zhuǎn)移指令的操作數(shù)。如上例中,在第二次掃描發(fā)現(xiàn)BYTECODE_2是跳轉(zhuǎn)指令,取得其跳轉(zhuǎn)的相對(duì)偏移為8,原字節(jié)碼的跳轉(zhuǎn)目的為10。tcode_offset的序號(hào)與Bytecode的序號(hào)是一一對(duì)應(yīng)的,通過tcode_offset找到BYTECODE_2及其跳轉(zhuǎn)目的10在Threaded Code數(shù)組中對(duì)應(yīng)的序號(hào)位置,分別為2和7。最后,將Threaded Code數(shù)組中序號(hào)為2的Threaded Code單元之后的操作數(shù)改為5。到此,BYTECODE_2這條跳轉(zhuǎn)指令的相對(duì)跳轉(zhuǎn)地址修改完畢,繼續(xù)查看下一條指令是否為跳轉(zhuǎn)指令。

這樣,通過兩次掃描就完成了字節(jié)碼到Threaded Code的翻譯過程。

在此基礎(chǔ)上,本文還采取了一些其他優(yōu)化措施,如字節(jié)碼合并、可拋棄Threaded Code、調(diào)整解釋程序的排列順序等。字節(jié)碼合并主要包括:將某些不指定操作數(shù)類型的指令細(xì)分并改寫為針對(duì)特定類型的指令;將常量操作數(shù)直接嵌入在Threaded Code中,減少一次查表的開銷;合并某些功能相近或相同的指令??蓲仐塗hreaded Code是采用LRU(最近最久未用)表來管理專門用于存放Threaded Code的內(nèi)存空間,進(jìn)一步降低Threaded Code的內(nèi)存占用。此外,Java虛擬機(jī)中定義的指令在Java程序中出現(xiàn)的頻率是不一樣的。將使用頻率高的指令解釋程序安排在相鄰的地址空間中,提高CPU指令Cache的命中率,進(jìn)而改善虛擬機(jī)性能。

4性能比較

本文使用JBenchmark 2.0以及自行編寫的綜合測試案例,對(duì)運(yùn)行在ARM7、16位總線的手機(jī)平臺(tái)上的KVM進(jìn)行了多次測試。為了比較與Direct Threaded Interpreter的性能差異,將之前實(shí)現(xiàn)的基于Direct Threaded Interpreter優(yōu)化的KVM加入測試。表1列出了每組測試結(jié)果的平均值。其中,JBenchmark 2.0針對(duì)MIDP 2.0檢測第二代Java設(shè)備的圖像表現(xiàn)力,有五個(gè)小的測試項(xiàng)目,每個(gè)10 s。自行編寫的測試案例包含大量的循環(huán)、整數(shù)乘除法運(yùn)算、對(duì)象分配和虛方法調(diào)用。

從JBenchmark 2.0的分?jǐn)?shù)來看,采用了該優(yōu)化方案的KVM的性能比RI和基于Direct Threaded Interpreter的KVM都要高;內(nèi)存的占用也比基于Direct Threaded Interpreter的版本減少了。從測試案例的結(jié)果進(jìn)行估算,采用本文優(yōu)化方案的KVM的性能比RI高出約69%,比基于Direct Threaded Interpreter的版本高出約8%。

5結(jié)束語

本文介紹了Java字節(jié)碼的解釋執(zhí)行, 詳細(xì)分析了Direct Threaded Interpreter優(yōu)化技術(shù)。在此基礎(chǔ)上,針對(duì)目前最常用的ARM7、16位總線的手機(jī)平臺(tái)提出并實(shí)現(xiàn)了一種改良的解釋器優(yōu)化方案,即16 bits Direct Threaded Interpreter。文中對(duì)16 bits Direct Threaded Interpreter優(yōu)化方案進(jìn)行了詳細(xì)描述,并對(duì)Direct Threaded Interpreter及CLDC RI進(jìn)行了性能對(duì)比工作。通過性能對(duì)比,說明了采用本優(yōu)化方案能使Java虛擬機(jī)解釋器性能得到比較顯著的提高。

參考文獻(xiàn):

[1]LINDHOLM T,YELLIN F. The JavaTM virtual machine specification[EB/OL].2nd ed.(1999).http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html.

[2]ADL-TABATABAI A R,CIERNAK M,LUEH G Y,et al.Fast, effective code generation in a justin-time Java compiler:proc.of the ACM SIGPLAN Conference on Programming Language Design and Implementation[C].Montreal:[s.n.],1998.

[3]BELL J R. Threaded code[J].Communications of the ACM,1973,16(6),370-372.

[4]ERTL M A. A portable 4th engine:proc.of the EuroFORTH Confe-rence[C].Marienbad:[s.n.],1993:253-257. 

[5]PIUMARTA I, RICCARDI F.Optimizing direct threaded code by selective inlining:proc. of the ACM SIGPLAN Conference on Programming Language Design and Implementation[C].Montreal:[s.n.],1998:291-300.

注:“本文中所涉及到的圖表、注解、公式等內(nèi)容請(qǐng)以PDF格式閱讀原文”

主站蜘蛛池模板: 55夜色66夜色国产精品视频| A级毛片高清免费视频就| 蜜臀av性久久久久蜜臀aⅴ麻豆| 97久久精品人人| 香蕉伊思人视频| 国产精品护士| 又粗又硬又大又爽免费视频播放| 黄色在线不卡| 女人18一级毛片免费观看| 中文字幕乱码二三区免费| 91在线播放国产| 欧美国产日韩在线播放| 午夜免费小视频| 女人18毛片一级毛片在线 | 99九九成人免费视频精品| 99热这里都是国产精品| 操国产美女| 国产主播福利在线观看| 久久天天躁狠狠躁夜夜2020一| 国产精品99久久久久久董美香| 天天综合色网| 国产亚洲欧美另类一区二区| 在线综合亚洲欧美网站| 欧美成人aⅴ| 欧美日本在线观看| 一本无码在线观看| 91精品情国产情侣高潮对白蜜| 国产高清在线丝袜精品一区| 精品少妇人妻无码久久| 国产精品观看视频免费完整版| 重口调教一区二区视频| 99无码中文字幕视频| 免费又爽又刺激高潮网址 | 免费看黄片一区二区三区| 国产农村1级毛片| 久热中文字幕在线| 欧美精品一二三区| 三级国产在线观看| 国产精品亚欧美一区二区| 性激烈欧美三级在线播放| 丰满的熟女一区二区三区l| 国产亚洲成AⅤ人片在线观看| 亚洲人成网站18禁动漫无码| 毛片一级在线| 国产白浆在线| 一级全黄毛片| 无码视频国产精品一区二区| 高清码无在线看| 91探花国产综合在线精品| 亚欧美国产综合| 欧美一区二区精品久久久| 91网站国产| 狠狠亚洲婷婷综合色香| 91在线播放免费不卡无毒| 亚洲精品你懂的| 永久毛片在线播| 国产91特黄特色A级毛片| a毛片免费在线观看| 亚洲中文字幕在线一区播放| 宅男噜噜噜66国产在线观看| 91精品国产情侣高潮露脸| 99国产在线视频| 99精品高清在线播放| 国产毛片不卡| 国产手机在线ΑⅤ片无码观看| 日本欧美一二三区色视频| 欧美亚洲第一页| 免费在线看黄网址| 亚洲精品国产精品乱码不卞| 国产精品乱偷免费视频| 91亚瑟视频| 国产亚洲欧美在线中文bt天堂| 久久精品人妻中文系列| 日韩麻豆小视频| 三级欧美在线| 四虎成人精品在永久免费| 久久久久人妻一区精品| 91日本在线观看亚洲精品| 狠狠色香婷婷久久亚洲精品| 正在播放久久| 粗大猛烈进出高潮视频无码| 免费无码又爽又黄又刺激网站|