< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page
rev 54386 : 8221766: Load-reference barriers for Shenandoah


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


< prev index next >