成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript是如何工作的:深入V8引擎&編寫(xiě)優(yōu)化代碼的5個(gè)技巧

Turbo / 3056人閱讀

摘要:第二篇文章將深入谷歌的引擎的內(nèi)部。引擎可以實(shí)現(xiàn)為標(biāo)準(zhǔn)解釋器,或者以某種形式將編譯為字節(jié)碼的即時(shí)編譯器。這個(gè)引擎是在谷歌中使用的,但是,與其他引擎不同的是也用于流行的。一種更復(fù)雜的優(yōu)化編譯器,生成高度優(yōu)化的代碼。不是唯一能夠做到的引擎。

本系列的 第一篇文章 主要介紹引擎、運(yùn)行時(shí)和調(diào)用堆棧。第二篇文章將深入谷歌 V8 的JavaScript引擎的內(nèi)部。

想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你!

概述

JavaScript引擎是執(zhí)行 JavaScript 代碼的程序或解釋器。JavaScript引擎可以實(shí)現(xiàn)為標(biāo)準(zhǔn)解釋器,或者以某種形式將JavaScript編譯為字節(jié)碼的即時(shí)編譯器。

以為實(shí)現(xiàn)JavaScript引擎的流行項(xiàng)目的列表:

V8?—?開(kāi)源,由 Google 開(kāi)發(fā),用 C ++ 編寫(xiě)

Rhino?—?由 Mozilla 基金會(huì)管理,開(kāi)源,完全用 Java 開(kāi)發(fā)

SpiderMonkey?—?是第一個(gè)支持 Netscape Navigator 的 JavaScript 引擎,目前正供 Firefox 使用

JavaScriptCore —?開(kāi)源,以Nitro形式銷(xiāo)售,由蘋(píng)果為Safari開(kāi)發(fā)

KJS?—?KDE 的引擎,最初由 Harri Porten 為 KDE 項(xiàng)目中的 Konqueror 網(wǎng)頁(yè)瀏覽器開(kāi)發(fā)

Chakra (JScript9)?—?Internet Explorer

Chakra (JavaScript)?—?Microsoft Edge

Nashorn, 作為 OpenJDK 的一部分,由 Oracle Java 語(yǔ)言和工具組編寫(xiě)

JerryScript?—? 物聯(lián)網(wǎng)的輕量級(jí)引擎

為什么要?jiǎng)?chuàng)建V8引擎?

由谷歌構(gòu)建的V8引擎是開(kāi)源的,使用c++編寫(xiě)。這個(gè)引擎是在谷歌Chrome中使用的,但是,與其他引擎不同的是 V8 也用于流行的 node.js。

V8最初被設(shè)計(jì)用來(lái)提高web瀏覽器中JavaScript執(zhí)行的性能。為了獲得速度,V8 將 JavaScript 代碼轉(zhuǎn)換成更高效的機(jī)器碼,而不是使用解釋器。它通過(guò)實(shí)現(xiàn) JIT (Just-In-Time) 編譯器將 JavaScript 代碼編譯為執(zhí)行時(shí)的機(jī)器碼,就像許多現(xiàn)代 JavaScript 引擎(如SpiderMonkey或Rhino (Mozilla)) 所做的那樣。這里的主要區(qū)別是 V8 不生成字節(jié)碼或任何中間代碼。

V8 曾有兩個(gè)編譯器

在 V8 的 5.9 版本出來(lái)之前,V8 引擎使用了兩個(gè)編譯器:

full-codegen?—?一個(gè)簡(jiǎn)單和非常快的編譯器,產(chǎn)生簡(jiǎn)單和相對(duì)較慢的機(jī)器碼。

Crankshaft?— 一種更復(fù)雜(Just-In-Time)的優(yōu)化編譯器,生成高度優(yōu)化的代碼。

V8 引擎也在內(nèi)部使用多個(gè)線(xiàn)程:

主線(xiàn)程執(zhí)行你所期望的操作:獲取代碼、編譯代碼并執(zhí)行它

還有一個(gè)多帶帶的線(xiàn)程用于編譯,因此主線(xiàn)程可以在前者優(yōu)化代碼的同時(shí)繼續(xù)執(zhí)行

一個(gè) Profiler 線(xiàn)程,它會(huì)告訴運(yùn)行時(shí)我們花了很多時(shí)間,讓 Crankshaft 可以?xún)?yōu)化它們

一些線(xiàn)程處理垃圾收集器

當(dāng)?shù)谝淮螆?zhí)行 JavaScript 代碼時(shí),V8 利用 full-codegen 編譯器,直接將解析的 JavaScript 翻譯成機(jī)器代碼而不進(jìn)行任何轉(zhuǎn)換。這使得它可以非??焖俚亻_(kāi)始執(zhí)行機(jī)器代碼。請(qǐng)注意,V8 不使用中間字節(jié)碼,從而不需要解釋器。

當(dāng)代碼已經(jīng)運(yùn)行一段時(shí)間后,分析線(xiàn)程已經(jīng)收集了足夠的數(shù)據(jù)來(lái)判斷應(yīng)該優(yōu)化哪個(gè)方法。

接下來(lái),Crankshaft? 從另一個(gè)線(xiàn)程開(kāi)始優(yōu)化。它將 JavaScript 抽象語(yǔ)法樹(shù)轉(zhuǎn)換為被稱(chēng)為 Hydrogen 的高級(jí)靜態(tài)單分配(SSA)表示,并嘗試優(yōu)化 Hydrogen 圖,大多數(shù)優(yōu)化都是在這個(gè)級(jí)別完成的。

內(nèi)聯(lián)代碼

第一個(gè)優(yōu)化是提前內(nèi)聯(lián)盡可能多的代碼。內(nèi)聯(lián)是用被調(diào)用函數(shù)的主體替換調(diào)用點(diǎn)(調(diào)用函數(shù)的代碼行)的過(guò)程。這個(gè)簡(jiǎn)單的步驟允許下面的優(yōu)化更有意義。

隱藏類(lèi)

JavaScript是一種基于原型的語(yǔ)言:沒(méi)有使用克隆過(guò)程創(chuàng)建類(lèi)和對(duì)象。JavaScript也是一種動(dòng)態(tài)編程語(yǔ)言,這意味著可以在實(shí)例化后輕松地在對(duì)象中添加或刪除屬性。

大多數(shù) JavaScript 解釋器使用類(lèi)似字典的結(jié)構(gòu)(基于哈希函數(shù))來(lái)存儲(chǔ)對(duì)象屬性值在內(nèi)存中的位置,這種結(jié)構(gòu)使得在 JavaScript 中檢索屬性的值比在 Java 或 C# 等非動(dòng)態(tài)編程語(yǔ)言中的計(jì)算成本更高。

在Java中,所有對(duì)象屬性都是在編譯之前由固定對(duì)象布局確定的,并且無(wú)法在運(yùn)行時(shí)動(dòng)態(tài)添加或刪除(當(dāng)然,C#具有動(dòng)態(tài)類(lèi)型,這是另一個(gè)主題)。

因此,屬性值(或指向這些屬性的指針)可以作為連續(xù)緩沖區(qū)存儲(chǔ)在存儲(chǔ)器中,每個(gè)緩沖區(qū)之間具有固定偏移量, 可以根據(jù)屬性類(lèi)型輕松確定偏移的長(zhǎng)度,而在運(yùn)行時(shí)可以更改屬性類(lèi)型的 JavaScript 中這是不可能的。

由于使用字典查找內(nèi)存中對(duì)象屬性的位置效率非常低,因此 V8 使用了不同的方法:隱藏類(lèi)。隱藏類(lèi)與 Java 等語(yǔ)言中使用的固定對(duì)象(類(lèi))的工作方式類(lèi)似,只是它們是在運(yùn)行時(shí)創(chuàng)建的?,F(xiàn)在,讓我們看看他們實(shí)際的例子:

一旦 “new Point(1,2)” 調(diào)用發(fā)生,V8 將創(chuàng)建一個(gè)名為 “C0” 的隱藏類(lèi)。

尚未為 Point 定義屬性,因此“C0”為空。

一旦第一個(gè)語(yǔ)句“this.x = x”被執(zhí)行(在“Point”函數(shù)內(nèi)),V8 將創(chuàng)建一個(gè)名為 “C1” 的第二個(gè)隱藏類(lèi),它基于“C0”。 “C1”描述了可以找到屬性 x 的存儲(chǔ)器中的位置(相對(duì)于對(duì)象指針)。

在這種情況下,“x”存儲(chǔ)在偏移0處,這意味著當(dāng)將存儲(chǔ)器中的 point 對(duì)象視為連續(xù)緩沖區(qū)時(shí),第一偏移將對(duì)應(yīng)于屬性 “x”。 V8 還將使用 “類(lèi)轉(zhuǎn)換” 更新 “C0” ,該類(lèi)轉(zhuǎn)換指出如果將屬性 “x” 添加到 point 對(duì)象,則隱藏類(lèi)應(yīng)從 “C0” 切換到 “C1”。 下面的 point 對(duì)象的隱藏類(lèi)現(xiàn)在是“C1”。

每次將新屬性添加到對(duì)象時(shí),舊的隱藏類(lèi)都會(huì)更新為指向新隱藏類(lèi)的轉(zhuǎn)換路徑。隱藏類(lèi)轉(zhuǎn)換非常重要,因?yàn)樗鼈冊(cè)试S在以相同方式創(chuàng)建的對(duì)象之間共享隱藏類(lèi)。如果兩個(gè)對(duì)象共享一個(gè)隱藏類(lèi)并且同一屬性被添加到它們中,則轉(zhuǎn)換將確保兩個(gè)對(duì)象都接收相同的新隱藏類(lèi)以及隨其附帶的所有優(yōu)化代碼。

當(dāng)語(yǔ)句 “this.y = y” 被執(zhí)行時(shí),會(huì)重復(fù)同樣的過(guò)程(在 “Point” 函數(shù)內(nèi)部,“this.x = x”語(yǔ)句之后)。

一個(gè)名為“C2”的新隱藏類(lèi)會(huì)被創(chuàng)建,如果將一個(gè)屬性 “y” 添加到一個(gè) Point 對(duì)象(已經(jīng)包含屬性“x”),一個(gè)類(lèi)轉(zhuǎn)換會(huì)添加到“C1”,則隱藏類(lèi)應(yīng)該更改為“C2”,point 對(duì)象的隱藏類(lèi)更新為“C2”。

隱藏類(lèi)轉(zhuǎn)換取決于將屬性添加到對(duì)象的順序。看看下面的代碼片段:

現(xiàn)在,假設(shè)對(duì)于p1和p2,將使用相同的隱藏類(lèi)和轉(zhuǎn)換。那么,對(duì)于“p1”,首先添加屬性“a”,然后添加屬性“b”。然而,“p2”首先分配“b”,然后是“a”。因此,由于不同的轉(zhuǎn)換路徑,“p1”和“p2”以不同的隱藏類(lèi)別結(jié)束。在這種情況下,以相同的順序初始化動(dòng)態(tài)屬性好得多,以便隱藏的類(lèi)可以被重用。

內(nèi)聯(lián)緩存

V8利用了另一種優(yōu)化動(dòng)態(tài)類(lèi)型語(yǔ)言的技術(shù),稱(chēng)為內(nèi)聯(lián)緩存。內(nèi)聯(lián)緩存依賴(lài)于這樣一種觀(guān)察,即對(duì)同一方法的重復(fù)調(diào)用往往發(fā)生在同一類(lèi)型的對(duì)象上。這里可以找到對(duì)內(nèi)聯(lián)緩存的深入解釋。

接下來(lái)將討論內(nèi)聯(lián)緩存的一般概念(如果您沒(méi)有時(shí)間通過(guò)上面的深入了解)。

那么它是如何工作的呢? V8 維護(hù)了在最近的方法調(diào)用中作為參數(shù)傳遞的對(duì)象類(lèi)型的緩存,并使用這些信息預(yù)測(cè)將來(lái)作為參數(shù)傳遞的對(duì)象類(lèi)型。如果 V8 能夠很好地預(yù)測(cè)傳遞給方法的對(duì)象的類(lèi)型,它就可以繞過(guò)如何訪(fǎng)問(wèn)對(duì)象屬性的過(guò)程,而是使用從以前的查找到對(duì)象的隱藏類(lèi)的存儲(chǔ)信息。

那么隱藏類(lèi)和內(nèi)聯(lián)緩存的概念如何相關(guān)呢?無(wú)論何時(shí)在特定對(duì)象上調(diào)用方法時(shí),V8 引擎都必須執(zhí)行對(duì)該對(duì)象的隱藏類(lèi)的查找,以確定訪(fǎng)問(wèn)特定屬性的偏移量。在同一個(gè)隱藏類(lèi)的兩次成功的調(diào)用之后,V8 省略了隱藏類(lèi)的查找,并簡(jiǎn)單地將該屬性的偏移量添加到對(duì)象指針本身。對(duì)于該方法的所有下一次調(diào)用,V8 引擎都假定隱藏的類(lèi)沒(méi)有更改,并使用從以前的查找存儲(chǔ)的偏移量直接跳轉(zhuǎn)到特定屬性的內(nèi)存地址。這大大提高了執(zhí)行速度。

內(nèi)聯(lián)緩存也是為什么相同類(lèi)型的對(duì)象共享隱藏類(lèi)非常重要的原因。 如果你創(chuàng)建兩個(gè)相同類(lèi)型和不同隱藏類(lèi)的對(duì)象(正如我們之前的例子中所做的那樣),V8將無(wú)法使用內(nèi)聯(lián)緩存,因?yàn)榧词惯@兩個(gè)對(duì)象屬于同一類(lèi)型,它們對(duì)應(yīng)的隱藏類(lèi)為其屬性分配不同的偏移量。

這兩個(gè)對(duì)象基本相同,但是“a”和“b”屬性的創(chuàng)建順序不同。
編譯成機(jī)器碼

一旦 Hydrogen 圖被優(yōu)化,Crankshaft 將其降低到稱(chēng)為 Lithium 的較低級(jí)表示。大部分的 Lithium 實(shí)現(xiàn)都是特定于架構(gòu)的。寄存器分配往往發(fā)生在這個(gè)級(jí)別。

最后,Lithium 被編譯成機(jī)器碼。然后就是 OSR :on-stack replacement(堆棧替換)。在我們開(kāi)始編譯和優(yōu)化一個(gè)明確的長(zhǎng)期運(yùn)行的方法之前,我們可能會(huì)運(yùn)行堆棧替換。 V8 不只是緩慢執(zhí)行堆棧替換,并再次開(kāi)始優(yōu)化。相反,它會(huì)轉(zhuǎn)換我們擁有的所有上下文(堆棧,寄存器),以便在執(zhí)行過(guò)程中切換到優(yōu)化版本上。這是一個(gè)非常復(fù)雜的任務(wù),考慮到除了其他優(yōu)化之外,V8 最初還將代碼內(nèi)聯(lián)。 V8 不是唯一能夠做到的引擎。

有一種叫去優(yōu)化的安全措施來(lái)進(jìn)行相反的轉(zhuǎn)換,并在假設(shè)引擎無(wú)效的情況下返回未優(yōu)化的代碼。

垃圾收集

對(duì)于垃圾收集,V8采用傳統(tǒng)的 mark-and-sweep 算法 來(lái)清理舊一代。 標(biāo)記階段應(yīng)該停止JavaScript執(zhí)行。 為了控制GC成本并使執(zhí)行更穩(wěn)定,V8使用增量標(biāo)記:不是遍歷整個(gè)堆,嘗試標(biāo)記每個(gè)可能的對(duì)象,它只是遍歷堆的一部分,然后恢復(fù)正常執(zhí)行。下一個(gè)GC停止將從上一個(gè)堆行走停止的位置繼續(xù),這允許在正常執(zhí)行期間非常短暫的暫停,如前所述,掃描階段由多帶帶的線(xiàn)程處理。

如何編寫(xiě)優(yōu)化的 JavaScript

對(duì)象屬性的順序:始終以相同的順序?qū)嵗瘜?duì)象屬性,以便可以共享隱藏的類(lèi)和隨后優(yōu)化的代碼。

動(dòng)態(tài)屬性: 因?yàn)樵趯?shí)例化之后向?qū)ο筇砑訉傩詫?qiáng)制執(zhí)行隱藏的類(lèi)更改,并降低之前隱藏類(lèi)所優(yōu)化的所有方法的執(zhí)行速度,所以在其構(gòu)造函數(shù)中分配所有對(duì)象的屬性。

方法:重復(fù)執(zhí)行相同方法的代碼將比僅執(zhí)行一次的多個(gè)不同方法(由于內(nèi)聯(lián)緩存)的代碼運(yùn)行得更快。

數(shù)組:避免稀疏數(shù)組,其中鍵值不是自增的數(shù)字,并沒(méi)有存儲(chǔ)所有元素的稀疏數(shù)組是哈希表。這種數(shù)組中的元素訪(fǎng)問(wèn)開(kāi)銷(xiāo)較高。另外,盡量避免預(yù)分配大數(shù)組。最好是按需增長(zhǎng)。最后,不要?jiǎng)h除數(shù)組中的元素,這會(huì)使鍵值變得稀疏。

標(biāo)記值:V8 使用 32 位表示對(duì)象和數(shù)值。由于數(shù)值是 31 位的,它使用了一位來(lái)區(qū)分它是一個(gè)對(duì)象(flag = 1)還是一個(gè)稱(chēng)為 SMI(SMall Integer)整數(shù)(flag = 0)。那么,如果一個(gè)數(shù)值大于 31 位,V8會(huì)將該數(shù)字裝箱,把它變成一個(gè)雙精度數(shù),并創(chuàng)建一個(gè)新的對(duì)象來(lái)存放該數(shù)字。盡可能使用 31 位有符號(hào)數(shù)字,以避免對(duì) JS 對(duì)象的高開(kāi)銷(xiāo)的裝箱操作。

Ignition and TurboFan

隨著2017年早些時(shí)候發(fā)布V8 5.9,引入了新的執(zhí)行管道。 這個(gè)新的管道在實(shí)際的JavaScript應(yīng)用程序中實(shí)現(xiàn)了更大的性能提升和顯著節(jié)省內(nèi)存。

新的執(zhí)行流程是建立在 Ignition( V8 的解釋器)和 TurboFan( V8 的最新優(yōu)化編譯器)之上的。

自從 V8 5.9 版本問(wèn)世以來(lái),由于 V8 團(tuán)隊(duì)一直努力跟上新的 JavaScript 語(yǔ)言特性以及這些特性所需要的優(yōu)化,V8 團(tuán)隊(duì)已經(jīng)不再使用 full-codegen 和 Crankshaft(自 2010 年以來(lái)為 V8 技術(shù)所服務(wù))。

這意味著 V8 整體上將有更簡(jiǎn)單和更易維護(hù)的架構(gòu)。

這些改進(jìn)只是一個(gè)開(kāi)始。 新的Ignition和TurboFan管道為進(jìn)一步優(yōu)化鋪平了道路,這些優(yōu)化將在未來(lái)幾年內(nèi)提升JavaScript性能并縮小V8在Chrome和Node.js中的占用空間。

原文:https://blog.sessionstack.com...

你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!

交流

干貨系列文章匯總?cè)缦拢X(jué)得不錯(cuò)點(diǎn)個(gè)Star,歡迎 加群 互相學(xué)習(xí)。

https://github.com/qq44924588...

我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛(ài)好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!

關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/54694.html

相關(guān)文章

  • JavaScript如何工作深入V8引擎&編寫(xiě)優(yōu)化代碼5個(gè)技巧

    摘要:第二篇文章將深入谷歌的引擎的內(nèi)部。引擎可以實(shí)現(xiàn)為標(biāo)準(zhǔn)解釋器,或者以某種形式將編譯為字節(jié)碼的即時(shí)編譯器。這個(gè)引擎是在谷歌中使用的,但是,與其他引擎不同的是也用于流行的。一種更復(fù)雜的優(yōu)化編譯器,生成高度優(yōu)化的代碼。不是唯一能夠做到的引擎。 本系列的 第一篇文章 主要介紹引擎、運(yùn)行時(shí)和調(diào)用堆棧。第二篇文章將深入谷歌 V8 的JavaScript引擎的內(nèi)部。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHu...

    DevWiki 評(píng)論0 收藏0
  • JavaScript 工作原理之二-如何V8 引擎中書(shū)寫(xiě)最優(yōu)代碼 5 條小技巧(譯)

    摘要:本章將會(huì)深入谷歌引擎的內(nèi)部結(jié)構(gòu)。一個(gè)引擎可以用標(biāo)準(zhǔn)解釋程序或者即時(shí)編譯器來(lái)實(shí)現(xiàn),即時(shí)編譯器即以某種形式把解釋為字節(jié)碼。引擎的由來(lái)引擎是由谷歌開(kāi)源并以語(yǔ)言編寫(xiě)。注意到?jīng)]有使用中間字節(jié)碼來(lái)表示,這樣就不需要解釋器了。 原文請(qǐng)查閱這里,略有刪減。 本系列持續(xù)更新中,Github 地址請(qǐng)查閱這里。 這是 JavaScript 工作原理的第二章。 本章將會(huì)深入谷歌 V8 引擎的內(nèi)部結(jié)構(gòu)。我們也會(huì)...

    PingCAP 評(píng)論0 收藏0
  • [譯文] JavaScript工作原理:V8引擎內(nèi)部+5優(yōu)化代碼竅門(mén)

    摘要:本文將會(huì)深入分析的引擎的內(nèi)部實(shí)現(xiàn)。該引擎使用在谷歌瀏覽器內(nèi)部。同其他現(xiàn)代引擎如或所做的一樣,通過(guò)實(shí)現(xiàn)即時(shí)編譯器在執(zhí)行時(shí)將代碼編譯成機(jī)器代碼。這可使正常執(zhí)行期間只發(fā)生相當(dāng)短的暫停。 原文 How JavaScript works: inside the V8 engine + 5 tips on how to write optimized code 幾周前我們開(kāi)始了一個(gè)系列博文旨在深入...

    dreamans 評(píng)論0 收藏0
  • JavaScript如何工作V8引擎深入探究 + 優(yōu)化代碼5個(gè)技巧(譯文)

    摘要:引擎可以是一個(gè)標(biāo)準(zhǔn)的解釋器,也可以是一個(gè)將編譯成某種形式的字節(jié)碼的即時(shí)編譯器。和其他引擎最主要的差別在于,不會(huì)生成任何字節(jié)碼或是中間代碼。不使用中間字節(jié)碼的表示方式,就沒(méi)有必要用解釋器了。 原文地址:https://blog.sessionstack.com... showImg(https://segmentfault.com/img/bVVwZ8?w=395&h=395); 數(shù)周之...

    William_Sang 評(píng)論0 收藏0
  • JavaScript工作原理(二):V8引擎5招高效代碼

    摘要:引擎可以用標(biāo)準(zhǔn)解釋器或即時(shí)編譯器來(lái)實(shí)現(xiàn),即時(shí)編譯器以某種形式將代碼編譯為字節(jié)碼。這里的主要區(qū)別在于不生成字節(jié)碼或任何中間代碼。請(qǐng)注意,不使用中間字節(jié)碼表示法,不需要解釋器。這允許在正常執(zhí)行期間非常短的暫停。 本系列的第一篇文章重點(diǎn)介紹了引擎,運(yùn)行時(shí)和調(diào)用棧的概述。第二篇文章將深入V8的JavaScript引擎的內(nèi)部。我們還會(huì)提供一些關(guān)于如何編寫(xiě)更好的JavaScript代碼的技巧。 概...

    leone 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<