< prev index next >

src/hotspot/share/runtime/frame.cpp

Print this page

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

  42 #include "oops/stackChunkOop.inline.hpp"
  43 #include "oops/verifyOopClosure.hpp"
  44 #include "prims/methodHandles.hpp"
  45 #include "runtime/continuation.hpp"
  46 #include "runtime/continuationEntry.inline.hpp"
  47 #include "runtime/frame.inline.hpp"
  48 #include "runtime/handles.inline.hpp"
  49 #include "runtime/javaCalls.hpp"
  50 #include "runtime/javaThread.hpp"
  51 #include "runtime/monitorChunk.hpp"
  52 #include "runtime/os.hpp"
  53 #include "runtime/sharedRuntime.hpp"
  54 #include "runtime/safefetch.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 = nullptr;)
  70   NOT_PRODUCT(_skip_missing = false;)
  71   NOT_PRODUCT(_async = false;)
  72 
  73   if (walk_cont == WalkContinuation::include && thread != nullptr && thread->last_continuation() != nullptr) {
  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] = nullptr;
  80 #endif /* PRODUCT */
  81 }

 341   return !nm->is_at_poll_return(pc());
 342 }
 343 
 344 void frame::deoptimize(JavaThread* thread) {
 345   assert(thread == nullptr
 346          || (thread->frame_anchor()->has_last_Java_frame() &&
 347              thread->frame_anchor()->walkable()), "must be");
 348   // Schedule deoptimization of an nmethod activation with this frame.
 349   assert(_cb != nullptr && _cb->is_nmethod(), "must be");
 350 
 351   // If the call site is a MethodHandle call site use the MH deopt handler.
 352   nmethod* nm = _cb->as_nmethod();
 353   address deopt = nm->is_method_handle_return(pc()) ?
 354                         nm->deopt_mh_handler_begin() :
 355                         nm->deopt_handler_begin();
 356 
 357   NativePostCallNop* inst = nativePostCallNop_at(pc());
 358 
 359   // Save the original pc before we patch in the new one
 360   nm->set_original_pc(this, pc());



















 361   patch_pc(thread, deopt);
 362   assert(is_deoptimized_frame(), "must be");
 363 
 364 #ifdef ASSERT
 365   if (thread != nullptr) {
 366     frame check = thread->last_frame();
 367     if (is_older(check.id())) {
 368       RegisterMap map(thread,
 369                       RegisterMap::UpdateMap::skip,
 370                       RegisterMap::ProcessFrames::include,
 371                       RegisterMap::WalkContinuation::skip);
 372       while (id() != check.id()) {
 373         check = check.sender(&map);
 374       }
 375       assert(check.is_deoptimized_frame(), "missed deopt");
 376     }
 377   }
 378 #endif // ASSERT
 379 }
 380 

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


 772     } else {
 773       addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
 774       // In case of exceptions, the expression stack is invalid and the esp will be reset to express
 775       // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
 776       bool in_stack;
 777       if (frame::interpreter_frame_expression_stack_direction() > 0) {
 778         in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
 779       } else {
 780         in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
 781       }
 782       if (in_stack) {
 783         _f->do_oop(addr);


 784       }
 785     }
 786   }
 787 };
 788 
 789 
 790 class InterpretedArgumentOopFinder: public SignatureIterator {
 791  private:
 792   OopClosure*  _f;             // Closure to invoke
 793   int          _offset;        // TOS-relative offset, decremented with each argument
 794   bool         _has_receiver;  // true if the callee has a receiver
 795   const frame* _fr;
 796 
 797   friend class SignatureIterator;  // so do_parameters_on can call do_type
 798   void do_type(BasicType type) {
 799     _offset -= parameter_type_word_count(type);
 800     if (is_reference_type(type)) oop_offset_do();
 801    }
 802 
 803   void oop_offset_do() {

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

















 970 
 971 void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const {
 972   InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
 973   finder.oops_do();
 974 }
 975 
 976 void frame::oops_nmethod_do(OopClosure* f, NMethodClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* reg_map) const {
 977   assert(_cb != nullptr, "sanity check");
 978   assert((oop_map() == nullptr) == (_cb->oop_maps() == nullptr), "frame and _cb must agree that oopmap is set or not");
 979   if (oop_map() != nullptr) {
 980     if (df != nullptr) {
 981       _oop_map->oops_do(this, reg_map, f, df);
 982     } else {
 983       _oop_map->oops_do(this, reg_map, f, derived_mode);
 984     }
 985 
 986     // Preserve potential arguments for a callee. We handle this by dispatching
 987     // on the codeblob. For c2i, we do
 988     if (reg_map->include_argument_oops() && _cb->is_nmethod()) {
 989       // Only nmethod preserves outgoing arguments at call.

1002 class CompiledArgumentOopFinder: public SignatureIterator {
1003  protected:
1004   OopClosure*     _f;
1005   int             _offset;        // the current offset, incremented with each argument
1006   bool            _has_receiver;  // true if the callee has a receiver
1007   bool            _has_appendix;  // true if the call has an appendix
1008   frame           _fr;
1009   RegisterMap*    _reg_map;
1010   int             _arg_size;
1011   VMRegPair*      _regs;        // VMReg list of arguments
1012 
1013   friend class SignatureIterator;  // so do_parameters_on can call do_type
1014   void do_type(BasicType type) {
1015     if (is_reference_type(type))  handle_oop_offset();
1016     _offset += parameter_type_word_count(type);
1017   }
1018 
1019   virtual void handle_oop_offset() {
1020     // Extract low order register number from register array.
1021     // In LP64-land, the high-order bits are valid but unhelpful.

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

  22  *
  23  */
  24 
  25 #include "classfile/moduleEntry.hpp"
  26 #include "code/codeCache.hpp"
  27 #include "code/scopeDesc.hpp"
  28 #include "code/vmreg.inline.hpp"
  29 #include "compiler/abstractCompiler.hpp"
  30 #include "compiler/disassembler.hpp"
  31 #include "compiler/oopMap.hpp"
  32 #include "gc/shared/collectedHeap.inline.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "interpreter/oopMapCache.hpp"
  35 #include "logging/log.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "memory/universe.hpp"
  38 #include "oops/markWord.hpp"
  39 #include "oops/method.inline.hpp"
  40 #include "oops/methodData.hpp"
  41 #include "oops/oop.inline.hpp"
  42 #include "oops/inlineKlass.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/safefetch.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 = nullptr;)
  74   NOT_PRODUCT(_skip_missing = false;)
  75   NOT_PRODUCT(_async = false;)
  76 
  77   if (walk_cont == WalkContinuation::include && thread != nullptr && thread->last_continuation() != nullptr) {
  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] = nullptr;
  84 #endif /* PRODUCT */
  85 }

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

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

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

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




1094   }
1095 
1096   void oops_do() {
1097     if (_has_receiver) {
1098       handle_oop_offset();
1099       _offset++;
1100     }
1101     do_parameters_on(this);
1102     if (_has_appendix) {
1103       handle_oop_offset();
1104       _offset++;
1105     }
1106   }
1107 };
1108 
1109 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1110                                        const RegisterMap* reg_map, OopClosure* f) const {
1111   // ResourceMark rm;
1112   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1113   finder.oops_do();
< prev index next >