src/share/vm/runtime/frame.cpp

Print this page
rev 4267 : 8009981: nashorn tests fail with -XX:+VerifyStack
Summary: nmethod::preserve_callee_argument_oops() must take appendix into account.
Reviewed-by:


 991     // Preserve potential arguments for a callee. We handle this by dispatching
 992     // on the codeblob. For c2i, we do
 993     if (reg_map->include_argument_oops()) {
 994       _cb->preserve_callee_argument_oops(*this, reg_map, f);
 995     }
 996   }
 997   // In cases where perm gen is collected, GC will want to mark
 998   // oops referenced from nmethods active on thread stacks so as to
 999   // prevent them from being collected. However, this visit should be
1000   // restricted to certain phases of the collection only. The
1001   // closure decides how it wants nmethods to be traced.
1002   if (cf != NULL)
1003     cf->do_code_blob(_cb);
1004 }
1005 
1006 class CompiledArgumentOopFinder: public SignatureInfo {
1007  protected:
1008   OopClosure*     _f;
1009   int             _offset;        // the current offset, incremented with each argument
1010   bool            _has_receiver;  // true if the callee has a receiver

1011   frame           _fr;
1012   RegisterMap*    _reg_map;
1013   int             _arg_size;
1014   VMRegPair*      _regs;        // VMReg list of arguments
1015 
1016   void set(int size, BasicType type) {
1017     if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset();
1018     _offset += size;
1019   }
1020 
1021   virtual void handle_oop_offset() {
1022     // Extract low order register number from register array.
1023     // In LP64-land, the high-order bits are valid but unhelpful.
1024     VMReg reg = _regs[_offset].first();
1025     oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
1026     _f->do_oop(loc);
1027   }
1028 
1029  public:
1030   CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr,  const RegisterMap* reg_map)
1031     : SignatureInfo(signature) {
1032 
1033     // initialize CompiledArgumentOopFinder
1034     _f         = f;
1035     _offset    = 0;
1036     _has_receiver = has_receiver;

1037     _fr        = fr;
1038     _reg_map   = (RegisterMap*)reg_map;
1039     _arg_size  = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
1040 
1041     int arg_size;
1042     _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size);
1043     assert(arg_size == _arg_size, "wrong arg size");
1044   }
1045 
1046   void oops_do() {
1047     if (_has_receiver) {
1048       handle_oop_offset();
1049       _offset++;
1050     }
1051     iterate_parameters();



1052   }
1053 };
1054 
1055 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
1056   ResourceMark rm;
1057   CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
1058   finder.oops_do();
1059 }
1060 
1061 
1062 // Get receiver out of callers frame, i.e. find parameter 0 in callers
1063 // frame.  Consult ADLC for where parameter 0 is to be found.  Then
1064 // check local reg_map for it being a callee-save register or argument
1065 // register, both of which are saved in the local frame.  If not found
1066 // there, it must be an in-stack argument of the caller.
1067 // Note: caller.sp() points to callee-arguments
1068 oop frame::retrieve_receiver(RegisterMap* reg_map) {
1069   frame caller = *this;
1070 
1071   // First consult the ADLC on where it puts parameter 0 for this signature.
1072   VMReg reg = SharedRuntime::name_for_receiver();
1073   oop* oop_adr = caller.oopmapreg_to_location(reg, reg_map);
1074   if (oop_adr == NULL) {
1075     guarantee(oop_adr != NULL, "bad register save location");
1076     return NULL;
1077   }




 991     // Preserve potential arguments for a callee. We handle this by dispatching
 992     // on the codeblob. For c2i, we do
 993     if (reg_map->include_argument_oops()) {
 994       _cb->preserve_callee_argument_oops(*this, reg_map, f);
 995     }
 996   }
 997   // In cases where perm gen is collected, GC will want to mark
 998   // oops referenced from nmethods active on thread stacks so as to
 999   // prevent them from being collected. However, this visit should be
1000   // restricted to certain phases of the collection only. The
1001   // closure decides how it wants nmethods to be traced.
1002   if (cf != NULL)
1003     cf->do_code_blob(_cb);
1004 }
1005 
1006 class CompiledArgumentOopFinder: public SignatureInfo {
1007  protected:
1008   OopClosure*     _f;
1009   int             _offset;        // the current offset, incremented with each argument
1010   bool            _has_receiver;  // true if the callee has a receiver
1011   bool            _has_appendix;  // true if the call has an appendix
1012   frame           _fr;
1013   RegisterMap*    _reg_map;
1014   int             _arg_size;
1015   VMRegPair*      _regs;        // VMReg list of arguments
1016 
1017   void set(int size, BasicType type) {
1018     if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset();
1019     _offset += size;
1020   }
1021 
1022   virtual void handle_oop_offset() {
1023     // Extract low order register number from register array.
1024     // In LP64-land, the high-order bits are valid but unhelpful.
1025     VMReg reg = _regs[_offset].first();
1026     oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
1027     _f->do_oop(loc);
1028   }
1029 
1030  public:
1031   CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr,  const RegisterMap* reg_map)
1032     : SignatureInfo(signature) {
1033 
1034     // initialize CompiledArgumentOopFinder
1035     _f         = f;
1036     _offset    = 0;
1037     _has_receiver = has_receiver;
1038     _has_appendix = has_appendix;
1039     _fr        = fr;
1040     _reg_map   = (RegisterMap*)reg_map;
1041     _arg_size  = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
1042 
1043     int arg_size;
1044     _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
1045     assert(arg_size == _arg_size, "wrong arg size");
1046   }
1047 
1048   void oops_do() {
1049     if (_has_receiver) {
1050       handle_oop_offset();
1051       _offset++;
1052     }
1053     iterate_parameters();
1054     if (_has_appendix) {
1055       handle_oop_offset();
1056     }
1057   }
1058 };
1059 
1060 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) {
1061   ResourceMark rm;
1062   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1063   finder.oops_do();
1064 }
1065 
1066 
1067 // Get receiver out of callers frame, i.e. find parameter 0 in callers
1068 // frame.  Consult ADLC for where parameter 0 is to be found.  Then
1069 // check local reg_map for it being a callee-save register or argument
1070 // register, both of which are saved in the local frame.  If not found
1071 // there, it must be an in-stack argument of the caller.
1072 // Note: caller.sp() points to callee-arguments
1073 oop frame::retrieve_receiver(RegisterMap* reg_map) {
1074   frame caller = *this;
1075 
1076   // First consult the ADLC on where it puts parameter 0 for this signature.
1077   VMReg reg = SharedRuntime::name_for_receiver();
1078   oop* oop_adr = caller.oopmapreg_to_location(reg, reg_map);
1079   if (oop_adr == NULL) {
1080     guarantee(oop_adr != NULL, "bad register save location");
1081     return NULL;
1082   }