hotspot/src/share/vm/runtime/frame.cpp
changeset 4567 7fc02fbe5c7a
parent 3908 24b55ad4c228
child 4573 6358f8c9ed3b
equal deleted inserted replaced
4566:b363f6ef4068 4567:7fc02fbe5c7a
     1 /*
     1 /*
     2  * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   767 };
   767 };
   768 
   768 
   769 
   769 
   770 class InterpretedArgumentOopFinder: public SignatureInfo {
   770 class InterpretedArgumentOopFinder: public SignatureInfo {
   771  private:
   771  private:
   772   OopClosure* _f;      // Closure to invoke
   772   OopClosure* _f;        // Closure to invoke
   773   int    _offset;      // TOS-relative offset, decremented with each argument
   773   int    _offset;        // TOS-relative offset, decremented with each argument
   774   bool   _is_static;   // true if the callee is a static method
   774   bool   _has_receiver;  // true if the callee has a receiver
   775   frame* _fr;
   775   frame* _fr;
   776 
   776 
   777   void set(int size, BasicType type) {
   777   void set(int size, BasicType type) {
   778     _offset -= size;
   778     _offset -= size;
   779     if (type == T_OBJECT || type == T_ARRAY) oop_offset_do();
   779     if (type == T_OBJECT || type == T_ARRAY) oop_offset_do();
   784     addr = (oop*)_fr->interpreter_frame_tos_at(_offset);
   784     addr = (oop*)_fr->interpreter_frame_tos_at(_offset);
   785     _f->do_oop(addr);
   785     _f->do_oop(addr);
   786   }
   786   }
   787 
   787 
   788  public:
   788  public:
   789   InterpretedArgumentOopFinder(symbolHandle signature, bool is_static, frame* fr, OopClosure* f) : SignatureInfo(signature) {
   789   InterpretedArgumentOopFinder(symbolHandle signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) {
   790     // compute size of arguments
   790     // compute size of arguments
   791     int args_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
   791     int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
   792     assert(!fr->is_interpreted_frame() ||
   792     assert(!fr->is_interpreted_frame() ||
   793            args_size <= fr->interpreter_frame_expression_stack_size(),
   793            args_size <= fr->interpreter_frame_expression_stack_size(),
   794             "args cannot be on stack anymore");
   794             "args cannot be on stack anymore");
   795     // initialize InterpretedArgumentOopFinder
   795     // initialize InterpretedArgumentOopFinder
   796     _f         = f;
   796     _f         = f;
   797     _fr        = fr;
   797     _fr        = fr;
   798     _offset    = args_size;
   798     _offset    = args_size;
   799     _is_static = is_static;
       
   800   }
   799   }
   801 
   800 
   802   void oops_do() {
   801   void oops_do() {
   803     if (!_is_static) {
   802     if (_has_receiver) {
   804       --_offset;
   803       --_offset;
   805       oop_offset_do();
   804       oop_offset_do();
   806     }
   805     }
   807     iterate_parameters();
   806     iterate_parameters();
   808   }
   807   }
   910   }
   909   }
   911 
   910 
   912   int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
   911   int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
   913 
   912 
   914   symbolHandle signature;
   913   symbolHandle signature;
   915   bool is_static = false;
   914   bool has_receiver = false;
   916 
   915 
   917   // Process a callee's arguments if we are at a call site
   916   // Process a callee's arguments if we are at a call site
   918   // (i.e., if we are at an invoke bytecode)
   917   // (i.e., if we are at an invoke bytecode)
   919   // This is used sometimes for calling into the VM, not for another
   918   // This is used sometimes for calling into the VM, not for another
   920   // interpreted or compiled frame.
   919   // interpreted or compiled frame.
   921   if (!m->is_native()) {
   920   if (!m->is_native()) {
   922     Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci);
   921     Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci);
   923     if (call != NULL) {
   922     if (call != NULL) {
   924       signature = symbolHandle(thread, call->signature());
   923       signature = symbolHandle(thread, call->signature());
   925       is_static = call->is_invokestatic();
   924       has_receiver = call->has_receiver();
   926       if (map->include_argument_oops() &&
   925       if (map->include_argument_oops() &&
   927           interpreter_frame_expression_stack_size() > 0) {
   926           interpreter_frame_expression_stack_size() > 0) {
   928         ResourceMark rm(thread);  // is this right ???
   927         ResourceMark rm(thread);  // is this right ???
   929         // we are at a call site & the expression stack is not empty
   928         // we are at a call site & the expression stack is not empty
   930         // => process callee's arguments
   929         // => process callee's arguments
   934         //       cases we empty the expression stack completely be-
   933         //       cases we empty the expression stack completely be-
   935         //       fore handling the exception (the exception handling
   934         //       fore handling the exception (the exception handling
   936         //       code in the interpreter calls a blocking runtime
   935         //       code in the interpreter calls a blocking runtime
   937         //       routine which can cause this code to be executed).
   936         //       routine which can cause this code to be executed).
   938         //       (was bug gri 7/27/98)
   937         //       (was bug gri 7/27/98)
   939         oops_interpreted_arguments_do(signature, is_static, f);
   938         oops_interpreted_arguments_do(signature, has_receiver, f);
   940       }
   939       }
   941     }
   940     }
   942   }
   941   }
   943 
   942 
   944   if (TaggedStackInterpreter) {
   943   if (TaggedStackInterpreter) {
   948     InterpreterOopMap oopmap_mask;
   947     InterpreterOopMap oopmap_mask;
   949     OopMapCache::compute_one_oop_map(m, bci, &oopmap_mask);
   948     OopMapCache::compute_one_oop_map(m, bci, &oopmap_mask);
   950     mask = &oopmap_mask;
   949     mask = &oopmap_mask;
   951 #endif // ASSERT
   950 #endif // ASSERT
   952     oops_interpreted_locals_do(f, max_locals, mask);
   951     oops_interpreted_locals_do(f, max_locals, mask);
   953     oops_interpreted_expressions_do(f, signature, is_static,
   952     oops_interpreted_expressions_do(f, signature, has_receiver,
   954                                     m->max_stack(),
   953                                     m->max_stack(),
   955                                     max_locals, mask);
   954                                     max_locals, mask);
   956   } else {
   955   } else {
   957     InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
   956     InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
   958 
   957 
   990   }
   989   }
   991 }
   990 }
   992 
   991 
   993 void frame::oops_interpreted_expressions_do(OopClosure *f,
   992 void frame::oops_interpreted_expressions_do(OopClosure *f,
   994                                       symbolHandle signature,
   993                                       symbolHandle signature,
   995                                       bool is_static,
   994                                       bool has_receiver,
   996                                       int max_stack,
   995                                       int max_stack,
   997                                       int max_locals,
   996                                       int max_locals,
   998                                       InterpreterOopMap *mask) {
   997                                       InterpreterOopMap *mask) {
   999   // There is no stack no matter what the esp is pointing to (native methods
   998   // There is no stack no matter what the esp is pointing to (native methods
  1000   // might look like expression stack is nonempty).
   999   // might look like expression stack is nonempty).
  1003   // Point the top of the expression stack above arguments to a call so
  1002   // Point the top of the expression stack above arguments to a call so
  1004   // arguments aren't gc'ed as both stack values for callee and callee
  1003   // arguments aren't gc'ed as both stack values for callee and callee
  1005   // arguments in callee's locals.
  1004   // arguments in callee's locals.
  1006   int args_size = 0;
  1005   int args_size = 0;
  1007   if (!signature.is_null()) {
  1006   if (!signature.is_null()) {
  1008     args_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
  1007     args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
  1009   }
  1008   }
  1010 
  1009 
  1011   intptr_t *tos_addr = interpreter_frame_tos_at(args_size);
  1010   intptr_t *tos_addr = interpreter_frame_tos_at(args_size);
  1012   assert(args_size != 0 || tos_addr == interpreter_frame_tos_address(), "these are same");
  1011   assert(args_size != 0 || tos_addr == interpreter_frame_tos_address(), "these are same");
  1013   intptr_t *frst_expr = interpreter_frame_expression_stack_at(0);
  1012   intptr_t *frst_expr = interpreter_frame_expression_stack_at(0);
  1036 #endif // ASSERT
  1035 #endif // ASSERT
  1037     }
  1036     }
  1038   }
  1037   }
  1039 }
  1038 }
  1040 
  1039 
  1041 void frame::oops_interpreted_arguments_do(symbolHandle signature, bool is_static, OopClosure* f) {
  1040 void frame::oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f) {
  1042   InterpretedArgumentOopFinder finder(signature, is_static, this, f);
  1041   InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
  1043   finder.oops_do();
  1042   finder.oops_do();
  1044 }
  1043 }
  1045 
  1044 
  1046 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) {
  1045 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) {
  1047   assert(_cb != NULL, "sanity check");
  1046   assert(_cb != NULL, "sanity check");
  1064 }
  1063 }
  1065 
  1064 
  1066 class CompiledArgumentOopFinder: public SignatureInfo {
  1065 class CompiledArgumentOopFinder: public SignatureInfo {
  1067  protected:
  1066  protected:
  1068   OopClosure*     _f;
  1067   OopClosure*     _f;
  1069   int             _offset;      // the current offset, incremented with each argument
  1068   int             _offset;        // the current offset, incremented with each argument
  1070   bool            _is_static;   // true if the callee is a static method
  1069   bool            _has_receiver;  // true if the callee has a receiver
  1071   frame           _fr;
  1070   frame           _fr;
  1072   RegisterMap*    _reg_map;
  1071   RegisterMap*    _reg_map;
  1073   int             _arg_size;
  1072   int             _arg_size;
  1074   VMRegPair*      _regs;        // VMReg list of arguments
  1073   VMRegPair*      _regs;        // VMReg list of arguments
  1075 
  1074 
  1085     oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
  1084     oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
  1086     _f->do_oop(loc);
  1085     _f->do_oop(loc);
  1087   }
  1086   }
  1088 
  1087 
  1089  public:
  1088  public:
  1090   CompiledArgumentOopFinder(symbolHandle signature, bool is_static, OopClosure* f, frame fr,  const RegisterMap* reg_map)
  1089   CompiledArgumentOopFinder(symbolHandle signature, bool has_receiver, OopClosure* f, frame fr,  const RegisterMap* reg_map)
  1091     : SignatureInfo(signature) {
  1090     : SignatureInfo(signature) {
  1092 
  1091 
  1093     // initialize CompiledArgumentOopFinder
  1092     // initialize CompiledArgumentOopFinder
  1094     _f         = f;
  1093     _f         = f;
  1095     _offset    = 0;
  1094     _offset    = 0;
  1096     _is_static = is_static;
  1095     _has_receiver = has_receiver;
  1097     _fr        = fr;
  1096     _fr        = fr;
  1098     _reg_map   = (RegisterMap*)reg_map;
  1097     _reg_map   = (RegisterMap*)reg_map;
  1099     _arg_size  = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
  1098     _arg_size  = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
  1100 
  1099 
  1101     int arg_size;
  1100     int arg_size;
  1102     _regs = SharedRuntime::find_callee_arguments(signature(), is_static, &arg_size);
  1101     _regs = SharedRuntime::find_callee_arguments(signature(), has_receiver, &arg_size);
  1103     assert(arg_size == _arg_size, "wrong arg size");
  1102     assert(arg_size == _arg_size, "wrong arg size");
  1104   }
  1103   }
  1105 
  1104 
  1106   void oops_do() {
  1105   void oops_do() {
  1107     if (!_is_static) {
  1106     if (_has_receiver) {
  1108       handle_oop_offset();
  1107       handle_oop_offset();
  1109       _offset++;
  1108       _offset++;
  1110     }
  1109     }
  1111     iterate_parameters();
  1110     iterate_parameters();
  1112   }
  1111   }
  1113 };
  1112 };
  1114 
  1113 
  1115 void frame::oops_compiled_arguments_do(symbolHandle signature, bool is_static, const RegisterMap* reg_map, OopClosure* f) {
  1114 void frame::oops_compiled_arguments_do(symbolHandle signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
  1116   ResourceMark rm;
  1115   ResourceMark rm;
  1117   CompiledArgumentOopFinder finder(signature, is_static, f, *this, reg_map);
  1116   CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
  1118   finder.oops_do();
  1117   finder.oops_do();
  1119 }
  1118 }
  1120 
  1119 
  1121 
  1120 
  1122 // Get receiver out of callers frame, i.e. find parameter 0 in callers
  1121 // Get receiver out of callers frame, i.e. find parameter 0 in callers