United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6910618 C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
JDK-6910618 : C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")

Details
Type:
Bug
Submit Date:
2009-12-15
Status:
Resolved
Updated Date:
2012-02-01
Project Name:
JDK
Resolved Date:
2010-03-02
Component:
hotspot
OS:
solaris
Sub-Component:
compiler
CPU:
sparc
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs17 (b10)

Related Reports
Backport:
Backport:

Sub Tasks

Description
#  Internal Error (/tmp/jprt/P1/B/042139.kvn/source/src/share/vm/prims/jvm.cpp:246), pid=16752, tid=16
#  Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")

Fails when DeoptimizeALot is enabled.

Execution results:
http://sqeweb.sfbay/nfs/results/vm/gtee/JDK7/NIGHTLY/VM/2009-12-13/Comp_Baseline/vm/solaris-sparcv9/server/comp/solaris-sparcv9_server_comp_vm.gc.testlist/ResultDir/StringGC/
 
Affected tests:
gc/gctests/StringGC

                                    

Comments
EVALUATION

If deoptimization happened on the return from runtime call which allocate new object,
the obect's oop will be not updated during GC which could be triggered by scalar
replaced objects reallocation.

Deoptimization site:

6d8   B71: #	B117 B72 <- B9 B10  Freq: 0.00010103
6d8 + 	SET    precise klass [C: 0x000000010022ef58:Constant:exact *,R_O0	!ptr
6f8 + 	MOV    R_L1,R_O1	! spill
6fc   	CALL,static  ; NOP ==>  wrapper for: _new_array_Java
        # java.util.Arrays::copyOf @ bci:1  L[0]=R_I4 L[1]=R_L1 L[2]=_
        # java.lang.AbstractStringBuilder::expandCapacity @ bci:33  L[0]=#ScObj0 L[1]=R_L5 L[2]=R_L1 STK[0]=#ScObj0
        # ScObj0 java/lang/StringBuilder={ [count :0]=#0, [value :1]=R_I4 }
        # java.lang.AbstractStringBuilder::append @ bci:36  L[0]=#ScObj0 L[1]=R_I1 L[2]=R_L5 L[3]=R_L5
        # ScObj0 java/lang/StringBuilder={ [count :0]=#0, [value :1]=R_I4 }
        # java.lang.StringBuilder::append @ bci:2  L[0]=#ScObj0 L[1]=R_I1
        # ScObj0 java/lang/StringBuilder={ [count :0]=#0, [value :1]=R_I4 }
        # gc.gctests.StringGC.StringGC$StringAdder::run @ bci:12  L[0]=R_I0 STK[0]=R_I0
        # OopMap{L2=Oop L4=Oop I0=Oop I1=Oop I4=Oop off=1796}


OptoRuntime::new_array_C() will preserv the result oop:

  thread->set_vm_result(result);
  JRT_BLOCK_END;

but on the return from it the call wrapper will push the result oop to the register and then jump to deop blob

  // Runtime call returning oop in TLS?  Fetch it out
  if( pass_tls ) {
    Node* adr = basic_plus_adr(top(), thread, in_bytes(JavaThread::vm_result_offset()));
    Node* vm_result = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
    map()->set_req(TypeFunc::Parms, vm_result); // vm_result passed as result
    // clear thread-local-storage(tls)
    store_to_memory(NULL, adr, null(), T_ADDRESS, NoAlias);
  }

And the deopt blob does not know that the result was oop. It save all registers on stack but the result reguister
is not marked as oop in deopt_blob's oop map since it is common code.
                                     
2010-02-08
EVALUATION

ChangeSet=http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/f70b0d9ab095,ChangeRequest=6910618
                                     
2010-02-09
PUBLIC COMMENTS

Problem:
If deoptimization happened on the return from a call which
returns oop, the oop will be not updated during GC which
is triggered by scalar replaced objects reallocation.

Solution:
Mark in PcDesc call sites which return oop (this is main part of changes)
and save the result oop across objects reallocation during deoptimization.

Added regression test.
                                     
2010-02-09



Hardware and Software, Engineered to Work Together