Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4151449
Votes 3
Synopsis (1.1) Trap in interpreter due to bytecode rewriting
Category java:runtime
Reported Against 1.1.6 , 1.1.8 , 1.2.2
Release Fixed
State 11-Closed, Not Reproducible, bug
Priority: 4-Low
Related Bugs 4152757 , 4169736 , 4265842 , 4337029
Submit Date 23-JUN-1998
Description




A trap occured when debugging a defect, running
execution04501 on an SMP machine.

Initial analysis showed the following cause.

Thread 8 trapped executing opc_invokenonvirtual_quick

The reason was the the constant pool reference was wrong:

        case opc_invokenonvirtual_quick:
            mb = constant_pool[GET_INDEX(pc + 1)].mb;   <=== trap here
            args_size = mb->args_size;
            optop -= args_size;
            frame->returnpc = pc + 3;
            o = S_HANDLE(0);
            if (o == 0)
                JAVA_ERROR("NullPointerException", 0);
            goto callmethod;

PC = 0D677EC1
dump
0D677EC0 2A DC 01 01 B1
aload_0
invokeignored_quick
return

but the code is actually in a switch statement for invokenonvirtual_quick

This code seems to be for the <init> method of execution04501b

However thread 4 is also executing this code at this address,
and has just finished rewriting the byte codes.

The problem seems to be that one thread starts to execute a
invokespecial opcode, and resolves the method reference from the constant
pool and rewrites it as a invokenonvirtual_quick.

A second thread starts to execute the invokenonvirtual_quick opcode and gets
as far as doing the switch statement on the opcode.

The first thread then continues to run, and rewrites the target method
as inline code, and then updates and replaces the invoke call.  In this case
the code doesn't do anything (as it is the defaualt constructor from Object),
so it is rewritten as invokeignore_quick.  The parameters are changes to
01 01, indicating 1 argument, and the  customer  reference should be checked
as being non-null.

The second thread the continues to execute, and reads the 01 01 as an index
into the constant pool for the invokenonvirtual_quick  customer .

This then traps.

Disabling inlining by returning NO_INLINING_FLAG from
static unsigned long
MethodInlining(struct methodblock *mb) {

may reduce the problem.


The problem occurred about 1 in 3-4 times without the fix.
With the fix, it ran 5 times OK, then hung on the 6th.

This was because thread 6 was blocked on CODE_LOCK.
The only other threads were 1,2,3.

Javasoft seem to have allowed for code rewriting by testing the opcode
compared to the first reading, (after having read the rest of the
operands of the instruction) then retrying the loop again with
a SIZE_AND_STACK(0, 0)

Even if the JVM tested the opcode again just before reading the operand
then this may not be safe, as if code is updated with a memcpy() inside a
CODE_LOCK() CODE_UNLOCK() pair, then the update using memcpy is
still not atomic if the opcodes are read outside a CODE_LOCK() block.

Code that can be rewritten perhaps includes any of the following
opcodes:

opc_invokenonvirtual_quick
opc_invokesuper_quick
opc_invokevirtual_quick_w
opc_invokestatic_quick
opc_invokeinterface_quick
opc_invokevirtualobject_quick

See Sun bug 4066650, reported against 1.2

This was reported as fixed in 1.2Beta2

Sun said that this was reproduced in 1.1, but there
is no reference to a fix at this level.

I am not sure if this solves the problem, or just tries to do the rewriting
early, when we still have a code lock and the opcode has not been rewritten
to a quick instruction.  Rewriting could be safe at that point, but not
after the quick rewrite, as someone else could execute the instruction
without locking.

Also, bug 4077463 may be relevant

This needs to be fixed in the 1.1.x level





======================================================================
Work Around
N/A
Evaluation
Simply making FixupQuickInvocation into an empty method should get rid of the problem.  Are you specifically requesting that we put a fix for this into 1.1.7?  If we do it I'd recommend just removing the entire bytecode inliner.  Any opinions on that?
  xxxxx@xxxxx   1998-07-30

The test case passed 1.2.2_013 ~ 1.2.2_015 latest. So it's been fixed in those versions. 

  xxxxx@xxxxx   2003-04-07
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang