< prev index next >

src/hotspot/share/runtime/frame.cpp

Print this page

  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  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/safefetch.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 = 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 }

 344     return false;
 345 
 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->deopt_handler_entry();
 359 
 360   NativePostCallNop* inst = nativePostCallNop_at(pc());
 361 
 362   // Save the original pc before we patch in the new one
 363   nm->set_original_pc(this, pc());



















 364   patch_pc(thread, deopt);
 365   assert(is_deoptimized_frame(), "must be");
 366 
 367 #ifdef ASSERT
 368   if (thread != nullptr) {
 369     frame fr = thread->last_frame();
 370     RegisterMap map(thread,
 371                     RegisterMap::UpdateMap::skip,
 372                     RegisterMap::ProcessFrames::include,
 373                     !is_heap_frame() ? RegisterMap::WalkContinuation::skip : RegisterMap::WalkContinuation::include);
 374     intptr_t* fr_id = fr.id();
 375     while (id() != fr_id) {
 376       fr = fr.sender(&map);
 377       if (fr.is_heap_frame()) {
 378         assert(is_heap_frame(), "");
 379         frame derel_fr = map.stack_chunk()->derelativize(fr);
 380         fr_id = derel_fr.id();
 381       } else {
 382         fr_id = fr.id();
 383       }

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

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

1385       tos = MAX2(tos, interpreter_frame_expression_stack_at(e));
1386       values.describe(frame_no, interpreter_frame_expression_stack_at(e),
1387                       err_msg("stack %d", e), 1);
1388     }
1389     if (tos != nullptr) {
1390       values.describe(-1, tos, err_msg("expression stack for #%d", frame_no), 2);
1391     }
1392 
1393     if (reg_map != nullptr) {
1394       FrameValuesOopClosure oopsFn;
1395       oops_do(&oopsFn, nullptr, &oopsFn, reg_map);
1396       oopsFn.describe(values, frame_no);
1397     }
1398   } else if (is_entry_frame()) {
1399     // For now just label the frame
1400     values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
1401   } else if (is_compiled_frame()) {
1402     // For now just label the frame
1403     nmethod* nm = cb()->as_nmethod();
1404     values.describe(-1, info_address,
1405                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method J %s%s", frame_no,
1406                                        p2i(nm),
1407                                        nm->method()->name_and_sig_as_C_string(),
1408                                        (_deopt_state == is_deoptimized) ?
1409                                        " (deoptimized)" :
1410                                        ((_deopt_state == unknown) ? " (state unknown)" : "")),
1411                     3);
1412 
1413     { // mark arguments (see nmethod::print_nmethod_labels)
1414       Method* m = nm->method();
1415 





1416       int stack_slot_offset = nm->frame_size() * wordSize; // offset, in bytes, to caller sp
1417       int sizeargs = m->size_of_parameters();
1418 
1419       BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
1420       VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
1421       {
1422         int sig_index = 0;
1423         if (!m->is_static()) {
1424           sig_bt[sig_index++] = T_OBJECT; // 'this'
1425         }
1426         for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) {
1427           BasicType t = ss.type();
1428           assert(type2size[t] == 1 || type2size[t] == 2, "size is 1 or 2");
1429           sig_bt[sig_index++] = t;
1430           if (type2size[t] == 2) {
1431             sig_bt[sig_index++] = T_VOID;
1432           }
1433         }
1434         assert(sig_index == sizeargs, "");
1435       }
1436       int stack_arg_slots = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
1437       assert(stack_arg_slots ==  nm->as_nmethod()->num_stack_arg_slots(false /* rounded */) || nm->is_osr_method(), "");
1438       int out_preserve = SharedRuntime::out_preserve_stack_slots();
1439       int sig_index = 0;
1440       int arg_index = (m->is_static() ? 0 : -1);
1441       for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) {
1442         bool at_this = (arg_index == -1);
1443         bool at_old_sp = false;
1444         BasicType t = (at_this ? T_OBJECT : ss.type());
1445         assert(t == sig_bt[sig_index], "sigs in sync");
1446         VMReg fst = regs[sig_index].first();
1447         if (fst->is_stack()) {
1448           assert(((int)fst->reg2stack()) >= 0, "reg2stack: %d", fst->reg2stack());
1449           int offset = (fst->reg2stack() + out_preserve) * VMRegImpl::stack_slot_size + stack_slot_offset;
1450           intptr_t* stack_address = (intptr_t*)((address)unextended_sp() + offset);
1451           if (at_this) {
1452             values.describe(frame_no, stack_address, err_msg("this for #%d", frame_no), 1);
1453           } else {
1454             values.describe(frame_no, stack_address, err_msg("param %d %s for #%d", arg_index, type2name(t), frame_no), 1);
1455           }
1456         }
1457         sig_index += type2size[t];
1458         arg_index += 1;
1459         if (!at_this) {
1460           ss.next();
1461         }
1462       }
1463     }
1464 
1465     if (reg_map != nullptr && is_java_frame()) {
1466       int scope_no = 0;
1467       for (ScopeDesc* scope = nm->scope_desc_at(pc()); scope != nullptr; scope = scope->sender(), scope_no++) {
1468         Method* m = scope->method();
1469         int  bci = scope->bci();
1470         values.describe(-1, info_address, err_msg("- #%d scope %s @ %d", scope_no, m->name_and_sig_as_C_string(), bci), 2);
1471 
1472         { // mark locals
1473           GrowableArray<ScopeValue*>* scvs = scope->locals();
1474           int scvs_length = scvs != nullptr ? scvs->length() : 0;
1475           for (int i = 0; i < scvs_length; i++) {
1476             intptr_t* stack_address = (intptr_t*)StackValue::stack_value_address(this, reg_map, scvs->at(i));
1477             if (stack_address != nullptr) {
1478               values.describe(frame_no, stack_address, err_msg("local %d for #%d (scope %d)", i, frame_no, scope_no), 1);
1479             }
1480           }
1481         }

  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  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/inlineKlass.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/safefetch.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 = 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 }

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

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




1069   }
1070 
1071   void oops_do() {
1072     if (_has_receiver) {
1073       handle_oop_offset();
1074       _offset++;
1075     }
1076     do_parameters_on(this);
1077     if (_has_appendix) {
1078       handle_oop_offset();
1079       _offset++;
1080     }
1081   }
1082 };
1083 
1084 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1085                                        const RegisterMap* reg_map, OopClosure* f) const {
1086   // ResourceMark rm;
1087   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1088   finder.oops_do();

1405       tos = MAX2(tos, interpreter_frame_expression_stack_at(e));
1406       values.describe(frame_no, interpreter_frame_expression_stack_at(e),
1407                       err_msg("stack %d", e), 1);
1408     }
1409     if (tos != nullptr) {
1410       values.describe(-1, tos, err_msg("expression stack for #%d", frame_no), 2);
1411     }
1412 
1413     if (reg_map != nullptr) {
1414       FrameValuesOopClosure oopsFn;
1415       oops_do(&oopsFn, nullptr, &oopsFn, reg_map);
1416       oopsFn.describe(values, frame_no);
1417     }
1418   } else if (is_entry_frame()) {
1419     // For now just label the frame
1420     values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
1421   } else if (is_compiled_frame()) {
1422     // For now just label the frame
1423     nmethod* nm = cb()->as_nmethod();
1424     values.describe(-1, info_address,
1425                     FormatBuffer<1024>("#%d nmethod (%s %d) " INTPTR_FORMAT " for method J %s%s", frame_no,
1426                                        nm->is_compiled_by_c1() ? "c1" : "c2", nm->frame_size(), p2i(nm),
1427                                        nm->method()->name_and_sig_as_C_string(),
1428                                        (_deopt_state == is_deoptimized) ?
1429                                        " (deoptimized)" :
1430                                        ((_deopt_state == unknown) ? " (state unknown)" : "")),
1431                     3);
1432 
1433     { // mark arguments (see nmethod::print_nmethod_labels)
1434       Method* m = nm->method();
1435 
1436       CompiledEntrySignature ces(m);
1437       ces.compute_calling_conventions(false);
1438       const GrowableArray<SigEntry>* sig_cc = nm->is_compiled_by_c2() ? ces.sig_cc() : ces.sig();
1439       const VMRegPair* regs = nm->is_compiled_by_c2() ? ces.regs_cc() : ces.regs();
1440 
1441       int stack_slot_offset = nm->frame_size() * wordSize; // offset, in bytes, to caller sp





















1442       int out_preserve = SharedRuntime::out_preserve_stack_slots();
1443       int sig_index = 0;
1444       int arg_index = (m->is_static() ? 0 : -1);
1445       for (ExtendedSignature sig = ExtendedSignature(sig_cc, SigEntryFilter()); !sig.at_end(); ++sig) {
1446         bool at_this = (arg_index == -1);
1447         BasicType t = (*sig)._bt;


1448         VMReg fst = regs[sig_index].first();
1449         if (fst->is_stack()) {
1450           assert(((int)fst->reg2stack()) >= 0, "reg2stack: %d", fst->reg2stack());
1451           int offset = (fst->reg2stack() + out_preserve) * VMRegImpl::stack_slot_size + stack_slot_offset;
1452           intptr_t* stack_address = (intptr_t*)((address)unextended_sp() + offset);
1453           if (at_this) {
1454             values.describe(frame_no, stack_address, err_msg("this for #%d", frame_no), 1);
1455           } else {
1456             values.describe(frame_no, stack_address, err_msg("param %d %s for #%d", arg_index, type2name(t), frame_no), 1);
1457           }
1458         }
1459         sig_index += type2size[t];
1460         arg_index += 1;



1461       }
1462     }
1463 
1464     if (reg_map != nullptr && is_java_frame()) {
1465       int scope_no = 0;
1466       for (ScopeDesc* scope = nm->scope_desc_at(pc()); scope != nullptr; scope = scope->sender(), scope_no++) {
1467         Method* m = scope->method();
1468         int  bci = scope->bci();
1469         values.describe(-1, info_address, err_msg("- #%d scope %s @ %d", scope_no, m->name_and_sig_as_C_string(), bci), 2);
1470 
1471         { // mark locals
1472           GrowableArray<ScopeValue*>* scvs = scope->locals();
1473           int scvs_length = scvs != nullptr ? scvs->length() : 0;
1474           for (int i = 0; i < scvs_length; i++) {
1475             intptr_t* stack_address = (intptr_t*)StackValue::stack_value_address(this, reg_map, scvs->at(i));
1476             if (stack_address != nullptr) {
1477               values.describe(frame_no, stack_address, err_msg("local %d for #%d (scope %d)", i, frame_no, scope_no), 1);
1478             }
1479           }
1480         }
< prev index next >