Subscribe: IKVM.NET Weblog
Added By: Feedage Forager Feedage Grade B rated
Language: English
classpath  code  directory  eclipse  file  float int  float  ikvm net  ikvm  int  integer  java  mono  net  run  static  undefined 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: IKVM.NET Weblog


The development of a Java VM for .NET

Last Build Date: Tue, 01 Apr 2003 13:12:57 GMT

Copyright: Copyright 2003 Jeroen Frijters


Thu, 13 Mar 2003 12:37:28 GMT

Please excuse the mess, but we're moving today ;-)

New address:

RSS feed:

I hope to see you on the other side.

Yet another vacation

Wed, 05 Mar 2003 16:38:35 GMT

Tomorrow I'm off to Finland for a week of snow scooter fun :-)

I'll be back on the 14th.

Hello Mono (2)

Mon, 03 Mar 2003 09:57:22 GMT

C:\>mono --noinline --share-code c:\ikvm\bin\ikvm.exe hello
** Warning **: cannot find C:\cygwin\home\lalo\go-mono\install\
Trying to load app config file...
Hello World

The latest ikvm binaries together with Mono 0.21 now run Hello World!

Many thanks to everyone at Ximian, the Mono contributors and especially Zoltan Varga!

The --noinline and --share-code options are needed to work around a bug in the current Mono JIT that cause it to call the class constructors to eagerly.

I've updated the source and binaries snapshots.

Undefined behavio[u]r

Fri, 28 Feb 2003 09:56:00 GMT

While fixing bugs in ikvm to get more Mauve tests working (BTW, current results: 224 of 7584 tests failed), I ran across a small but interesting difference between Java and C# (and the underlying bytecodes) in converting floating point numbers to integers. Java code: class Test {  public static void main(String[] args) {    float f = Integer.MIN_VALUE;    f -= 5;    System.out.println((int)(f + 0.5f));  }} Java output: -2147483648 (= Integer.MIN_VALUE) C# code: class Test {  static void Main() {    float f = int.MinValue;    f -= 5;    System.Console.WriteLine((int)(f + 0.5f));  }} C# output (release build): 2147483644C# output (debug build): -2147483647 It turns out that the CIL instruction conv.i4 returns an undefined value when the float value lies outside of the range representable by an 32 bit integer, unlike the JVM's f2i instruction which is defined to return either Integer.MIN_VALUE or Integer.MAX_VALUE in that case. If you want your .NET code to run consistently, use the conv.ovf.i4 instruction that checks for overflow. In C# this can be done by using a checked block: class Test {  static void Main() {    float f = int.MinValue;    f -= 5;    checked {      System.Console.WriteLine((int)(f + 0.5f));    }  }} Now, instead of returning an undefined value, the cast throws a System.OverflowException. The JVM designers felt it was very important not to have any undefined or implementation defined behavior. One of the lessons learned from C and C++ is that whenever there is undefined or implementation defined behavior, code will be written that depends on the behavior of a particular platform/compiler. The JVM designers wanted to removed this source of portability problems. However, they payed a price in performance for this. A well known example is the case of floating point performance (on x86), which was later "fixed" by relaxing the floating point specification and introducing strictfp. As Morpheus would say: "Welcome to the real world!" (Don Box claims everything in computing can be understood by watching The Matrix enough times). Let's examine the performance of Java's f2i compared with .NET's conv.i4. Please note that the usual disclaimer wrt (micro) benchmarking applies. Here is the loop I used: float f = SOME_VALUE;for(int i = 0; i < 10000000; i++) {  int j = (int)f;  f = j;} Timings:     SOME_VALUE     0 +Infinity Sun JDK 1.1 (Symantec JIT) Float 600 ms 2000 ms Double* 800 ms 2300 ms Sun J2RE 1.4.1 (Hotspot Client VM) Float 600 ms 3800 ms Double* 1100 ms 2600 ms .NET 1.0 Float 500 ms 500 ms Double* 800 ms 800 ms .NET 1.0 (checked) Float 800 ms n/a Double* 1200 ms n/a * For the double test, the value was cast to a long instead of an int. Let's look at the code that the Symantec JIT uses to convert a float to an int:01F543F0  ftst             01F543F2  fldcw       word ptr ds:[1F5FB30h] 01F543F8  push        eax  01F543F9  fistp       dword ptr [esp] 01F543FC  fldcw       word ptr ds:[1F5FB34h] 01F54402  pop         eax  01F54403  cmp         eax,80000000h01F54408  je          01F5440B 01F5440A  ret              01F5440B  push        eax  01F5440C  fnstsw      ax   01F5440E  sahf       [...]


Sat, 15 Feb 2003 17:10:50 GMT

Zoltan has been working on running the Mauve testsuite on IKVM.NET running on Mono  and I've been doing the same on MS .NET.

Current status on MS .NET: 298 of 7338 tests failed
Current status on Mono: 143 of 3996 tests failed

Thanks to Mark for getting me started with Mauve and thanks to Zoltan for his excellent work on getting ikvm running on Mono.

Getting Eclipse to run

Wed, 12 Feb 2003 16:19:47 GMT

In the comments of the previous item John asked for specific instructions to get Eclipse running.

  1. Download the most recent IKVM binaries (I just updated them).
  2. Download Eclipse. I use build M3.
  3. Unzip both zip files. Here I will assume that both are unzipped in the root of C: (the ikvm zip creates an ikvm directory and all the Eclipse files end up in an eclipse directory)
  4. Download eclipse.bat, save it in the eclipse directory.
  5. Open a Command Prompt window and cd into the eclipse directory and run eclipse.bat

This should do the trick. If you have any problems, please let me know.


Finally back

Wed, 12 Feb 2003 11:46:52 GMT

I came across a class file that was the equivalent of the following source:

class Test
    public static final int FOO = 1;

    static {
        FOO = 1;

This isn't legal Java, but the class file equivalent is. The FOO field has a ConstValue attribute with the value 1 and then there is code in the static initializer to set the value again. The code in the static initializer isn't needed and the Java compilers I've seen so far don't emit it.

Anyway, IKVM handles assignments to (non-blank) final fields by just ignoring the assignment, but my code generator emitted a nop instruction, instead of a pop (because it should consume the value on the stack). Fixed.

GNU Classpath is about to release version 0.05, so I got their code from cvs and updated my native methods to work with the latest code (the only changes required were for Object[In][Out]putStream, because Mark cleaned those up to use less native code, a nice improvement!). There was still one remaining issue with compiling the classpath code with ikvmc, I had to comment out a line of code in java/nio/charset/

  public final ByteBuffer encode (String str)
    return encode (CharBuffer.wrap (str));

CharBuffer.wrap takes an CharSequence as its argument, but my java.lang.String doesn't implement CharSequence (yet). It occurred to me that since it is legal for any reference type to be passed where an interface is expected (see here) this code was legal as well (even if String doesn't implement CharSequence), so I added support to the compiler to insert casts when the arguments on the stack do not match with the expected method arguments (but only for interface references).

Finally, there is still one patch required to Classpath, because new File("c://") hangs:

RCS file: /cvsroot/classpath/classpath/java/io/,v
retrieving revision 1.21
diff -r1.21
< if (!PlatformHelper.isRootDirectory(path))
< while (PlatformHelper.endWithSeparator(path))
> while (!PlatformHelper.isRootDirectory(path) &&
> PlatformHelper.endWithSeparator(path))

You wouldn't expect this to be a common occurrence, but it turns out that this exact path is constructed by the code that computes the current directory, so if you use ikvm to run a Java application in the root directory of a drive it hangs (without this patch).


Hello Mono

Fri, 17 Jan 2003 20:04:28 GMT

Zoltan Varga wrote on the ikvm-developers list:

   After lots of hacking, I managed to get IKVM to run HelloWorld under mono. This involved lots of changes/bugfixes to IKVM, the mono runtime and the class libs. I intend to submit a big patch to the mono mailing list shortly with the changes.

Great news!

Unrelated to the above, I checked in a bunch of changes and updated the source and binary snapshots. I'll be out of the country for two weeks, so there probably won't be much activity.