日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > Mozilla與三星之子――Servo特性解讀

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

來源:程序員人生   發布時間:2014-09-06 23:31:21 閱讀次數:2767次

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

背景介紹

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

DOM內存管理

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

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

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

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

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

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

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

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

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

Rust中有一個traits(特性)的概念,類似于Haskell語言中的類型類或面向對象語言中的接口。

例如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是一個特殊的類型,因為編譯器能自行來實現它。

我們來看看DOM的Document文檔接口在Servo中的實現:

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等字段進行encode處理。如果往Document中添加了一個非Endoable的字段,編譯器會報錯,這就確保了在編譯時進行全字段跟蹤。

生存期檢查(Lifetime checking)

Servo中,需要用Rust來傳遞一個DOM對象指針作為函數參數,在本地變量中存儲DOM對象指針等等。這些額外的臨時引用,需要在垃圾回收器中進行可到達分析時,以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有效生存期內的Root引用”

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

如果我們嘗試執行下面的代碼:

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 }

有關該語法中有關概念的詳細解釋,請點擊這里進行了解。

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

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

寫在最后

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

  • Rust語言指導;
  • Rust Reddit討論區
  • 向Servo提出建議;
  • Servo代碼范例。

更多詳細內容:mozilla.org

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品色综合一区二区三区 | 在线小视频| 午夜毛片免费看 | 爱爱免费视频网址 | 国产精品网站在线观看 | 懂色av影视一区二区三区 | 久久久久久久免费 | 自拍偷拍第一页 | 麻豆乱码国产一区二区三区 | 久久久久成人精品 | 国产成人精品自拍 | 日韩中文字幕在线观看 | 欧美一区二区三区 | 欧美大片一区二区 | 天堂成人国产精品一区 | 欧美日韩视频一区二区三区 | 亚洲天堂免费视频 | 最新国产网站 | 国产va在线观看 | 日韩精品在线视频 | 在线播放a| 精品成人在线观看 | 亚洲国产精品久久久久 | 91精品国产九九九久久久亚洲 | 自拍偷拍在线视频 | 午夜精品av | 日韩av一区在线 | 91.成人天堂一区 | 欧美精品网站 | 欧美成人a级片 | 精品国产一区二区三区在线观看 | 久久免费高清 | 日韩一页| 精品在线| 午夜国产视频 | 亚洲综合字幕 | 国产精品免费一区二区三区都可以 | 日韩视频在线免费 | 午夜在线精品偷拍 | 久久综合爱 | 日韩在线欧美 |