JDK-6910618 : C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 7
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris
  • CPU: sparc
  • Submitted: 2009-12-15
  • Updated: 2014-07-07
  • Resolved: 2010-03-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u21Fixed 7Fixed hs17Fixed
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
A similar failure, triggered because the orphaned oop is not live in the optimized code.
07-07-2014

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.
09-02-2010

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

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.
08-02-2010