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); |