Mercurial > hg > truffle
comparison src/share/vm/opto/output.cpp @ 63:eac007780a58
6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
Summary: Values of non-static fields of a scalarized object should be saved in debug info to reallocate the object during deoptimization.
Reviewed-by: never
author | kvn |
---|---|
date | Thu, 13 Mar 2008 16:06:34 -0700 |
parents | 67914967a4b5 |
children | 6dbf1a175d6b |
comparison
equal
deleted
inserted
replaced
46:8b6e49187640 | 63:eac007780a58 |
---|---|
559 return (OptoReg::is_reg(regnum)) | 559 return (OptoReg::is_reg(regnum)) |
560 ? new LocationValue(Location::new_reg_loc(l_type, OptoReg::as_VMReg(regnum)) ) | 560 ? new LocationValue(Location::new_reg_loc(l_type, OptoReg::as_VMReg(regnum)) ) |
561 : new LocationValue(Location::new_stk_loc(l_type, ra->reg2offset(regnum))); | 561 : new LocationValue(Location::new_stk_loc(l_type, ra->reg2offset(regnum))); |
562 } | 562 } |
563 | 563 |
564 void Compile::FillLocArray( int idx, Node *local, GrowableArray<ScopeValue*> *array ) { | 564 |
565 ObjectValue* | |
566 Compile::sv_for_node_id(GrowableArray<ScopeValue*> *objs, int id) { | |
567 for (int i = 0; i < objs->length(); i++) { | |
568 assert(objs->at(i)->is_object(), "corrupt object cache"); | |
569 ObjectValue* sv = (ObjectValue*) objs->at(i); | |
570 if (sv->id() == id) { | |
571 return sv; | |
572 } | |
573 } | |
574 // Otherwise.. | |
575 return NULL; | |
576 } | |
577 | |
578 void Compile::set_sv_for_object_node(GrowableArray<ScopeValue*> *objs, | |
579 ObjectValue* sv ) { | |
580 assert(sv_for_node_id(objs, sv->id()) == NULL, "Precondition"); | |
581 objs->append(sv); | |
582 } | |
583 | |
584 | |
585 void Compile::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, | |
586 GrowableArray<ScopeValue*> *array, | |
587 GrowableArray<ScopeValue*> *objs ) { | |
565 assert( local, "use _top instead of null" ); | 588 assert( local, "use _top instead of null" ); |
566 if (array->length() != idx) { | 589 if (array->length() != idx) { |
567 assert(array->length() == idx + 1, "Unexpected array count"); | 590 assert(array->length() == idx + 1, "Unexpected array count"); |
568 // Old functionality: | 591 // Old functionality: |
569 // return | 592 // return |
575 return; | 598 return; |
576 } | 599 } |
577 array->pop(); | 600 array->pop(); |
578 } | 601 } |
579 const Type *t = local->bottom_type(); | 602 const Type *t = local->bottom_type(); |
603 | |
604 // Is it a safepoint scalar object node? | |
605 if (local->is_SafePointScalarObject()) { | |
606 SafePointScalarObjectNode* spobj = local->as_SafePointScalarObject(); | |
607 | |
608 ObjectValue* sv = Compile::sv_for_node_id(objs, spobj->_idx); | |
609 if (sv == NULL) { | |
610 ciKlass* cik = t->is_oopptr()->klass(); | |
611 assert(cik->is_instance_klass() || | |
612 cik->is_array_klass(), "Not supported allocation."); | |
613 sv = new ObjectValue(spobj->_idx, | |
614 new ConstantOopWriteValue(cik->encoding())); | |
615 Compile::set_sv_for_object_node(objs, sv); | |
616 | |
617 uint first_ind = spobj->first_index(); | |
618 for (uint i = 0; i < spobj->n_fields(); i++) { | |
619 Node* fld_node = sfpt->in(first_ind+i); | |
620 (void)FillLocArray(sv->field_values()->length(), sfpt, fld_node, sv->field_values(), objs); | |
621 } | |
622 } | |
623 array->append(sv); | |
624 return; | |
625 } | |
580 | 626 |
581 // Grab the register number for the local | 627 // Grab the register number for the local |
582 OptoReg::Name regnum = _regalloc->get_reg_first(local); | 628 OptoReg::Name regnum = _regalloc->get_reg_first(local); |
583 if( OptoReg::is_valid(regnum) ) {// Got a register/stack? | 629 if( OptoReg::is_valid(regnum) ) {// Got a register/stack? |
584 // Record the double as two float registers. | 630 // Record the double as two float registers. |
753 // Loop over the JVMState list to add scope information | 799 // Loop over the JVMState list to add scope information |
754 // Do not skip safepoints with a NULL method, they need monitor info | 800 // Do not skip safepoints with a NULL method, they need monitor info |
755 JVMState* youngest_jvms = sfn->jvms(); | 801 JVMState* youngest_jvms = sfn->jvms(); |
756 int max_depth = youngest_jvms->depth(); | 802 int max_depth = youngest_jvms->depth(); |
757 | 803 |
804 // Allocate the object pool for scalar-replaced objects -- the map from | |
805 // small-integer keys (which can be recorded in the local and ostack | |
806 // arrays) to descriptions of the object state. | |
807 GrowableArray<ScopeValue*> *objs = new GrowableArray<ScopeValue*>(); | |
808 | |
758 // Visit scopes from oldest to youngest. | 809 // Visit scopes from oldest to youngest. |
759 for (int depth = 1; depth <= max_depth; depth++) { | 810 for (int depth = 1; depth <= max_depth; depth++) { |
760 JVMState* jvms = youngest_jvms->of_depth(depth); | 811 JVMState* jvms = youngest_jvms->of_depth(depth); |
761 int idx; | 812 int idx; |
762 ciMethod* method = jvms->has_method() ? jvms->method() : NULL; | 813 ciMethod* method = jvms->has_method() ? jvms->method() : NULL; |
771 // Add Local and Expression Stack Information | 822 // Add Local and Expression Stack Information |
772 | 823 |
773 // Insert locals into the locarray | 824 // Insert locals into the locarray |
774 GrowableArray<ScopeValue*> *locarray = new GrowableArray<ScopeValue*>(num_locs); | 825 GrowableArray<ScopeValue*> *locarray = new GrowableArray<ScopeValue*>(num_locs); |
775 for( idx = 0; idx < num_locs; idx++ ) { | 826 for( idx = 0; idx < num_locs; idx++ ) { |
776 FillLocArray( idx, sfn->local(jvms, idx), locarray ); | 827 FillLocArray( idx, sfn, sfn->local(jvms, idx), locarray, objs ); |
777 } | 828 } |
778 | 829 |
779 // Insert expression stack entries into the exparray | 830 // Insert expression stack entries into the exparray |
780 GrowableArray<ScopeValue*> *exparray = new GrowableArray<ScopeValue*>(num_exps); | 831 GrowableArray<ScopeValue*> *exparray = new GrowableArray<ScopeValue*>(num_exps); |
781 for( idx = 0; idx < num_exps; idx++ ) { | 832 for( idx = 0; idx < num_exps; idx++ ) { |
782 FillLocArray( idx, sfn->stack(jvms, idx), exparray ); | 833 FillLocArray( idx, sfn, sfn->stack(jvms, idx), exparray, objs ); |
783 } | 834 } |
784 | 835 |
785 // Add in mappings of the monitors | 836 // Add in mappings of the monitors |
786 assert( !method || | 837 assert( !method || |
787 !method->is_synchronized() || | 838 !method->is_synchronized() || |
801 box_node = sfn->monitor_box(jvms, idx); | 852 box_node = sfn->monitor_box(jvms, idx); |
802 obj_node = sfn->monitor_obj(jvms, idx); | 853 obj_node = sfn->monitor_obj(jvms, idx); |
803 | 854 |
804 // Create ScopeValue for object | 855 // Create ScopeValue for object |
805 ScopeValue *scval = NULL; | 856 ScopeValue *scval = NULL; |
806 if( !obj_node->is_Con() ) { | 857 |
858 if( obj_node->is_SafePointScalarObject() ) { | |
859 SafePointScalarObjectNode* spobj = obj_node->as_SafePointScalarObject(); | |
860 scval = Compile::sv_for_node_id(objs, spobj->_idx); | |
861 if (scval == NULL) { | |
862 const Type *t = obj_node->bottom_type(); | |
863 ciKlass* cik = t->is_oopptr()->klass(); | |
864 assert(cik->is_instance_klass() || | |
865 cik->is_array_klass(), "Not supported allocation."); | |
866 ObjectValue* sv = new ObjectValue(spobj->_idx, | |
867 new ConstantOopWriteValue(cik->encoding())); | |
868 Compile::set_sv_for_object_node(objs, sv); | |
869 | |
870 uint first_ind = spobj->first_index(); | |
871 for (uint i = 0; i < spobj->n_fields(); i++) { | |
872 Node* fld_node = sfn->in(first_ind+i); | |
873 (void)FillLocArray(sv->field_values()->length(), sfn, fld_node, sv->field_values(), objs); | |
874 } | |
875 scval = sv; | |
876 } | |
877 } else if( !obj_node->is_Con() ) { | |
807 OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); | 878 OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node); |
808 scval = new_loc_value( _regalloc, obj_reg, Location::oop ); | 879 scval = new_loc_value( _regalloc, obj_reg, Location::oop ); |
809 } else { | 880 } else { |
810 scval = new ConstantOopWriteValue(obj_node->bottom_type()->is_instptr()->const_oop()->encoding()); | 881 scval = new ConstantOopWriteValue(obj_node->bottom_type()->is_instptr()->const_oop()->encoding()); |
811 } | 882 } |
812 | 883 |
813 OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node); | 884 OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node); |
814 monarray->append(new MonitorValue(scval, Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg)))); | 885 monarray->append(new MonitorValue(scval, Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg)))); |
815 } | 886 } |
816 | 887 |
888 // We dump the object pool first, since deoptimization reads it in first. | |
889 debug_info()->dump_object_pool(objs); | |
890 | |
817 // Build first class objects to pass to scope | 891 // Build first class objects to pass to scope |
818 DebugToken *locvals = debug_info()->create_scope_values(locarray); | 892 DebugToken *locvals = debug_info()->create_scope_values(locarray); |
819 DebugToken *expvals = debug_info()->create_scope_values(exparray); | 893 DebugToken *expvals = debug_info()->create_scope_values(exparray); |
820 DebugToken *monvals = debug_info()->create_monitor_values(monarray); | 894 DebugToken *monvals = debug_info()->create_monitor_values(monarray); |
821 | 895 |
822 // Make method available for all Safepoints | 896 // Make method available for all Safepoints |
823 ciMethod* scope_method = method ? method : _method; | 897 ciMethod* scope_method = method ? method : _method; |
824 // Describe the scope here | 898 // Describe the scope here |
825 assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI"); | 899 assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI"); |
900 // Now we can describe the scope. | |
826 debug_info()->describe_scope(safepoint_pc_offset,scope_method,jvms->bci(),locvals,expvals,monvals); | 901 debug_info()->describe_scope(safepoint_pc_offset,scope_method,jvms->bci(),locvals,expvals,monvals); |
827 } // End jvms loop | 902 } // End jvms loop |
828 | 903 |
829 // Mark the end of the scope set. | 904 // Mark the end of the scope set. |
830 debug_info()->end_safepoint(safepoint_pc_offset); | 905 debug_info()->end_safepoint(safepoint_pc_offset); |