4468 // we set the JVM state for uncommon traps between the allocation and
4469 // the arraycopy to the state before the allocation so, in case of
4470 // deoptimization, we'll reexecute the allocation and the
4471 // initialization.
4472 JVMState* LibraryCallKit::arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp) {
4473 if (alloc != NULL) {
4474 ciMethod* trap_method = alloc->jvms()->method();
4475 int trap_bci = alloc->jvms()->bci();
4476
4477 if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) &
4478 !C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_null_check)) {
4479 // Make sure there's no store between the allocation and the
4480 // arraycopy otherwise visible side effects could be rexecuted
4481 // in case of deoptimization and cause incorrect execution.
4482 bool no_interfering_store = true;
4483 Node* mem = alloc->in(TypeFunc::Memory);
4484 if (mem->is_MergeMem()) {
4485 for (MergeMemStream mms(merged_memory(), mem->as_MergeMem()); mms.next_non_empty2(); ) {
4486 Node* n = mms.memory();
4487 if (n != mms.memory2() && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4488 assert(n->is_Store() || n->Opcode() == Op_ShenandoahWBMemProj, "what else?");
4489 no_interfering_store = false;
4490 break;
4491 }
4492 }
4493 } else {
4494 for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
4495 Node* n = mms.memory();
4496 if (n != mem && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4497 assert(n->is_Store() || n->Opcode() == Op_ShenandoahWBMemProj, "what else?");
4498 no_interfering_store = false;
4499 break;
4500 }
4501 }
4502 }
4503
4504 if (no_interfering_store) {
4505 JVMState* old_jvms = alloc->jvms()->clone_shallow(C);
4506 uint size = alloc->req();
4507 SafePointNode* sfpt = new SafePointNode(size, old_jvms);
4508 old_jvms->set_map(sfpt);
4509 for (uint i = 0; i < size; i++) {
4510 sfpt->init_req(i, alloc->in(i));
4511 }
4512 // re-push array length for deoptimization
4513 sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength));
4514 old_jvms->set_sp(old_jvms->sp()+1);
4515 old_jvms->set_monoff(old_jvms->monoff()+1);
4516 old_jvms->set_scloff(old_jvms->scloff()+1);
4517 old_jvms->set_endoff(old_jvms->endoff()+1);
|
4468 // we set the JVM state for uncommon traps between the allocation and
4469 // the arraycopy to the state before the allocation so, in case of
4470 // deoptimization, we'll reexecute the allocation and the
4471 // initialization.
4472 JVMState* LibraryCallKit::arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp) {
4473 if (alloc != NULL) {
4474 ciMethod* trap_method = alloc->jvms()->method();
4475 int trap_bci = alloc->jvms()->bci();
4476
4477 if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) &
4478 !C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_null_check)) {
4479 // Make sure there's no store between the allocation and the
4480 // arraycopy otherwise visible side effects could be rexecuted
4481 // in case of deoptimization and cause incorrect execution.
4482 bool no_interfering_store = true;
4483 Node* mem = alloc->in(TypeFunc::Memory);
4484 if (mem->is_MergeMem()) {
4485 for (MergeMemStream mms(merged_memory(), mem->as_MergeMem()); mms.next_non_empty2(); ) {
4486 Node* n = mms.memory();
4487 if (n != mms.memory2() && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4488 assert(n->is_Store(), "what else?");
4489 no_interfering_store = false;
4490 break;
4491 }
4492 }
4493 } else {
4494 for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
4495 Node* n = mms.memory();
4496 if (n != mem && !(n->is_Proj() && n->in(0) == alloc->initialization())) {
4497 assert(n->is_Store(), "what else?");
4498 no_interfering_store = false;
4499 break;
4500 }
4501 }
4502 }
4503
4504 if (no_interfering_store) {
4505 JVMState* old_jvms = alloc->jvms()->clone_shallow(C);
4506 uint size = alloc->req();
4507 SafePointNode* sfpt = new SafePointNode(size, old_jvms);
4508 old_jvms->set_map(sfpt);
4509 for (uint i = 0; i < size; i++) {
4510 sfpt->init_req(i, alloc->in(i));
4511 }
4512 // re-push array length for deoptimization
4513 sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength));
4514 old_jvms->set_sp(old_jvms->sp()+1);
4515 old_jvms->set_monoff(old_jvms->monoff()+1);
4516 old_jvms->set_scloff(old_jvms->scloff()+1);
4517 old_jvms->set_endoff(old_jvms->endoff()+1);
|