< prev index next >

src/hotspot/share/runtime/frame.cpp

Print this page

  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/moduleEntry.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "code/scopeDesc.hpp"
  29 #include "code/vmreg.inline.hpp"
  30 #include "compiler/abstractCompiler.hpp"
  31 #include "compiler/disassembler.hpp"
  32 #include "compiler/oopMap.hpp"
  33 #include "gc/shared/collectedHeap.inline.hpp"
  34 #include "interpreter/interpreter.hpp"
  35 #include "interpreter/oopMapCache.hpp"
  36 #include "logging/log.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/markWord.hpp"
  40 #include "oops/method.inline.hpp"
  41 #include "oops/methodData.hpp"
  42 #include "oops/oop.inline.hpp"

  43 #include "oops/stackChunkOop.inline.hpp"
  44 #include "oops/verifyOopClosure.hpp"
  45 #include "prims/methodHandles.hpp"
  46 #include "runtime/continuation.hpp"
  47 #include "runtime/continuationEntry.inline.hpp"
  48 #include "runtime/frame.inline.hpp"
  49 #include "runtime/handles.inline.hpp"
  50 #include "runtime/javaCalls.hpp"
  51 #include "runtime/javaThread.hpp"
  52 #include "runtime/monitorChunk.hpp"
  53 #include "runtime/os.hpp"
  54 #include "runtime/sharedRuntime.hpp"
  55 #include "runtime/signature.hpp"
  56 #include "runtime/stackValue.hpp"
  57 #include "runtime/stubCodeGenerator.hpp"
  58 #include "runtime/stubRoutines.hpp"
  59 #include "utilities/debug.hpp"
  60 #include "utilities/decoder.hpp"
  61 #include "utilities/formatBuffer.hpp"



  62 
  63 RegisterMap::RegisterMap(JavaThread *thread, UpdateMap update_map, ProcessFrames process_frames, WalkContinuation walk_cont) {
  64   _thread         = thread;
  65   _update_map     = update_map == UpdateMap::include;
  66   _process_frames = process_frames == ProcessFrames::include;
  67   _walk_cont      = walk_cont == WalkContinuation::include;
  68   clear();
  69   DEBUG_ONLY (_update_for_id = NULL;)
  70   NOT_PRODUCT(_skip_missing = false;)
  71   NOT_PRODUCT(_async = false;)
  72 
  73   if (walk_cont == WalkContinuation::include && thread != NULL && thread->last_continuation() != NULL) {
  74     _chunk = stackChunkHandle(Thread::current()->handle_area()->allocate_null_handle(), true /* dummy */);
  75   }
  76   _chunk_index = -1;
  77 
  78 #ifndef PRODUCT
  79   for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL;
  80 #endif /* PRODUCT */
  81 }

 330   return !nm->is_at_poll_return(pc());
 331 }
 332 
 333 void frame::deoptimize(JavaThread* thread) {
 334   assert(thread == NULL
 335          || (thread->frame_anchor()->has_last_Java_frame() &&
 336              thread->frame_anchor()->walkable()), "must be");
 337   // Schedule deoptimization of an nmethod activation with this frame.
 338   assert(_cb != NULL && _cb->is_compiled(), "must be");
 339 
 340   // If the call site is a MethodHandle call site use the MH deopt handler.
 341   CompiledMethod* cm = (CompiledMethod*) _cb;
 342   address deopt = cm->is_method_handle_return(pc()) ?
 343                         cm->deopt_mh_handler_begin() :
 344                         cm->deopt_handler_begin();
 345 
 346   NativePostCallNop* inst = nativePostCallNop_at(pc());
 347 
 348   // Save the original pc before we patch in the new one
 349   cm->set_original_pc(this, pc());



















 350   patch_pc(thread, deopt);
 351   assert(is_deoptimized_frame(), "must be");
 352 
 353 #ifdef ASSERT
 354   if (thread != NULL) {
 355     frame check = thread->last_frame();
 356     if (is_older(check.id())) {
 357       RegisterMap map(thread,
 358                       RegisterMap::UpdateMap::skip,
 359                       RegisterMap::ProcessFrames::include,
 360                       RegisterMap::WalkContinuation::skip);
 361       while (id() != check.id()) {
 362         check = check.sender(&map);
 363       }
 364       assert(check.is_deoptimized_frame(), "missed deopt");
 365     }
 366   }
 367 #endif // ASSERT
 368 }
 369 

 728 }
 729 
 730 
 731 /*
 732   The interpreter_frame_expression_stack_at method in the case of SPARC needs the
 733   max_stack value of the method in order to compute the expression stack address.
 734   It uses the Method* in order to get the max_stack value but during GC this
 735   Method* value saved on the frame is changed by reverse_and_push and hence cannot
 736   be used. So we save the max_stack value in the FrameClosure object and pass it
 737   down to the interpreter_frame_expression_stack_at method
 738 */
 739 class InterpreterFrameClosure : public OffsetClosure {
 740  private:
 741   const frame* _fr;
 742   OopClosure*  _f;
 743   int          _max_locals;
 744   int          _max_stack;
 745 
 746  public:
 747   InterpreterFrameClosure(const frame* fr, int max_locals, int max_stack,
 748                           OopClosure* f) {
 749     _fr         = fr;
 750     _max_locals = max_locals;
 751     _max_stack  = max_stack;
 752     _f          = f;
 753   }
 754 
 755   void offset_do(int offset) {
 756     oop* addr;
 757     if (offset < _max_locals) {
 758       addr = (oop*) _fr->interpreter_frame_local_at(offset);
 759       assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
 760       _f->do_oop(addr);


 761     } else {
 762       addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
 763       // In case of exceptions, the expression stack is invalid and the esp will be reset to express
 764       // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
 765       bool in_stack;
 766       if (frame::interpreter_frame_expression_stack_direction() > 0) {
 767         in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
 768       } else {
 769         in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
 770       }
 771       if (in_stack) {
 772         _f->do_oop(addr);


 773       }
 774     }
 775   }
 776 };
 777 
 778 
 779 class InterpretedArgumentOopFinder: public SignatureIterator {
 780  private:
 781   OopClosure*  _f;             // Closure to invoke
 782   int          _offset;        // TOS-relative offset, decremented with each argument
 783   bool         _has_receiver;  // true if the callee has a receiver
 784   const frame* _fr;
 785 
 786   friend class SignatureIterator;  // so do_parameters_on can call do_type
 787   void do_type(BasicType type) {
 788     _offset -= parameter_type_word_count(type);
 789     if (is_reference_type(type)) oop_offset_do();
 790    }
 791 
 792   void oop_offset_do() {

 927       signature = call.signature();
 928       has_receiver = call.has_receiver();
 929       if (map->include_argument_oops() &&
 930           interpreter_frame_expression_stack_size() > 0) {
 931         ResourceMark rm(thread);  // is this right ???
 932         // we are at a call site & the expression stack is not empty
 933         // => process callee's arguments
 934         //
 935         // Note: The expression stack can be empty if an exception
 936         //       occurred during method resolution/execution. In all
 937         //       cases we empty the expression stack completely be-
 938         //       fore handling the exception (the exception handling
 939         //       code in the interpreter calls a blocking runtime
 940         //       routine which can cause this code to be executed).
 941         //       (was bug gri 7/27/98)
 942         oops_interpreted_arguments_do(signature, has_receiver, f);
 943       }
 944     }
 945   }
 946 
 947   InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
 948 
 949   // process locals & expression stack
 950   InterpreterOopMap mask;
 951   if (query_oop_map_cache) {
 952     m->mask_for(bci, &mask);
 953   } else {
 954     OopMapCache::compute_one_oop_map(m, bci, &mask);
 955   }
 956   mask.iterate_oop(&blk);
 957 }
 958 

















 959 
 960 void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const {
 961   InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
 962   finder.oops_do();
 963 }
 964 
 965 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* reg_map) const {
 966   assert(_cb != NULL, "sanity check");
 967   assert((oop_map() == NULL) == (_cb->oop_maps() == NULL), "frame and _cb must agree that oopmap is set or not");
 968   if (oop_map() != NULL) {
 969     if (df != NULL) {
 970       _oop_map->oops_do(this, reg_map, f, df);
 971     } else {
 972       _oop_map->oops_do(this, reg_map, f, derived_mode);
 973     }
 974 
 975     // Preserve potential arguments for a callee. We handle this by dispatching
 976     // on the codeblob. For c2i, we do
 977     if (reg_map->include_argument_oops()) {
 978       _cb->preserve_callee_argument_oops(*this, reg_map, f);

 990 class CompiledArgumentOopFinder: public SignatureIterator {
 991  protected:
 992   OopClosure*     _f;
 993   int             _offset;        // the current offset, incremented with each argument
 994   bool            _has_receiver;  // true if the callee has a receiver
 995   bool            _has_appendix;  // true if the call has an appendix
 996   frame           _fr;
 997   RegisterMap*    _reg_map;
 998   int             _arg_size;
 999   VMRegPair*      _regs;        // VMReg list of arguments
1000 
1001   friend class SignatureIterator;  // so do_parameters_on can call do_type
1002   void do_type(BasicType type) {
1003     if (is_reference_type(type))  handle_oop_offset();
1004     _offset += parameter_type_word_count(type);
1005   }
1006 
1007   virtual void handle_oop_offset() {
1008     // Extract low order register number from register array.
1009     // In LP64-land, the high-order bits are valid but unhelpful.

1010     VMReg reg = _regs[_offset].first();
1011     oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1012   #ifdef ASSERT
1013     if (loc == NULL) {
1014       if (_reg_map->should_skip_missing()) {
1015         return;
1016       }
1017       tty->print_cr("Error walking frame oops:");
1018       _fr.print_on(tty);
1019       assert(loc != NULL, "missing register map entry reg: " INTPTR_FORMAT " %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1020     }
1021   #endif
1022     _f->do_oop(loc);
1023   }
1024 
1025  public:
1026   CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
1027     : SignatureIterator(signature) {
1028 
1029     // initialize CompiledArgumentOopFinder
1030     _f         = f;
1031     _offset    = 0;
1032     _has_receiver = has_receiver;
1033     _has_appendix = has_appendix;
1034     _fr        = fr;
1035     _reg_map   = (RegisterMap*)reg_map;
1036     _arg_size  = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
1037 
1038     int arg_size;
1039     _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
1040     assert(arg_size == _arg_size, "wrong arg size");
1041   }
1042 
1043   void oops_do() {
1044     if (_has_receiver) {
1045       handle_oop_offset();
1046       _offset++;
1047     }
1048     do_parameters_on(this);
1049     if (_has_appendix) {
1050       handle_oop_offset();
1051       _offset++;
1052     }
1053   }
1054 };
1055 
1056 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1057                                        const RegisterMap* reg_map, OopClosure* f) const {
1058   // ResourceMark rm;
1059   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1060   finder.oops_do();

  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/moduleEntry.hpp"
  27 #include "code/codeCache.hpp"
  28 #include "code/scopeDesc.hpp"
  29 #include "code/vmreg.inline.hpp"
  30 #include "compiler/abstractCompiler.hpp"
  31 #include "compiler/disassembler.hpp"
  32 #include "compiler/oopMap.hpp"
  33 #include "gc/shared/collectedHeap.inline.hpp"
  34 #include "interpreter/interpreter.hpp"
  35 #include "interpreter/oopMapCache.hpp"
  36 #include "logging/log.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/markWord.hpp"
  40 #include "oops/method.inline.hpp"
  41 #include "oops/methodData.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "oops/inlineKlass.hpp"
  44 #include "oops/stackChunkOop.inline.hpp"
  45 #include "oops/verifyOopClosure.hpp"
  46 #include "prims/methodHandles.hpp"
  47 #include "runtime/continuation.hpp"
  48 #include "runtime/continuationEntry.inline.hpp"
  49 #include "runtime/frame.inline.hpp"
  50 #include "runtime/handles.inline.hpp"
  51 #include "runtime/javaCalls.hpp"
  52 #include "runtime/javaThread.hpp"
  53 #include "runtime/monitorChunk.hpp"
  54 #include "runtime/os.hpp"
  55 #include "runtime/sharedRuntime.hpp"
  56 #include "runtime/signature.hpp"
  57 #include "runtime/stackValue.hpp"
  58 #include "runtime/stubCodeGenerator.hpp"
  59 #include "runtime/stubRoutines.hpp"
  60 #include "utilities/debug.hpp"
  61 #include "utilities/decoder.hpp"
  62 #include "utilities/formatBuffer.hpp"
  63 #ifdef COMPILER1
  64 #include "c1/c1_Runtime1.hpp"
  65 #endif
  66 
  67 RegisterMap::RegisterMap(JavaThread *thread, UpdateMap update_map, ProcessFrames process_frames, WalkContinuation walk_cont) {
  68   _thread         = thread;
  69   _update_map     = update_map == UpdateMap::include;
  70   _process_frames = process_frames == ProcessFrames::include;
  71   _walk_cont      = walk_cont == WalkContinuation::include;
  72   clear();
  73   DEBUG_ONLY (_update_for_id = NULL;)
  74   NOT_PRODUCT(_skip_missing = false;)
  75   NOT_PRODUCT(_async = false;)
  76 
  77   if (walk_cont == WalkContinuation::include && thread != NULL && thread->last_continuation() != NULL) {
  78     _chunk = stackChunkHandle(Thread::current()->handle_area()->allocate_null_handle(), true /* dummy */);
  79   }
  80   _chunk_index = -1;
  81 
  82 #ifndef PRODUCT
  83   for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL;
  84 #endif /* PRODUCT */
  85 }

 334   return !nm->is_at_poll_return(pc());
 335 }
 336 
 337 void frame::deoptimize(JavaThread* thread) {
 338   assert(thread == NULL
 339          || (thread->frame_anchor()->has_last_Java_frame() &&
 340              thread->frame_anchor()->walkable()), "must be");
 341   // Schedule deoptimization of an nmethod activation with this frame.
 342   assert(_cb != NULL && _cb->is_compiled(), "must be");
 343 
 344   // If the call site is a MethodHandle call site use the MH deopt handler.
 345   CompiledMethod* cm = (CompiledMethod*) _cb;
 346   address deopt = cm->is_method_handle_return(pc()) ?
 347                         cm->deopt_mh_handler_begin() :
 348                         cm->deopt_handler_begin();
 349 
 350   NativePostCallNop* inst = nativePostCallNop_at(pc());
 351 
 352   // Save the original pc before we patch in the new one
 353   cm->set_original_pc(this, pc());
 354 
 355 #ifdef COMPILER1
 356   if (cm->is_compiled_by_c1() && cm->method()->has_scalarized_args() &&
 357       pc() < cm->verified_inline_entry_point()) {
 358     // The VEP and VIEP(RO) of C1-compiled methods call into the runtime to buffer scalarized value
 359     // type args. We can't deoptimize at that point because the buffers have not yet been initialized.
 360     // Also, if the method is synchronized, we first need to acquire the lock.
 361     // Don't patch the return pc to delay deoptimization until we enter the method body (the check
 362     // added in LIRGenerator::do_Base will detect the pending deoptimization by checking the original_pc).
 363 #if defined ASSERT && !defined AARCH64   // Stub call site does not look like NativeCall on AArch64
 364     NativeCall* call = nativeCall_before(this->pc());
 365     address dest = call->destination();
 366     assert(dest == Runtime1::entry_for(Runtime1::buffer_inline_args_no_receiver_id) ||
 367            dest == Runtime1::entry_for(Runtime1::buffer_inline_args_id), "unexpected safepoint in entry point");
 368 #endif
 369     return;
 370   }
 371 #endif
 372 
 373   patch_pc(thread, deopt);
 374   assert(is_deoptimized_frame(), "must be");
 375 
 376 #ifdef ASSERT
 377   if (thread != NULL) {
 378     frame check = thread->last_frame();
 379     if (is_older(check.id())) {
 380       RegisterMap map(thread,
 381                       RegisterMap::UpdateMap::skip,
 382                       RegisterMap::ProcessFrames::include,
 383                       RegisterMap::WalkContinuation::skip);
 384       while (id() != check.id()) {
 385         check = check.sender(&map);
 386       }
 387       assert(check.is_deoptimized_frame(), "missed deopt");
 388     }
 389   }
 390 #endif // ASSERT
 391 }
 392 

 751 }
 752 
 753 
 754 /*
 755   The interpreter_frame_expression_stack_at method in the case of SPARC needs the
 756   max_stack value of the method in order to compute the expression stack address.
 757   It uses the Method* in order to get the max_stack value but during GC this
 758   Method* value saved on the frame is changed by reverse_and_push and hence cannot
 759   be used. So we save the max_stack value in the FrameClosure object and pass it
 760   down to the interpreter_frame_expression_stack_at method
 761 */
 762 class InterpreterFrameClosure : public OffsetClosure {
 763  private:
 764   const frame* _fr;
 765   OopClosure*  _f;
 766   int          _max_locals;
 767   int          _max_stack;
 768 
 769  public:
 770   InterpreterFrameClosure(const frame* fr, int max_locals, int max_stack,
 771                           OopClosure* f, BufferedValueClosure* bvt_f) {
 772     _fr         = fr;
 773     _max_locals = max_locals;
 774     _max_stack  = max_stack;
 775     _f          = f;
 776   }
 777 
 778   void offset_do(int offset) {
 779     oop* addr;
 780     if (offset < _max_locals) {
 781       addr = (oop*) _fr->interpreter_frame_local_at(offset);
 782       assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
 783       if (_f != NULL) {
 784         _f->do_oop(addr);
 785       }
 786     } else {
 787       addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
 788       // In case of exceptions, the expression stack is invalid and the esp will be reset to express
 789       // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
 790       bool in_stack;
 791       if (frame::interpreter_frame_expression_stack_direction() > 0) {
 792         in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
 793       } else {
 794         in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
 795       }
 796       if (in_stack) {
 797         if (_f != NULL) {
 798           _f->do_oop(addr);
 799         }
 800       }
 801     }
 802   }
 803 };
 804 
 805 
 806 class InterpretedArgumentOopFinder: public SignatureIterator {
 807  private:
 808   OopClosure*  _f;             // Closure to invoke
 809   int          _offset;        // TOS-relative offset, decremented with each argument
 810   bool         _has_receiver;  // true if the callee has a receiver
 811   const frame* _fr;
 812 
 813   friend class SignatureIterator;  // so do_parameters_on can call do_type
 814   void do_type(BasicType type) {
 815     _offset -= parameter_type_word_count(type);
 816     if (is_reference_type(type)) oop_offset_do();
 817    }
 818 
 819   void oop_offset_do() {

 954       signature = call.signature();
 955       has_receiver = call.has_receiver();
 956       if (map->include_argument_oops() &&
 957           interpreter_frame_expression_stack_size() > 0) {
 958         ResourceMark rm(thread);  // is this right ???
 959         // we are at a call site & the expression stack is not empty
 960         // => process callee's arguments
 961         //
 962         // Note: The expression stack can be empty if an exception
 963         //       occurred during method resolution/execution. In all
 964         //       cases we empty the expression stack completely be-
 965         //       fore handling the exception (the exception handling
 966         //       code in the interpreter calls a blocking runtime
 967         //       routine which can cause this code to be executed).
 968         //       (was bug gri 7/27/98)
 969         oops_interpreted_arguments_do(signature, has_receiver, f);
 970       }
 971     }
 972   }
 973 
 974   InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f, NULL);
 975 
 976   // process locals & expression stack
 977   InterpreterOopMap mask;
 978   if (query_oop_map_cache) {
 979     m->mask_for(bci, &mask);
 980   } else {
 981     OopMapCache::compute_one_oop_map(m, bci, &mask);
 982   }
 983   mask.iterate_oop(&blk);
 984 }
 985 
 986 void frame::buffered_values_interpreted_do(BufferedValueClosure* f) {
 987   assert(is_interpreted_frame(), "Not an interpreted frame");
 988   Thread *thread = Thread::current();
 989   methodHandle m (thread, interpreter_frame_method());
 990   jint      bci = interpreter_frame_bci();
 991 
 992   assert(m->is_method(), "checking frame value");
 993   assert(!m->is_native() && bci >= 0 && bci < m->code_size(),
 994          "invalid bci value");
 995 
 996   InterpreterFrameClosure blk(this, m->max_locals(), m->max_stack(), NULL, f);
 997 
 998   // process locals & expression stack
 999   InterpreterOopMap mask;
1000   m->mask_for(bci, &mask);
1001   mask.iterate_oop(&blk);
1002 }
1003 
1004 void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const {
1005   InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
1006   finder.oops_do();
1007 }
1008 
1009 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* reg_map) const {
1010   assert(_cb != NULL, "sanity check");
1011   assert((oop_map() == NULL) == (_cb->oop_maps() == NULL), "frame and _cb must agree that oopmap is set or not");
1012   if (oop_map() != NULL) {
1013     if (df != NULL) {
1014       _oop_map->oops_do(this, reg_map, f, df);
1015     } else {
1016       _oop_map->oops_do(this, reg_map, f, derived_mode);
1017     }
1018 
1019     // Preserve potential arguments for a callee. We handle this by dispatching
1020     // on the codeblob. For c2i, we do
1021     if (reg_map->include_argument_oops()) {
1022       _cb->preserve_callee_argument_oops(*this, reg_map, f);

1034 class CompiledArgumentOopFinder: public SignatureIterator {
1035  protected:
1036   OopClosure*     _f;
1037   int             _offset;        // the current offset, incremented with each argument
1038   bool            _has_receiver;  // true if the callee has a receiver
1039   bool            _has_appendix;  // true if the call has an appendix
1040   frame           _fr;
1041   RegisterMap*    _reg_map;
1042   int             _arg_size;
1043   VMRegPair*      _regs;        // VMReg list of arguments
1044 
1045   friend class SignatureIterator;  // so do_parameters_on can call do_type
1046   void do_type(BasicType type) {
1047     if (is_reference_type(type))  handle_oop_offset();
1048     _offset += parameter_type_word_count(type);
1049   }
1050 
1051   virtual void handle_oop_offset() {
1052     // Extract low order register number from register array.
1053     // In LP64-land, the high-order bits are valid but unhelpful.
1054     assert(_offset < _arg_size, "out of bounds");
1055     VMReg reg = _regs[_offset].first();
1056     oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1057   #ifdef ASSERT
1058     if (loc == NULL) {
1059       if (_reg_map->should_skip_missing()) {
1060         return;
1061       }
1062       tty->print_cr("Error walking frame oops:");
1063       _fr.print_on(tty);
1064       assert(loc != NULL, "missing register map entry reg: " INTPTR_FORMAT " %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1065     }
1066   #endif
1067     _f->do_oop(loc);
1068   }
1069 
1070  public:
1071   CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
1072     : SignatureIterator(signature) {
1073 
1074     // initialize CompiledArgumentOopFinder
1075     _f         = f;
1076     _offset    = 0;
1077     _has_receiver = has_receiver;
1078     _has_appendix = has_appendix;
1079     _fr        = fr;
1080     _reg_map   = (RegisterMap*)reg_map;
1081     _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &_arg_size);




1082   }
1083 
1084   void oops_do() {
1085     if (_has_receiver) {
1086       handle_oop_offset();
1087       _offset++;
1088     }
1089     do_parameters_on(this);
1090     if (_has_appendix) {
1091       handle_oop_offset();
1092       _offset++;
1093     }
1094   }
1095 };
1096 
1097 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1098                                        const RegisterMap* reg_map, OopClosure* f) const {
1099   // ResourceMark rm;
1100   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1101   finder.oops_do();
< prev index next >