Crazy bytecode madness...

Ive been thinking about writing Java bytecodes directly (using one of the Java assemblers out there) and just want to ask if anyone knows whether this will work:

Can I push a float value onto the stack, and then pop it off & use it as an int?

Does the VM ever check this sort of thing?

If it works, then there are a few sneaky optimisations I can make for a few maths functions (sqrt in particular) as well as doubling the speed of my 3D vertex transform & clip. (& I would definately like an inline bytecode assembler in the java compiler if you can!)

  • Dom

Hmm. I dunno. Type safety may be built into the machine for security reasons. Even if the VM allows it the byte code verifier may barf on it.

try it and see…

[quote]Ive been thinking about writing Java bytecodes directly (using one of the Java assemblers out there) and just want to ask if anyone knows whether this will work:
[/quote]
Forget it. Writing Java bytecode by hand for optimization purposes is a worthless endeavor. Java bytecode is useful in generative techniques, where you’re writing a compiler for a language that targets the Java VM, or developing an aspecting system (ala AspectWerkz/AspectJ) / rolling your own aspects. Occassionally you might write some bytecode by hand for correctness purposes - like invoking a MonitorEnter without a corresponding MonitorExit for a self-written mutex class.

[quote]Can I push a float value onto the stack, and then pop it off & use it as an int?
[/quote]
Nope. The verifier will check this the moment it loads your class file. If it didn’t there’d be security loopholes in the VM. Sun’s verifier is a piece of crap, in that it doesn’t give you much information when verification fails. You can use BCEL’s verifier, Justice, for much better error messages. Unfortunately, Justice has some quirks in that certain classes pass Sun’s verifier while failing Justice.

God bless,
-Toby Reyelts

[quote]Nope. The verifier will check this the moment it loads your class file
[/quote]
Ok… How does the floatToIntBits() work then? I would be upset if it took more than a couple of bytecodes - or then again would the JIT compiler convert this down to pretty much a move from float to int register anyway?

The reason I ask is because I am writing my inner loop for a transform & clip function, and I know I should be able to generate clipping flags during the stall for the z divide, providing that the floatToIntBits does not use any floating point operations at all.

Thanks for the comments,

  • Dom

Dom,

floatToIntBits() is a JNI call, once you have the value in C or C++ you can do what you like to it.

Although you should still adhere to sun’s type definition, so most likely the value is loaded into a jvalue as a jfloat and then read out as an jint. This is exactly how Kaffe does it:


Extract taken from Fp.c of Kaffe 1.0.7.

/*
 * Convert float to int.
 */
jint
floatToInt(jfloat val)
{
        jvalue d;

      d.f = val;
      return d.i;
}


Extract from Sun's JNI header file shipped with SDK1.3 jni.h

typedef union jvalue {
    jboolean z;
    jbyte    b;
    jchar    c;
    jshort   s;
    jint     i;
    jlong    j;
    jfloat   f;
    jdouble  d;
    jobject  l;
} jvalue;


Although the couple hundered clock cycles required to make the JNI call make this unsuitable for your inner loop as the Divide is considerably less.

Hope that helps,

Woz.

[quote]Dom,

floatToIntBits() is a JNI call, once you have the value in C or C++ you can do what you like to it.
[/quote]
It might look like a JNI call, but the JIT could easily optimise that away. There is no way of telling without the source to the JIT or timing it. Just like many of the methods in the Math class are routinely replaced by inline equivalents.

You know that you can get the source to HotSpot for free right? You just have to agree to some license with a click of a mouse.

Of course it’s allowed to convert between float<->int in that way. How can that be a security problem anyway? float and int are same fundamental type but with different semantics.

  • elias

Its a JNI call?!?

Its in the Java 1.1 spec as java.lang.Float.floatToIntBits()

  • Dom

If you look in the source from java.lang.Float:

public static native int floatToIntBits(float value);

(native = JNI :))

[quote]If you look in the source from java.lang.Float:

public static native int floatToIntBits(float value);

(native = JNI :))
[/quote]
Likewise the source for java.lang.Math appears to delegate many methods to StrictMath, but this is not necessarily what actually happens inside the JVM. In fact Math.sin for example apparently uses the argument reduction that would be used by StrictMath but the actual sin is computed using the Intel instruction. As I said before to determine what really happens you have to look at the JVM source, or deduce it from timing information. In all cases the specification requires that the result value have certain properties but does not require the JVM to obtain the result in any particular way.

Also see the comments in the “implementation” of Math.sqrt()

Mark’s right that the VM recognizes the basic math calls and “cheats” doign them directly in-line in compiled code :slight_smile:

Thsi is the same kind of mechanism that is used for native Byte Buffers :slight_smile:

Ok - Any idea whether the VM ‘cheats’ (as you put it) with the floatToIntBits?

  • Dom

Noob question: Where do I get the source code for these bits ???

At a guess probably not as its not a call that I woudl have expected to geta lot of use… OTOH if the VM guys needed it for the center of a loo pthen it might.

Best way to find out is to gag microbenchmark it and see if the result loosk like a JNI call in terms of time or if its faster :slight_smile: