< 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 }

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



















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

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


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


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

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

















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

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

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

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

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

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

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




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