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

 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_compiled(), "must be");
 350 
 351   // If the call site is a MethodHandle call site use the MH deopt handler.
 352   CompiledMethod* cm = (CompiledMethod*) _cb;
 353   address deopt = cm->is_method_handle_return(pc()) ?
 354                         cm->deopt_mh_handler_begin() :
 355                         cm->deopt_handler_begin();
 356 
 357   NativePostCallNop* inst = nativePostCallNop_at(pc());
 358 
 359   // Save the original pc before we patch in the new one
 360   cm->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 

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


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


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

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

















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

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

1015     VMReg reg = _regs[_offset].first();
1016     oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1017   #ifdef ASSERT
1018     if (loc == nullptr) {
1019       if (_reg_map->should_skip_missing()) {
1020         return;
1021       }
1022       tty->print_cr("Error walking frame oops:");
1023       _fr.print_on(tty);
1024       assert(loc != nullptr, "missing register map entry reg: %d %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1025     }
1026   #endif
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     : SignatureIterator(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     do_parameters_on(this);
1054     if (_has_appendix) {
1055       handle_oop_offset();
1056       _offset++;
1057     }
1058   }
1059 };
1060 
1061 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1062                                        const RegisterMap* reg_map, OopClosure* f) const {
1063   // ResourceMark rm;
1064   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1065   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/safefetch.hpp"
  57 #include "runtime/signature.hpp"
  58 #include "runtime/stackValue.hpp"
  59 #include "runtime/stubCodeGenerator.hpp"
  60 #include "runtime/stubRoutines.hpp"
  61 #include "utilities/debug.hpp"
  62 #include "utilities/decoder.hpp"
  63 #include "utilities/formatBuffer.hpp"
  64 #ifdef COMPILER1
  65 #include "c1/c1_Runtime1.hpp"
  66 #endif
  67 
  68 RegisterMap::RegisterMap(JavaThread *thread, UpdateMap update_map, ProcessFrames process_frames, WalkContinuation walk_cont) {
  69   _thread         = thread;
  70   _update_map     = update_map == UpdateMap::include;
  71   _process_frames = process_frames == ProcessFrames::include;
  72   _walk_cont      = walk_cont == WalkContinuation::include;
  73   clear();
  74   DEBUG_ONLY (_update_for_id = nullptr;)
  75   NOT_PRODUCT(_skip_missing = false;)
  76   NOT_PRODUCT(_async = false;)
  77 
  78   if (walk_cont == WalkContinuation::include && thread != nullptr && thread->last_continuation() != nullptr) {
  79     _chunk = stackChunkHandle(Thread::current()->handle_area()->allocate_null_handle(), true /* dummy */);
  80   }
  81   _chunk_index = -1;
  82 
  83 #ifndef PRODUCT
  84   for (int i = 0; i < reg_count ; i++ ) _location[i] = nullptr;
  85 #endif /* PRODUCT */
  86 }

 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_compiled(), "must be");
 354 
 355   // If the call site is a MethodHandle call site use the MH deopt handler.
 356   CompiledMethod* cm = (CompiledMethod*) _cb;
 357   address deopt = cm->is_method_handle_return(pc()) ?
 358                         cm->deopt_mh_handler_begin() :
 359                         cm->deopt_handler_begin();
 360 
 361   NativePostCallNop* inst = nativePostCallNop_at(pc());
 362 
 363   // Save the original pc before we patch in the new one
 364   cm->set_original_pc(this, pc());
 365 
 366 #ifdef COMPILER1
 367   if (cm->is_compiled_by_c1() && cm->method()->has_scalarized_args() &&
 368       pc() < cm->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(Runtime1::buffer_inline_args_no_receiver_id) ||
 378            dest == Runtime1::entry_for(Runtime1::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 

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

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

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




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