< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page




4447 // we set the JVM state for uncommon traps between the allocation and
4448 // the arraycopy to the state before the allocation so, in case of
4449 // deoptimization, we'll reexecute the allocation and the
4450 // initialization.
4451 JVMState* LibraryCallKit::arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp) {
4452   if (alloc != NULL) {
4453     ciMethod* trap_method = alloc->jvms()->method();
4454     int trap_bci = alloc->jvms()->bci();
4455 
4456     if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) &
4457           !C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_null_check)) {
4458       // Make sure there's no store between the allocation and the
4459       // arraycopy otherwise visible side effects could be rexecuted
4460       // in case of deoptimization and cause incorrect execution.
4461       bool no_interfering_store = true;
4462       Node* mem = alloc->in(TypeFunc::Memory);
4463       if (mem->is_MergeMem()) {
4464         for (MergeMemStream mms(merged_memory(), mem->as_MergeMem()); mms.next_non_empty2(); ) {
4465           Node* n = mms.memory();
4466           if (n != mms.memory2() && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4467             assert(n->is_Store(), "what else?");
4468             no_interfering_store = false;
4469             break;
4470           }
4471         }
4472       } else {
4473         for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
4474           Node* n = mms.memory();
4475           if (n != mem && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4476             assert(n->is_Store(), "what else?");
4477             no_interfering_store = false;
4478             break;
4479           }
4480         }
4481       }
4482 
4483       if (no_interfering_store) {
4484         JVMState* old_jvms = alloc->jvms()->clone_shallow(C);
4485         uint size = alloc->req();
4486         SafePointNode* sfpt = new SafePointNode(size, old_jvms);
4487         old_jvms->set_map(sfpt);
4488         for (uint i = 0; i < size; i++) {
4489           sfpt->init_req(i, alloc->in(i));
4490         }
4491         // re-push array length for deoptimization
4492         sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength));
4493         old_jvms->set_sp(old_jvms->sp()+1);
4494         old_jvms->set_monoff(old_jvms->monoff()+1);
4495         old_jvms->set_scloff(old_jvms->scloff()+1);
4496         old_jvms->set_endoff(old_jvms->endoff()+1);




4447 // we set the JVM state for uncommon traps between the allocation and
4448 // the arraycopy to the state before the allocation so, in case of
4449 // deoptimization, we'll reexecute the allocation and the
4450 // initialization.
4451 JVMState* LibraryCallKit::arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp) {
4452   if (alloc != NULL) {
4453     ciMethod* trap_method = alloc->jvms()->method();
4454     int trap_bci = alloc->jvms()->bci();
4455 
4456     if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) &
4457           !C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_null_check)) {
4458       // Make sure there's no store between the allocation and the
4459       // arraycopy otherwise visible side effects could be rexecuted
4460       // in case of deoptimization and cause incorrect execution.
4461       bool no_interfering_store = true;
4462       Node* mem = alloc->in(TypeFunc::Memory);
4463       if (mem->is_MergeMem()) {
4464         for (MergeMemStream mms(merged_memory(), mem->as_MergeMem()); mms.next_non_empty2(); ) {
4465           Node* n = mms.memory();
4466           if (n != mms.memory2() && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4467             assert(n->is_Store() || n->Opcode() == Op_ShenandoahWBMemProj, "what else?");
4468             no_interfering_store = false;
4469             break;
4470           }
4471         }
4472       } else {
4473         for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
4474           Node* n = mms.memory();
4475           if (n != mem && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4476             assert(n->is_Store() || n->Opcode() == Op_ShenandoahWBMemProj, "what else?");
4477             no_interfering_store = false;
4478             break;
4479           }
4480         }
4481       }
4482 
4483       if (no_interfering_store) {
4484         JVMState* old_jvms = alloc->jvms()->clone_shallow(C);
4485         uint size = alloc->req();
4486         SafePointNode* sfpt = new SafePointNode(size, old_jvms);
4487         old_jvms->set_map(sfpt);
4488         for (uint i = 0; i < size; i++) {
4489           sfpt->init_req(i, alloc->in(i));
4490         }
4491         // re-push array length for deoptimization
4492         sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength));
4493         old_jvms->set_sp(old_jvms->sp()+1);
4494         old_jvms->set_monoff(old_jvms->monoff()+1);
4495         old_jvms->set_scloff(old_jvms->scloff()+1);
4496         old_jvms->set_endoff(old_jvms->endoff()+1);


< prev index next >