`
RednaxelaFX
  • 浏览: 3016574 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

在WinXP上构建V8

阅读更多
事实上非常容易,以至于没啥好写的。根据V8的官方文档就能顺利"as-is"构造出来。

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

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

然后,根据说明,在构造时覆盖SCons的环境参数,在V8源码的根目录执行下述指令就行:
引用
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"

(把VS和WinSDK装在默认路径上也不是没好处,呵呵。用scons --help可以看到其它构建选项)

执行结束后,得到release/snapshot/static版的v8.lib。
接下来想把位于samples里的shell构造出来,只要把shell.cc从samples目录复制到V8的根目录然后:
引用
cl /Iinclude shell.cc v8.lib

加上/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,来玩玩看。
下面一图是V8 0.3.4 vs DMDScript 1.14 vs Managed JScript (sdl-sdk 0.4.0) vs Rhino 1.7R1 vs JScript 5.7做同一个测试的比较:

(图缩小了的话点击放大)
从数字上看,至少现在的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
引用
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)

.NET Framework是3.5 SP1。
采用client的JVM是因为这个例子运行时间太短,如果使用-server反而会更慢(数值上显示出来是1000+);Rhino的-opt在这里也没有多少作用,开了-opt 9之后执行这个例子的时间也没变化。

3、给不熟悉这几个引擎的简单介绍一下:
V8Google新推出的浏览器Chrome中使用的JavaScript引擎,用C++编写。发布于2008年9月;
DMDScriptDigital Mars开发的一种ECMAScript 3的实现,用D语言编写。也有C++编写的版本,上面例子里用的就是C++版的。发布于2007年9月;
Managed JScript微软在DLR平台上的ECMAScript 3的实现,用C#编写,运行在.NET Framework上。我测试用的版本来自Silverlight Dynamic Languages SDK 0.4.0(稍做修改,让它能在普通的.NET Framework 2.0而不是Silverlight 2.0 RC0中运行)。发布于2008年10月;
Rhino 1.7R1是Mozilla基于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的话,可以按照官网说明,这样:
make native mode=debug console=readline snapshot=on -j4 disassembler=on gdbjit=on objectprint=on

这样可以build出我需要的d8 shell,在out/native/d8。

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

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 ---
  • d8.zip (1 MB)
  • 下载次数: 28
分享到:
评论
4 楼 srdrm 2010-05-04  
good, 你说v8代码好, 我也想看看
3 楼 RednaxelaFX 2010-01-21  
liang.itjob 写道
不知楼主有没有试过中文,如
print("中文");

显示出来的全部都是乱码,不知道怎么解决,望楼主赐教

赐教不敢。确实,用我build出来的shell来跑那句 print("中文"); 的话显示出来的是乱码。这大概是因为V8的shell中的print函数使用的字符编码与中文Windows的字符编码不匹配导致的。等我回家看看具体的,现在在这边没build环境……我猜在shell的print函数临输出前加一个WideCharToMultiByte()的调用就好了。
2 楼 liang.itjob 2010-01-20  
不知楼主有没有试过中文,如
print("中文");

显示出来的全部都是乱码,不知道怎么解决,望楼主赐教
1 楼 lyo1005 2009-05-29  
 

相关推荐

Global site tag (gtag.js) - Google Analytics