锁定老帖子 主题:IKVM 编程武林之.NET派的北冥神功
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-29
ray_linn 写道 这里我想到如果实现动态ngen--似乎更美妙,只ngen到被调用的那些方法,可以称为动态ngen或者静态hotspot 动态ngen?和jit有什么区别?除非把native code保存到磁盘上,那倒算是有区别,不过那样似乎就把ngen和jit的缺点都占了——既不能动态优化,又必须在运行时编译。 |
|
返回顶楼 | |
发表时间:2009-12-29
幸存者 写道 ray_linn 写道 这里我想到如果实现动态ngen--似乎更美妙,只ngen到被调用的那些方法,可以称为动态ngen或者静态hotspot 动态ngen?和jit有什么区别?除非把native code保存到磁盘上,那倒算是有区别,不过那样似乎就把ngen和jit的缺点都占了——既不能动态优化,又必须在运行时编译。 我的意思是对于GAC里的类,替换被调用的IL为native code,这样之后的所有调用都是native code,而未被调用的IL则继续保持原来的格式。 |
|
返回顶楼 | |
发表时间:2009-12-29
JPython已经不叫JPython很久了……现在是Jython。该计划一直半死不活,到去年才开始重获生机开始快速发展。看看SourceForge中间有些版本是断的……
IronPython是从2.0开始转用DLR的(或者说把DLR剥离出来的)。剥离出来的DLR原本就是IronPython 1.x的一部分,独立出来之后为什么性能会降低……?随着经验的积累,在DLR的tuning也比IronPython 1.x的时代要好了。IronPython 2.6的性能比IronPython 2.0的性能……well有些地方因为实现的功能更复杂了所以……那不是DLR的错嗯。至少IronPython 2.6的启动速度比2.0快多了,在DLR的解释器的协助下。 DLR里的很多优化技巧也跟源于Smalltalk/Self系的技术,跟HotSpot的有相似的源头;像是callsite caching、hidden class等……用起来也很方便。 |
|
返回顶楼 | |
发表时间:2009-12-29
ray_linn 写道 幸存者 写道 ray_linn 写道 这里我想到如果实现动态ngen--似乎更美妙,只ngen到被调用的那些方法,可以称为动态ngen或者静态hotspot 动态ngen?和jit有什么区别?除非把native code保存到磁盘上,那倒算是有区别,不过那样似乎就把ngen和jit的缺点都占了——既不能动态优化,又必须在运行时编译。 我的意思是对于GAC里的类,替换被调用的IL为native code,这样之后的所有调用都是native code,而未被调用的IL则继续保持原来的格式。 谈到这个话题不得不提JTL式的编译器……just-too-late |
|
返回顶楼 | |
发表时间:2009-12-29
最后修改:2009-12-29
RednaxelaFX 写道 JVM的性能进步对上层应用的影响不可谓不大。其中一个有趣的侧面是Sun的javac:从JDK 1.3开始它就会忽略-o编译开关——Sun认为在Java源码到JVM字节码过程中的优化没多少必要,反正HotSpot能提供足够优化。虽说这个设计到底是不是真的合理还可以商榷……
JVM的实现自然也会影响到库的实现。之前正好记过一篇关于反射调用方法的一个log,也算是能扯上关系。 还是你对VM相关的技术更了解,我只是知道,拍脑袋认为的一些个人观点而已。 我没有什么证据,随口说一些功能上的例子吧,例如很好用的java.util.concurrent.atomic.AtomicInteger类,底层使用了不开源的sun.misc.Unsafe(未必不开源,实际上是我没花时间找,默认的JDK中貌似没有这个类的源代码),如果对应到CLR中不知能否正确实现AtomicInteger类的功能。 还有像在多核CPU下transient关键字在JVM自己的不同版本中实现都不一样,不知道CLR会如何处理。 |
|
返回顶楼 | |
发表时间:2009-12-30
最后修改:2009-12-30
icewubin 写道 RednaxelaFX 写道 JVM的性能进步对上层应用的影响不可谓不大。其中一个有趣的侧面是Sun的javac:从JDK 1.3开始它就会忽略-o编译开关——Sun认为在Java源码到JVM字节码过程中的优化没多少必要,反正HotSpot能提供足够优化。虽说这个设计到底是不是真的合理还可以商榷……
JVM的实现自然也会影响到库的实现。之前正好记过一篇关于反射调用方法的一个log,也算是能扯上关系。 还是你对VM相关的技术更了解,我只是知道,拍脑袋认为的一些个人观点而已。 我没有什么证据,随口说一些功能上的例子吧,例如很好用的java.util.concurrent.atomic.AtomicInteger类,底层使用了不开源的sun.misc.Unsafe(未必不开源,实际上是我没花时间找,默认的JDK中貌似没有这个类的源代码),如果对应到CLR中不知能否正确实现AtomicInteger类的功能。 还有像在多核CPU下transient关键字在JVM自己的不同版本中实现都不一样,不知道CLR会如何处理。 System.Threading.Interlocked.CompareExchange() = sun.misc.Unsafe.compareAndSwapInt(). AtomicInteger.incrementAndGet()=Interlocked.Increment(ref foo); 通过C#的等价替代,很自然就实现java基础类库的CLR版,(由于IKVM根本不依赖于JDK,所以必须提供自己的CLR版java类库以便让自己的java应用引用) |
|
返回顶楼 | |
发表时间:2009-12-30
最后修改:2009-12-30
icewubin 写道 我没有什么证据,随口说一些功能上的例子吧,例如很好用的java.util.concurrent.atomic.AtomicInteger类,底层使用了不开源的sun.misc.Unsafe(未必不开源,实际上是我没花时间找,默认的JDK中貌似没有这个类的源代码),如果对应到CLR中不知能否正确实现AtomicInteger类的功能。
基本上整个JDK都开源了,像Unsafe这么重要的类型要是不开源那也未免太不厚道了 XD 以java.util.concurrent.atomic.AtomicInteger举例: AtomicInteger.compareAndSet()的实现如下: public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } 该实现依赖于sun.misc.Unsafe。在class文件被加载时,sun.misc.Unsafe.compareAndSwapInt()就被识别为intrinsic方法了。 vmSymbols.hpp do_intrinsic(_compareAndSwapInt, sun_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_RN) \ do_name( compareAndSwapInt_name, "compareAndSwapInt") \ do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \ 在解释模式下,Unsafe.compareAndSwapInt()被实现为: unsafe.cpp UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) UnsafeWrapper("Unsafe_CompareAndSwapInt"); oop p = JNIHandles::resolve(obj); jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e; UNSAFE_END 通用的Atomic::cmpxchg()实现为: atomic.cpp unsigned Atomic::cmpxchg(unsigned int exchange_value, volatile unsigned int* dest, unsigned int compare_value) { assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value); } 在Windows/x86(非AMD64)上的实现为: inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { mov edx, dest mov ecx, exchange_value mov eax, compare_value LOCK_IF_MP(mp) cmpxchg dword ptr [edx], ecx } } 本来是可以直接用Win32 API中的InterlockedCompareExchange(),不过Sun的工程师觉得这个函数在Win95上跑不了所以就干脆自己写汇编了。 这里的重点就是x86的cmpxchg指令。这是一种compare-and-swap(CAS)系的指令。 在编译模式下,JIT会识别出对Unsafe.compareAndSwapInt()的调用。其中-client编译器(也称为C1)在x86上会通过下面一系列调用最终生成cmpxchg指令: c1_LIRGenerator_x86.cpp else if (type == intType) __ cas_int(addr, cmp.result(), val.result(), ill, ill); c1_LIR.cpp append(new LIR_OpCompareAndSwap(lir_cas_int, addr, cmp_value, new_value, t1, t2)); c1_LIRAssembler_x86.cpp else if (op->code() == lir_cas_int) { __ cmpxchgl(newval, Address(addr, 0)); } assembler_x86.cpp // The 32-bit cmpxchg compares the value at adr with the contents of rax, // and stores reg into adr if so; otherwise, the value at adr is loaded into rax,. // The ZF is set if the compared values were equal, and cleared otherwise. void Assembler::cmpxchgl(Register reg, Address adr) { // cmpxchg if (Atomics & 2) { // caveat: no instructionmark, so this isn't relocatable. // Emit a synthetic, non-atomic, CAS equivalent. // Beware. The synthetic form sets all ICCs, not just ZF. // cmpxchg r,[m] is equivalent to rax, = CAS (m, rax, r) cmpl(rax, adr); movl(rax, adr); if (reg != rax) { Label L ; jcc(Assembler::notEqual, L); movl(adr, reg); bind(L); } } else { InstructionMark im(this); prefix(adr, reg); emit_byte(0x0F); emit_byte(0xB1); emit_operand(reg, adr); } } 在else分支中,生成的0x0F 0xB1就是cmpxchg。 在.NET上,对应的功能由System.Threading.Interlocked提供。Unsafe.compareAndSwapInt()对应的是System.Threading.Interlocked.CompareExchange()。底下依赖的x86指令也同样是cmpxchg。 Interlocked类在.NET 1.0的时候就已经有了,而AtomicInteger是Java 5新增的,这个嘛…… |
|
返回顶楼 | |
发表时间:2010-01-05
高手很多啊。
mono和ikvm有多大的实际意义? |
|
返回顶楼 | |
发表时间:2010-01-05
liudun 写道 mono和ikvm有多大的实际意义?
要是用广告词语气的话,我会说实际意义在于“leverage”,在不同的场景下延用已掌握的技术/技巧。例如说: ·熟悉.NET开发的人希望开发Linux、Mac等平台上的程序 -- Mono/Portable .NET ·熟悉.NET开发的人希望开发iPhone、Wii、PS3等平台上的程序 -- Mono ·熟悉.NET的人希望利用Java的优秀的服务器 -- Grasshopper (看这里的评论) ·熟悉.NET技术但希望降低软件成本,希望在Linux上部署ASP.NET应用 -- Mono ·熟悉Java的人希望迁移到.NET平台上 -- IKVM/Ja.NET ·.NET程序员希望以很小的成本使用Java已有的丰富的库 -- 同上 不止一次见到有人拿JRuby、Rhino之类的Java实现的脚本引擎用IKVM放到.NET上跑了……人家就是有这乐子 ·希望在程序中嵌入高级语言运行环境作为脚本或高级开发语言 -- Mono (看Second Life或者Unity) Mono虽然比不上一些主流的JVM先进,但它的执行速度好歹还是比CPython和CRuby这些脚本引擎快多了,自带的库也很丰富(同时也可根据需要裁剪),甚至有对SIMD、continuation等的支持 ·希望在资源极度受限的环境中用类型安全的语言、在托管环境中开发 -- Portable.NET (看这里提到的几个实例) ·Linux开发者希望借用.NET的理念在Linux上做开发 -- Mono 这是Miguel创始Mono计划的初衷,为了在Linux上能更方便的开发桌面应用之类的;他觉得C做这种事情太麻烦了。 好吧现在的话用Vala也可以…… ·自由软件世界的同志不愿意看到微软树立了行业标准(CLI、C#)而大摇大摆 -- Portable .NET 随便举了些场景的例子。大家都有自己的算盘,有自己的需求;如果某东西的成熟度正好能满足场景与需求,那就拿来用呗 >_<b |
|
返回顶楼 | |
发表时间:2010-01-05
Linux下开发桌面应用,QT是不是更适合?
|
|
返回顶楼 | |