在WinXP上构建V8

事实上非常容易,以至于没啥好写的。根据V8的[url=http://code.google.com/apis/v8/build.html]官方文档[/url]就能顺利"as-is"构造出来。

必须的环境:
Subversion 1.4 or higher - see [url]http://subversion.tigris.org/links.html#clients[/url]
Python 2.4 or higher - see [url]http://www.python.org[/url]
SCons 1.0.0 or higher - see [url]http://www.scons.org[/url]

我使用的是
Subversion 1.4.6 (r28521)
Python 2.5.1
SCons 1.0.0
Visual Studio 2008 Professional

然后,根据[url=http://code.google.com/p/v8/wiki/BuildingOnWindows]说明[/url],在构造时覆盖SCons的环境参数,在V8源码的根目录执行下述指令就行:
[quote]scons env="PATH:C:\Program Files\Microsoft Visual Studio 9.0\VC\bin;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools,INCLUDE:C:\Program Files\Microsoft Visual Studio 9.0\VC\include;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include,LIB:C:\Program Files\Microsoft Visual Studio 9.0\VC\lib;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib"[/quote]
(把VS和WinSDK装在默认路径上也不是没好处,呵呵。用scons --help可以看到其它构建选项)

执行结束后,得到release/snapshot/static版的v8.lib。
接下来想把位于samples里的shell构造出来,只要把shell.cc从samples目录复制到V8的根目录然后:
[quote]cl /Iinclude shell.cc v8.lib[/quote]
加上/O2之类的开关当然也是可以的咯。

直接通过SCons脚本也可以构造出shell:
scons env="PATH:C:\Program Files\Microsoft Visual Studio 9.0\VC\bin;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools,INCLUDE:C:\Program Files\Microsoft Visual Studio 9.0\VC\include;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include,LIB:C:\Program Files\Microsoft Visual Studio 9.0\VC\lib;C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib" snapshot=on mode=debug console=readline disassembler=on sample=shell

然后可以开shell这样玩:
shell_g.exe --print_code

V8 version 2.0.0
> var i = 1
--- Raw source ---
var i = 1


--- Code ---
kind = FUNCTION
Instructions (size = 63)
01802EA0 0 55 push ebp
01802EA1 1 89e5 mov ebp,esp
01802EA3 3 56 push esi
01802EA4 4 57 push edi
01802EA5 5 6829013c00 push 0x3c0129 ;; object: 003C0129 <undefined>
01802EAA 10 56 push esi
01802EAB 11 680d2d1d00 push 0x1d2d0d ;; object: 001D2D0D <FixedArray[2]>
01802EB0 16 6a00 push 0x0
01802EB2 18 e86901ffff call 017F3020 ;; debug: statement 0
;; code: STUB, Runtime, RuntimeStub_DeclareGlobals
01802EB7 23 3b25400d7400 cmp esp,[0x740d40]
01802EBD 29 0f8305000000 jnc 40 (01802EC8)
01802EC3 35 e8d8d5feff call 017F04A0 ;; code: STUB, StackCheck, minor: 0
01802EC8 40 68b1293c00 push 0x3c29b1 ;; object: 003C29B1 <String[1]: i>
01802ECD 45 6a02 push 0x2
01802ECF 47 e88cd5feff call 017F0460 ;; code: STUB, Runtime, RuntimeStub_InitializeVarGlobal
01802ED4 52 b829013c00 mov eax,003C0129 ;; object: 003C0129 <undefined>
01802ED9 57 89ec mov esp,ebp ;; debug: statement 10
;; js return
01802EDB 59 5d pop ebp
01802EDC 60 c20400 ret 0x4

RelocInfo (size = 13)
01802EA6 embedded object (003C0129 <undefined>)
01802EAC embedded object (001D2D0D <FixedArray[2]>)
01802EB2 statement position (0)
01802EB3 code target (STUB) (017F3020)
01802EC4 code target (STUB) (017F04A0)
01802EC9 embedded object (003C29B1 <String[1]: i>)
01802ED0 code target (STUB) (017F0460)
01802ED5 embedded object (003C0129 <undefined>)
01802ED9 statement position (10)
01802ED9 js return

> i + 2
--- Raw source ---
i + 2


--- Code ---
kind = FUNCTION
Instructions (size = 71)
018030A0 0 55 push ebp
018030A1 1 89e5 mov ebp,esp
018030A3 3 56 push esi
018030A4 4 57 push edi
018030A5 5 6829013c00 push 0x3c0129 ;; object: 003C0129 <undefined>
018030AA 10 3b25400d7400 cmp esp,[0x740d40]
018030B0 16 0f8305000000 jnc 27 (018030BB)
018030B6 22 e8e5d3feff call 017F04A0 ;; debug: statement 0
;; code: STUB, StackCheck, minor: 0
018030BB 27 ff7617 push [esi+0x17]
018030BE 30 b9b1293c00 mov ecx,003C29B1 ;; object: 003C29B1 <String[1]: i>
018030C3 35 e8f82dffff call LoadIC_Initialize (017F5EC0) ;; code: contextual, LOAD_IC, UNINITIALIZED
018030C8 40 90 nop
018030C9 41 890424 mov [esp],eax
018030CC 44 6a04 push 0x4
018030CE 46 e86dfeffff call 01802F40 ;; code: STUB, GenericBinaryOp, minor: 4240
018030D3 51 50 push eax
018030D4 52 8f45f4 pop [ebp+0xf4]
018030D7 55 8b45f4 mov eax,[ebp+0xf4]
018030DA 58 89ec mov esp,ebp ;; js return
018030DC 60 5d pop ebp
018030DD 61 c20400 ret 0x4
018030E0 64 b829013c00 mov eax,003C0129 ;; object: 003C0129 <undefined>
018030E5 69 ebf3 jmp 58 (018030DA)

RelocInfo (size = 11)
018030A6 embedded object (003C0129 <undefined>)
018030B6 statement position (0)
018030B7 code target (STUB) (017F04A0)
018030BF embedded object (003C29B1 <String[1]: i>)
018030C4 code target (context) (LOAD_IC) (017F5EC0)
018030CF code target (STUB) (01802F40)
018030DA js return
018030E1 embedded object (003C0129 <undefined>)

3
> quit()
--- Raw source ---
quit()


--- Code ---
kind = FUNCTION
Instructions (size = 65)
01803140 0 55 push ebp
01803141 1 89e5 mov ebp,esp
01803143 3 56 push esi
01803144 4 57 push edi
01803145 5 6829013c00 push 0x3c0129 ;; object: 003C0129 <undefined>
0180314A 10 3b25400d7400 cmp esp,[0x740d40]
01803150 16 0f8305000000 jnc 27 (0180315B)
01803156 22 e845d3feff call 017F04A0 ;; debug: statement 0
;; code: STUB, StackCheck, minor: 0
0180315B 27 6829333c00 push 0x3c3329 ;; object: 003C3329 <String[4]: quit>
01803160 32 ff7617 push [esi+0x17]
01803163 35 e8f81bffff call 017F4D60 ;; code: contextual, CALL_IC, UNINITIALIZED, argc = 0
01803168 40 8b75fc mov esi,[ebp+0xfc]
0180316B 43 890424 mov [esp],eax
0180316E 46 8f45f4 pop [ebp+0xf4]
01803171 49 8b45f4 mov eax,[ebp+0xf4]
01803174 52 89ec mov esp,ebp ;; js return
01803176 54 5d pop ebp
01803177 55 c20400 ret 0x4
0180317A 58 b829013c00 mov eax,003C0129 ;; object: 003C0129 <undefined>
0180317F 63 ebf3 jmp 52 (01803174)

RelocInfo (size = 10)
01803146 embedded object (003C0129 <undefined>)
01803156 statement position (0)
01803157 code target (STUB) (017F04A0)
0180315C embedded object (003C3329 <String[4]: quit>)
01803164 code target (context) (CALL_IC) (017F4D60)
01803174 js return
0180317B embedded object (003C0129 <undefined>)

--- Raw source ---
(a){
if(%_IsSmi(a))return a;
return %NumberToJSInt32(ToNumber(a));
}


--- Code ---
kind = FUNCTION
name = ToInt32
Instructions (size = 72)
01803220 0 55 push ebp
01803221 1 8bec mov ebp,esp
01803223 3 56 push esi
01803224 4 57 push edi
01803225 5 3b25400d7400 cmp esp,[0x740d40]
0180322B 11 0f822d000000 jc 62 (0180325E)
01803231 17 8b4508 mov eax,[ebp+0x8]
01803234 20 a801 test al,0x1
01803236 22 0f8506000000 jnz 34 (01803242)
0180323C 28 8be5 mov esp,ebp ;; debug: statement 8356
;; js return
0180323E 30 5d pop ebp
0180323F 31 c20800 ret 0x8
01803242 34 8b5e17 mov ebx,[esi+0x17]
01803245 37 6829023c00 push 0x3c0229 ;; object: 003C0229 <String[8]: ToNumber>
0180324A 42 53 push ebx
0180324B 43 50 push eax
0180324C 44 e86fe1feff call 017F13C0 ;; debug: statement 8366
;; debug: position 8390
;; code: contextual, CALL_IC, UNINITIALIZED, in_loop, argc = 1
01803251 49 8b75fc mov esi,[ebp+0xfc]
01803254 52 8945f4 mov [ebp+0xf4],eax
01803257 55 e884ffffff call 018031E0 ;; code: STUB, Runtime, RuntimeStub_NumberToJSInt32
0180325C 60 ebde jmp 28 (0180323C)
0180325E 62 e83dd2feff call 017F04A0 ;; debug: statement 8337
;; code: STUB, StackCheck, minor: 0
01803263 67 8b7df8 mov edi,[ebp+0xf8]
01803266 70 ebc9 jmp 17 (01803231)

RelocInfo (size = 20)
0180323C statement position (8356)
0180323C js return
01803246 embedded object (003C0229 <String[8]: ToNumber>)
0180324C statement position (8366)
0180324C position (8390)
0180324D code target (context) (CALL_IC) (017F13C0)
01803258 code target (STUB) (018031E0)
0180325E statement position (8337)
0180325F code target (STUB) (017F04A0)

更多选项可以用shell_g --help得到。

在V8的tools\visual_studio\目录里有对应VS2005的solution文件,于是通过VS IDE也可以浏览V8代码,编辑,构建。

阅读V8的源码是件开心的事;代码风格看起来相当不错,至少很合我的偏好。里面借鉴Strongtalk等的技巧也让人很兴奋。有时间一定要仔细看看。

===========================================================================

Alright,来玩玩看。
下面一图是[b]V8 0.3.4[/b] vs [b]DMDScript 1.14[/b] vs [b]Managed JScript (sdl-sdk 0.4.0)[/b] vs [b]Rhino 1.7R1[/b] vs [b]JScript 5.7[/b]做同一个测试的比较:
[img]http://rednaxelafx.iteye.com/upload/picture/pic/22881/5baacfb1-0fd4-3516-8f60-d82b03a17aed.gif[/img]
(图缩小了的话点击放大)
从数字上看,至少现在的Managed JScript比06年底的JScript要快了,即便前者运行在.NET上而后者是native的。但它们的速度都远远比不上V8……时间差了一位啊 - -
新的JavaScript引擎真可怕。

sieve.js/ds/jsx来自DMDScript自带的sieve.ds测试文件,内容为:
/* Eratosthenes Sieve prime number calculation. */

size = 8190;
sizepl = 8191;

var flags = new Array(sizepl);

var i, prime, k, count, iter;

print("10 iterations\n");
starttime = new Date();
for (iter = 1; iter <= 10; iter++)
{ count = 0;
for (i = 0; i <= size; i++)
flags[i] = true;
for (i = 0; i <= size; i++)
{ if (flags[i])
{ prime = i + i + 3;
k = i + prime;
while (k <= size)
{
flags[k] = false;
k += prime;
}
count += 1;
}
}
}
elapsedtime = new Date() - starttime;
print("\n" + count + " primes\n");
print("elapsed time = " + elapsedtime + "\n");

纯啃数字的microbenchmark

需要说明的几点:
1、Benchmarks are nothing more than lies damn lies.这个是真理。但至少从图中数字可以看出不同实现间在这个特定例子下的速度差异。

2、关于运行环境:
用来测试的机器是运行在Intel Pentium-M 715 (Dothan核心,1.50GHz)+1248MB内存上的Windows XP SP3。
JVM是Sun的HotSpot Client VM
[quote]java version "1.6.0_05"
Java(TM) SE Runtime Environment (build 1.6.0_05-b13)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)[/quote]
.NET Framework是3.5 SP1。
采用client的JVM是因为这个例子运行时间太短,如果使用-server反而会更慢(数值上显示出来是1000+);Rhino的-opt在这里也没有多少作用,开了-opt 9之后执行这个例子的时间也没变化。

3、给不熟悉这几个引擎的简单介绍一下:
[url=http://code.google.com/apis/v8/intro.html]V8[/url]是[url=http://www.google.com]Google[/url]新推出的浏览器Chrome中使用的JavaScript引擎,用C++编写。发布于2008年9月;
[url=http://www.digitalmars.com/dscript/]DMDScript[/url]是[url=http://www.digitalmars.com]Digital Mars[/url]开发的一种ECMAScript 3的实现,用[url=http://www.digitalmars.com/d/1.0]D语言[/url]编写。也有C++编写的版本,上面例子里用的就是C++版的。发布于2007年9月;
[url=http://blogs.msdn.com/deepak/archive/2007/05/02/managed-jscript-is-availaible.aspx]Managed JScript[/url]是[url=http://www.microsoft.com]微软[/url]在DLR平台上的ECMAScript 3的实现,用C#编写,运行在.NET Framework上。我测试用的版本来自[url=http://www.codeplex.com/sdlsdk]Silverlight Dynamic Languages SDK[/url] [url=http://www.codeplex.com/sdlsdk/Release/ProjectReleases.aspx?ReleaseId=17839]0.4.0[/url](稍做修改,让它能在普通的.NET Framework 2.0而不是Silverlight 2.0 RC0中运行)。发布于2008年10月;
[url=http://www.mozilla.org/rhino/]Rhino[/url] 1.7R1是[url=http://www.mozilla.org/]Mozilla[/url]基于JVM开发的JavaScript 1.7实现,用Java编写。发布于2008年3月。很明显这个版本还不可能用上原型阶段的invokedynamic;
JScript 5.7是微软的另一个ECMAScript 3实现,我不太清楚它是C还是C++写的,不过它暴露了COM接口。IE7使用的JScript引擎就是它。发布于2006年11月。虽然是很老了,但现在IE8还没正式推出,只好用它来测。要在WSH里运行上面的测试,需要把print()改为WScript.Echo()。

4. 为什么不拿SquirrelFish Extreme和TraceMonkey来测?
答:因为我懒得单独build它们……以后有机会再说;虽说不自己build可以用它们各自所属的浏览器最新的nightly builds,但我也不想装nightly build的Safari和FireFox 3.1。

5. 那么JScript.NET (JScript 8.0)呢?
答:我测了,大概在600上下。这玩儿微软已经放弃了,所以没放在图里比较。这静态编译了的JScript.NET居然比动态编译的Managed JScript还慢 T T
要在JScript.NET上运行上述测试,需要在文件开头添加import System,然后把print()换为Console.WriteLine();同时还要用var语句显式声明所有变量。
开了/fast开关来编译的话,JScript.NET运行上述测试的时间降到500左右,但还是比Managed JScript稍微慢一些。

===============================================

2015-04更新:

在Mac OS X上build现在最新的V8的话,可以按照[url=https://code.google.com/p/v8-wiki/wiki/BuildingWithGYP]官网说明[/url],这样:
[code]make native mode=debug console=readline snapshot=on -j4 disassembler=on gdbjit=on objectprint=on[/code]
这样可以build出我需要的d8 shell,在out/native/d8。

但“有趣”的是print_ast居然只在ia32 target上有,而在x64 target上没有。太诡异了吧?

[code]V8 version 4.4.0 (candidate) [console: readline]
d8> function f1() { print("f1") }
--- Raw source ---
function f1() { print("f1") }

--- Code ---
source_position = 0
kind = FUNCTION
Instructions (size = 148)
0xb7f8c00f8c0 0 488b4c2408 REX.W movq rcx,[rsp+0x8]
0xb7f8c00f8c5 5 493b4da8 REX.W cmpq rcx,[r13-0x58]
0xb7f8c00f8c9 9 750d jnz 24 (0xb7f8c00f8d8)
0xb7f8c00f8cb 11 488b4e27 REX.W movq rcx,[rsi+0x27]
0xb7f8c00f8cf 15 488b4927 REX.W movq rcx,[rcx+0x27]
0xb7f8c00f8d3 19 48894c2408 REX.W movq [rsp+0x8],rcx
0xb7f8c00f8d8 24 55 push rbp
0xb7f8c00f8d9 25 4889e5 REX.W movq rbp,rsp
0xb7f8c00f8dc 28 56 push rsi
0xb7f8c00f8dd 29 57 push rdi
0xb7f8c00f8de 30 56 push rsi
0xb7f8c00f8df 31 49ba6165e8491b090000 REX.W movq r10,0x91b49e86561 ;; object: 0x91b49e86561 <FixedArray[2]>
0xb7f8c00f8e9 41 4152 push r10
0xb7f8c00f8eb 43 6a00 push 0x0
0xb7f8c00f8ed 45 b803000000 movl rax,0x3
0xb7f8c00f8f2 50 48bb70c3530001000000 REX.W movq rbx,0x10053c370 ;; v8::internal::Runtime_DeclareGlobals(int, v8::internal::Object**, v8::internal::Isolate*)
0xb7f8c00f8fc 60 e8bf85efff call 0xb7f8bf07ec0 ;; debug: statement 0
;; code: STUB, CEntryStub, minor: 0
0xb7f8c00f901 65 493ba520080000 REX.W cmpq rsp,[r13+0x820]
0xb7f8c00f908 72 7305 jnc 79 (0xb7f8c00f90f)
0xb7f8c00f90a 74 e8511ff2ff call StackCheck (0xb7f8bf31860) ;; code: BUILTIN
0xb7f8c00f90f 79 498b45a8 REX.W movq rax,[r13-0x58]
0xb7f8c00f913 83 48bbc164e8491b090000 REX.W movq rbx,0x91b49e864c1 ;; object: 0x91b49e864c1 Cell for 6144
0xb7f8c00f91d 93 83430bd1 addl [rbx+0xb],0xd1
0xb7f8c00f921 97 791f jns 130 (0xb7f8c00f942)
0xb7f8c00f923 99 50 push rax
0xb7f8c00f924 100 e8f71df2ff call InterruptCheck (0xb7f8bf31720) ;; code: BUILTIN
0xb7f8c00f929 105 58 pop rax
0xb7f8c00f92a 106 48bbc164e8491b090000 REX.W movq rbx,0x91b49e864c1 ;; object: 0x91b49e864c1 Cell for 6144
0xb7f8c00f934 116 49ba0000000000180000 REX.W movq r10,0x180000000000
0xb7f8c00f93e 126 4c895307 REX.W movq [rbx+0x7],r10
0xb7f8c00f942 130 488be5 REX.W movq rsp,rbp ;; debug: statement 28
;; js return
0xb7f8c00f945 133 5d pop rbp
0xb7f8c00f946 134 c20800 ret 0x8
0xb7f8c00f949 137 cc int3
0xb7f8c00f94a 138 cc int3
0xb7f8c00f94b 139 cc int3
0xb7f8c00f94c 140 cc int3
0xb7f8c00f94d 141 cc int3
0xb7f8c00f94e 142 cc int3
0xb7f8c00f94f 143 90 nop

Deoptimization Output Data (deopt points = 0)

Back edges (size = 0)
ast_id pc_offset loop_depth

0x91b49e865a1: [TypeFeedbackInfo]
- ic_total_count: 0, ic_with_type_info_count: 0, ic_generic_count: 0

RelocInfo (size = 12)
0xb7f8c00f8e1 embedded object (0x91b49e86561 <FixedArray[2]>)
0xb7f8c00f8fc statement position (0)
0xb7f8c00f8fd code target (STUB) (0xb7f8bf07ec0)
0xb7f8c00f90b code target (BUILTIN) (0xb7f8bf31860)
0xb7f8c00f915 embedded object (0x91b49e864c1 Cell for 6144)
0xb7f8c00f925 code target (BUILTIN) (0xb7f8bf31720)
0xb7f8c00f92c embedded object (0x91b49e864c1 Cell for 6144)
0xb7f8c00f942 statement position (28)
0xb7f8c00f942 js return

--- End code ---[/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值