If I compile with sdk1.4.0 or 1.3.1 the following java application :
public class HelloWorld {
> public static void main(String arg[]) {
> for(int number=0;number<=1000;number++)
> {
> new HelloWorld();
> }
> }
> }
I got the following bytecodes for the main method :
Method 1:
0000dd 0009 access flags = 9
0000df 0009 name = #9<main>
0000e1 000a descriptor = #10<([Ljava/lang/String;)V>
0000e3 0001 1 field/method attributes:
field/method attribute 0
0000e5 0007 name = #7<Code>
0000e7 0000003c length = 60
0000eb 0002 max stack: 2
0000ed 0002 max locals: 2
0000ef 00000018 code length: 24
0000f3 03 0 iconst_0
0000f4 3c 1 istore_1
0000f5 a7000e 2 goto 16
0000f8 bb0002 5 new #2
0000fb 59 8 dup
0000fc b70003 9 invokespecial #3
0000ff 57 12 pop
000100 840101 15 iinc 1 1
000103 1b 16 iload_1
000104 1103e8 17 sipush 1000
000107 a4fff1 20 if_icmple 65541
00010a b1 23 return
00010b 0000 0 exception table entries:
I don't understand the presence of the opcodes 'dup' and 'pop' repectly
before and after invokespecial #3
invokespecial call the <init()>V method which call the <init()>V method
of lava.lang.Object. But both methods don't take any argument. And 'new
#2' pushes the reference to the new object in the operand stack.
Why do we need to duplicate the reference before invokespecial ?, if
it's to pop the operand stack just after ?
Thanks
Sébastien
David Zimmerman - 04 Sep 2003 15:27 GMT
> If I compile with sdk1.4.0 or 1.3.1 the following java application :
>
[quoted text clipped - 47 lines]
> Thanks
> Sébastien
The call to the constructor (the 'invokespecial') consumes the object
reference on the stack. If you were assigning or otherwise using the
object reference you get from the 'new HelloWorld()', then the bytecode
had better 'dup' it before calling the constructor. Not using the
reference is the exception so my guess is that 'new <class>()' always
compiles to using the 'dup'. Since your code doesn't use the reference,
it needs to be disposed of with the 'pop'.
Michael Amling - 04 Sep 2003 15:56 GMT
> If I compile with sdk1.4.0 or 1.3.1 the following java application :
>
[quoted text clipped - 44 lines]
> Why do we need to duplicate the reference before invokespecial ?, if
> it's to pop the operand stack just after ?
I got the same assembly code compiling with javac (with or without
-O), but jikes does not emit the spurious dup and pop:
Method void main(java.lang.String[])
0 iconst_0
1 istore_1
2 goto 14
5 new #1 <Class HelloWorld>
8 invokespecial #12 <Method HelloWorld()>
11 iinc 1 1
14 iload_1
15 sipush 1000
18 if_icmple 5
21 return
--Mike Amling
Roedy Green - 04 Sep 2003 17:31 GMT
>0000f8 bb0002 5 new #2
>0000fb 59 8 dup
>0000fc b70003 9 invokespecial #3
>0000ff 57 12 pop
I have not checked the byte code docs to be sure, but I guess this is
what is happening:
new allocates space.
invokespecial is calling the constructor. The constructor needs the
address of the object to construct. 99% of the time, when you are
done constructing, you do something with the reference, either use it
to call a method or store it somewhere. In your case, you did the
unusual thing of creating an object and immediately discarding it.
So the mindless Java compiler speculatively does a dup, thinking it
will need the value. Later it discovers it did not need it after all,
and drops it. (pop in JVM terminology). It figures the hotspot will
notice and optimise the dup/pop out of existence.
--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.