多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > 互聯(lián)網(wǎng) > Mozilla與三星之子――Servo特性解讀

Mozilla與三星之子――Servo特性解讀

來源:程序員人生   發(fā)布時間:2014-09-06 23:31:21 閱讀次數(shù):2762次

【編者按】Servo是一個實(shí)驗(yàn)性質(zhì)的網(wǎng)頁瀏覽器排版引擎(類似于Gecko),由Mozilla聯(lián)合三星進(jìn)行開發(fā),采用Mozilla新推出的Rust語言編寫。Servo的愿景是盡可能地發(fā)揮多核處理器的“多核”功能,而不是讓它成為硬件商的噱頭,與三星強(qiáng)強(qiáng)聯(lián)合是希望Servo和Rust最終在Android平臺和ARM設(shè)備上開花結(jié)果。

背景介紹

一個Web瀏覽器的宗旨是幫助用戶和程序間建立起友好的溝通橋梁。用戶希望瀏覽器是反應(yīng)迅速的,因而瀏覽器的布局和渲染算法通常是采用底層本機(jī)代碼(Native Code)來實(shí)現(xiàn)的。同時,通過DOM,我們可以使用JavaScript來重構(gòu)整個HTML文檔。因此,使用瀏覽器來呈現(xiàn)頁面時,實(shí)質(zhì)上是使用了一個多語言的數(shù)據(jù)結(jié)構(gòu),使得低級本機(jī)代碼和高級語言如JavaScript之間可以無縫交流。在Servo項(xiàng)目中,我們會讓這個溝通的藝術(shù)變得更美好,我們有一個新的DOM內(nèi)存管理方法還使用了一些Rust的功能,如:自動生成域遍歷(Auto-generating field traversals),生命周期檢驗(yàn)(Lifetime checking),自定義靜態(tài)分析插件(custom static analysis plugins)。

DOM內(nèi)存管理

一個還將使用的DOM一般不會被馬上銷毀,但這通常會引起use-after-free 漏洞。要解決這個問題,很多瀏覽器都使用引用計(jì)數(shù)(reference counting即內(nèi)存回收)來追蹤不同底層DOM對象的指針。當(dāng)用JS獲取一個DOM對象時(如getElementById),瀏覽器會在JVM中生成一個反射對象來指向一個底層對象。如果JS的垃圾回收器判斷出一個反射對象不再使用,它會銷毀這個對象并相應(yīng)調(diào)減引用計(jì)數(shù),當(dāng)計(jì)數(shù)為0時,垃圾收集器會釋放引用次數(shù)為0的值所占內(nèi)存。

這個辦法的確能解決use-after-free問題,但如果瀏覽器內(nèi)存占用可以更少,用戶會更滿意的。因此,無用對象的銷毀是越快越好。然而,跨語言的反射對象體系會是一個障礙,出現(xiàn)循環(huán)引用問題。

例如下面代碼的一個C++ Element對象,它有一個Event的引用計(jì)數(shù)指針:

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_0.js">struct Element { RefPtr<Event> mEvent; };

假設(shè)我們在JS中為element對象添加一個事件:

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_1.js">elem.addEventListener('load', function (event) { event.originalTarget = elem; });

代碼執(zhí)行時,event的屬性會回指Element,這就是一個跨語言循環(huán)引用例子。C++的回收器不會銷毀這個循環(huán),JS的垃圾收集器追蹤不到C++指針,因此引用計(jì)數(shù)無法減為0,這些對象將永遠(yuǎn)不會被銷毀。盡管存在一些解決方法,但是可能會導(dǎo)致其它諸如內(nèi)存泄漏,NULL指針的問題。

有鑒于此,我們在Servo嘗試了新的思路―不再對DOM對象進(jìn)行引用計(jì)數(shù)。取而代之的,我們賦予了JS垃圾回收器全權(quán)來管理這些底層DOM對象。要實(shí)現(xiàn)它,Servo的Rust代碼與SpiderMonkey的垃圾回收器之間需要做一個相當(dāng)繁復(fù)的互動,還好Rust一些炫酷的特性會帶來極大的幫助。

自動生成字段遍歷(Auto-generating field traversals)

Rust中有一個traits(特性)的概念,類似于Haskell語言中的類型類或面向?qū)ο笳Z言中的接口。

例如Collection trait類型:

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_2.js">pub trait Collection { fn len(&self) -> uint; }

這個集合類型描述的是任何元素的類型集合,這里的len方法是用于獲取集合的長度。

還有一個是Endodable trait類型,用于序列化。

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_3.js">pub trait Encodable { fn encode<T: Encoder>(&self, encoder: &mut T); }

任何可序列化的類型都有一個泛型的encode方法。Encodable trait是一個特殊的類型,因?yàn)榫幾g器能自行來實(shí)現(xiàn)它。

我們來看看DOM的Document文檔接口在Servo中的實(shí)現(xiàn):

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_4.js">#[deriving(Encodable)] pub struct Document { pub node: Node, pub window: JS<Window>, pub is_html_document: bool, ... }

deriving屬性會讓編譯器遞歸地對node,window等字段進(jìn)行encode處理。如果往Document中添加了一個非Endoable的字段,編譯器會報(bào)錯,這就確保了在編譯時進(jìn)行全字段跟蹤。

生存期檢查(Lifetime checking)

Servo中,需要用Rust來傳遞一個DOM對象指針作為函數(shù)參數(shù),在本地變量中存儲DOM對象指針等等。這些額外的臨時引用,需要在垃圾回收器中進(jìn)行可到達(dá)分析時,以roots的形式來登記。否則,會引致 use-after-free 問題。為了解決該問題,Rust中引入了編譯時生存期檢查器,它會使編譯器識別并拒絕use-after-free或其它的危險錯誤。

例如:

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_5.js">pub fn root_ref<'a>(&'a self) -> JSRef<'a, T> {

這個語法的意思是:
1. <’a>: “任何值為’a生存期”

2. (&'a self):“一個在’a有效生存期內(nèi)的Root引用”

3. ->JSRef<'a, T>:“返回一個生存期參數(shù)為’a的JSRef”

如果我們嘗試執(zhí)行下面的代碼:

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_6.js">fn bogus_get_window<'a>(&self) -> JSRef<'a, Window> { let window = self.window.root(); window.root_ref() // return the JSRef }

我們會收到這樣的錯誤提示:

code_snippet_id="460315" snippet_file_name="ptcms_1409277338_7.js">document.rs:199:9: 199:15 error: `window` does not live long enough document.rs:199 window.root_ref() ^~~~~~ document.rs:197:57: 200:6 note: reference must be valid for the lifetime 'a as defined on the block at 197:56... document.rs:197 fn bogus_get_window<'a>(&self) -> JSRef<'a, Window> { document.rs:198 let window = self.window.root(); document.rs:199 window.root_ref() document.rs:200 } document.rs:197:57: 200:6 note: ...but borrowed value is only valid for the block at 197:56 document.rs:197 fn bogus_get_window<'a>(&self) -> JSRef<'a, Window> { document.rs:198 let window = self.window.root(); document.rs:199 window.root_ref() document.rs:200 }

有關(guān)該語法中有關(guān)概念的詳細(xì)解釋,請點(diǎn)擊這里進(jìn)行了解。

自定義靜態(tài)分析 (custom static analysis)

Rust的編譯器能夠載入“lint”插件進(jìn)行自定義靜態(tài)分析,從字面來看,”lint”的宗旨是采取低開銷戰(zhàn)略來捕捉常見錯誤。我們希望其與生存期檢查器一起為開發(fā)者帶來更安全可靠的瀏覽器引擎。

寫在最后

Rust語言(最新版本0.11.0)和Servo還處于實(shí)驗(yàn)階段,仍需各方協(xié)力來不斷完善,如果想進(jìn)一步了解Rust或Servo,請嘗試訪問下面的鏈接。

  • Rust語言指導(dǎo);
  • Rust Reddit討論區(qū)
  • 向Servo提出建議;
  • Servo代碼范例。

更多詳細(xì)內(nèi)容:mozilla.org

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 国产一二三区在线 | 亚洲国产精品ⅴa在线观看 亚洲国产精品aaa一区 | 欧美成人免费大片888 | 久久精品国产99久久6动漫欧 | 国产精品高清一区二区三区不卡 | 国产a级一级久久毛片 | 九九久久久久午夜精选 | 性欧美高清精品videos | 亚洲欧美在线免费观看 | 国产精品亚洲综合第一区 | 国产亚洲精品欧美一区 | 中文字幕第99页 | 国产一区二区三区日韩欧美 | 中文字幕第35页 | 中文字幕激情视频 | 欧美色欧 | 欧美日韩另类国产 | 欧美俄罗斯一级毛片激情 | 视频h在线 | 香蕉高清免费永久在线视频 | 日本欧美一区二区三区在线观看 | 成人综合色站 | 国产精品亚洲综合一区在线观看 | 最近中文字幕免费6 | 老司机午夜精品 | 欧美国产亚洲18 | 在线天堂中文 | 男人天堂国产 | 2020久久国产最新免费观看 | 日韩一区二区三区四区 | 在线观看免费亚洲 | 亚洲欧美日韩不卡一区二区三区 | 老女人毛片| 国产亚洲人成在线影院 | 自拍中文字幕 | 在线观看亚洲精品国产 | 欧美在线视频a | xxxxx做受大片视频免费 | 亚洲蜜桃| 一级做a爰性色毛片 | 午夜久久久精品 |