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 }
1011 class CompiledArgumentOopFinder: public SignatureIterator {
1012 protected:
1013 OopClosure* _f;
1014 int _offset; // the current offset, incremented with each argument
1015 bool _has_receiver; // true if the callee has a receiver
1016 bool _has_appendix; // true if the call has an appendix
1017 frame _fr;
1018 RegisterMap* _reg_map;
1019 int _arg_size;
1020 VMRegPair* _regs; // VMReg list of arguments
1021
1022 friend class SignatureIterator; // so do_parameters_on can call do_type
1023 void do_type(BasicType type) {
1024 if (is_reference_type(type)) handle_oop_offset();
1025 _offset += parameter_type_word_count(type);
1026 }
1027
1028 virtual void handle_oop_offset() {
1029 // Extract low order register number from register array.
1030 // In LP64-land, the high-order bits are valid but unhelpful.
1031 VMReg reg = _regs[_offset].first();
1032 oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1033 #ifdef ASSERT
1034 if (loc == nullptr) {
1035 if (_reg_map->should_skip_missing()) {
1036 return;
1037 }
1038 tty->print_cr("Error walking frame oops:");
1039 _fr.print_on(tty);
1040 assert(loc != nullptr, "missing register map entry reg: %d %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1041 }
1042 #endif
1043 _f->do_oop(loc);
1044 }
1045
1046 public:
1047 CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
1048 : SignatureIterator(signature) {
1049
1050 // initialize CompiledArgumentOopFinder
1051 _f = f;
1052 _offset = 0;
1053 _has_receiver = has_receiver;
1054 _has_appendix = has_appendix;
1055 _fr = fr;
1056 _reg_map = (RegisterMap*)reg_map;
1057 _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
1058
1059 int arg_size;
1060 _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
1061 assert(arg_size == _arg_size, "wrong arg size");
1062 }
1063
1064 void oops_do() {
1065 if (_has_receiver) {
1066 handle_oop_offset();
1067 _offset++;
1068 }
1069 do_parameters_on(this);
1070 if (_has_appendix) {
1071 handle_oop_offset();
1072 _offset++;
1073 }
1074 }
1075 };
1076
1077 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1078 const RegisterMap* reg_map, OopClosure* f) const {
1079 // ResourceMark rm;
1080 CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1081 finder.oops_do();
1398 tos = MAX2(tos, interpreter_frame_expression_stack_at(e));
1399 values.describe(frame_no, interpreter_frame_expression_stack_at(e),
1400 err_msg("stack %d", e), 1);
1401 }
1402 if (tos != nullptr) {
1403 values.describe(-1, tos, err_msg("expression stack for #%d", frame_no), 2);
1404 }
1405
1406 if (reg_map != nullptr) {
1407 FrameValuesOopClosure oopsFn;
1408 oops_do(&oopsFn, nullptr, &oopsFn, reg_map);
1409 oopsFn.describe(values, frame_no);
1410 }
1411 } else if (is_entry_frame()) {
1412 // For now just label the frame
1413 values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
1414 } else if (is_compiled_frame()) {
1415 // For now just label the frame
1416 nmethod* nm = cb()->as_nmethod();
1417 values.describe(-1, info_address,
1418 FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method J %s%s", frame_no,
1419 p2i(nm),
1420 nm->method()->name_and_sig_as_C_string(),
1421 (_deopt_state == is_deoptimized) ?
1422 " (deoptimized)" :
1423 ((_deopt_state == unknown) ? " (state unknown)" : "")),
1424 3);
1425
1426 { // mark arguments (see nmethod::print_nmethod_labels)
1427 Method* m = nm->method();
1428
1429 int stack_slot_offset = nm->frame_size() * wordSize; // offset, in bytes, to caller sp
1430 int sizeargs = m->size_of_parameters();
1431
1432 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
1433 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs);
1434 {
1435 int sig_index = 0;
1436 if (!m->is_static()) {
1437 sig_bt[sig_index++] = T_OBJECT; // 'this'
1438 }
1439 for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) {
1440 BasicType t = ss.type();
1441 assert(type2size[t] == 1 || type2size[t] == 2, "size is 1 or 2");
1442 sig_bt[sig_index++] = t;
1443 if (type2size[t] == 2) {
1444 sig_bt[sig_index++] = T_VOID;
1445 }
1446 }
1447 assert(sig_index == sizeargs, "");
1448 }
1449 int stack_arg_slots = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
1450 assert(stack_arg_slots == nm->as_nmethod()->num_stack_arg_slots(false /* rounded */) || nm->is_osr_method(), "");
1451 int out_preserve = SharedRuntime::out_preserve_stack_slots();
1452 int sig_index = 0;
1453 int arg_index = (m->is_static() ? 0 : -1);
1454 for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) {
1455 bool at_this = (arg_index == -1);
1456 bool at_old_sp = false;
1457 BasicType t = (at_this ? T_OBJECT : ss.type());
1458 assert(t == sig_bt[sig_index], "sigs in sync");
1459 VMReg fst = regs[sig_index].first();
1460 if (fst->is_stack()) {
1461 assert(((int)fst->reg2stack()) >= 0, "reg2stack: %d", fst->reg2stack());
1462 int offset = (fst->reg2stack() + out_preserve) * VMRegImpl::stack_slot_size + stack_slot_offset;
1463 intptr_t* stack_address = (intptr_t*)((address)unextended_sp() + offset);
1464 if (at_this) {
1465 values.describe(frame_no, stack_address, err_msg("this for #%d", frame_no), 1);
1466 } else {
1467 values.describe(frame_no, stack_address, err_msg("param %d %s for #%d", arg_index, type2name(t), frame_no), 1);
1468 }
1469 }
1470 sig_index += type2size[t];
1471 arg_index += 1;
1472 if (!at_this) {
1473 ss.next();
1474 }
1475 }
1476 }
1477
1478 if (reg_map != nullptr && is_java_frame()) {
1479 int scope_no = 0;
1480 for (ScopeDesc* scope = nm->scope_desc_at(pc()); scope != nullptr; scope = scope->sender(), scope_no++) {
1481 Method* m = scope->method();
1482 int bci = scope->bci();
1483 values.describe(-1, info_address, err_msg("- #%d scope %s @ %d", scope_no, m->name_and_sig_as_C_string(), bci), 2);
1484
1485 { // mark locals
1486 GrowableArray<ScopeValue*>* scvs = scope->locals();
1487 int scvs_length = scvs != nullptr ? scvs->length() : 0;
1488 for (int i = 0; i < scvs_length; i++) {
1489 intptr_t* stack_address = (intptr_t*)StackValue::stack_value_address(this, reg_map, scvs->at(i));
1490 if (stack_address != nullptr) {
1491 values.describe(frame_no, stack_address, err_msg("local %d for #%d (scope %d)", i, frame_no, scope_no), 1);
1492 }
1493 }
1494 }
|
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 }
1034 class CompiledArgumentOopFinder: public SignatureIterator {
1035 protected:
1036 OopClosure* _f;
1037 int _offset; // the current offset, incremented with each argument
1038 bool _has_receiver; // true if the callee has a receiver
1039 bool _has_appendix; // true if the call has an appendix
1040 frame _fr;
1041 RegisterMap* _reg_map;
1042 int _arg_size;
1043 VMRegPair* _regs; // VMReg list of arguments
1044
1045 friend class SignatureIterator; // so do_parameters_on can call do_type
1046 void do_type(BasicType type) {
1047 if (is_reference_type(type)) handle_oop_offset();
1048 _offset += parameter_type_word_count(type);
1049 }
1050
1051 virtual void handle_oop_offset() {
1052 // Extract low order register number from register array.
1053 // In LP64-land, the high-order bits are valid but unhelpful.
1054 assert(_offset < _arg_size, "out of bounds");
1055 VMReg reg = _regs[_offset].first();
1056 oop *loc = _fr.oopmapreg_to_oop_location(reg, _reg_map);
1057 #ifdef ASSERT
1058 if (loc == nullptr) {
1059 if (_reg_map->should_skip_missing()) {
1060 return;
1061 }
1062 tty->print_cr("Error walking frame oops:");
1063 _fr.print_on(tty);
1064 assert(loc != nullptr, "missing register map entry reg: %d %s loc: " INTPTR_FORMAT, reg->value(), reg->name(), p2i(loc));
1065 }
1066 #endif
1067 _f->do_oop(loc);
1068 }
1069
1070 public:
1071 CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
1072 : SignatureIterator(signature) {
1073
1074 // initialize CompiledArgumentOopFinder
1075 _f = f;
1076 _offset = 0;
1077 _has_receiver = has_receiver;
1078 _has_appendix = has_appendix;
1079 _fr = fr;
1080 _reg_map = (RegisterMap*)reg_map;
1081 _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &_arg_size);
1082 }
1083
1084 void oops_do() {
1085 if (_has_receiver) {
1086 handle_oop_offset();
1087 _offset++;
1088 }
1089 do_parameters_on(this);
1090 if (_has_appendix) {
1091 handle_oop_offset();
1092 _offset++;
1093 }
1094 }
1095 };
1096
1097 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
1098 const RegisterMap* reg_map, OopClosure* f) const {
1099 // ResourceMark rm;
1100 CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
1101 finder.oops_do();
1418 tos = MAX2(tos, interpreter_frame_expression_stack_at(e));
1419 values.describe(frame_no, interpreter_frame_expression_stack_at(e),
1420 err_msg("stack %d", e), 1);
1421 }
1422 if (tos != nullptr) {
1423 values.describe(-1, tos, err_msg("expression stack for #%d", frame_no), 2);
1424 }
1425
1426 if (reg_map != nullptr) {
1427 FrameValuesOopClosure oopsFn;
1428 oops_do(&oopsFn, nullptr, &oopsFn, reg_map);
1429 oopsFn.describe(values, frame_no);
1430 }
1431 } else if (is_entry_frame()) {
1432 // For now just label the frame
1433 values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2);
1434 } else if (is_compiled_frame()) {
1435 // For now just label the frame
1436 nmethod* nm = cb()->as_nmethod();
1437 values.describe(-1, info_address,
1438 FormatBuffer<1024>("#%d nmethod (%s %d) " INTPTR_FORMAT " for method J %s%s", frame_no,
1439 nm->is_compiled_by_c1() ? "c1" : "c2", nm->frame_size(), p2i(nm),
1440 nm->method()->name_and_sig_as_C_string(),
1441 (_deopt_state == is_deoptimized) ?
1442 " (deoptimized)" :
1443 ((_deopt_state == unknown) ? " (state unknown)" : "")),
1444 3);
1445
1446 { // mark arguments (see nmethod::print_nmethod_labels)
1447 Method* m = nm->method();
1448
1449 CompiledEntrySignature ces(m);
1450 ces.compute_calling_conventions(false);
1451 const GrowableArray<SigEntry>* sig_cc = nm->is_compiled_by_c2() ? ces.sig_cc() : ces.sig();
1452 const VMRegPair* regs = nm->is_compiled_by_c2() ? ces.regs_cc() : ces.regs();
1453
1454 int stack_slot_offset = nm->frame_size() * wordSize; // offset, in bytes, to caller sp
1455 int out_preserve = SharedRuntime::out_preserve_stack_slots();
1456 int sig_index = 0;
1457 int arg_index = (m->is_static() ? 0 : -1);
1458 for (ExtendedSignature sig = ExtendedSignature(sig_cc, SigEntryFilter()); !sig.at_end(); ++sig) {
1459 bool at_this = (arg_index == -1);
1460 BasicType t = (*sig)._bt;
1461 VMReg fst = regs[sig_index].first();
1462 if (fst->is_stack()) {
1463 assert(((int)fst->reg2stack()) >= 0, "reg2stack: %d", fst->reg2stack());
1464 int offset = (fst->reg2stack() + out_preserve) * VMRegImpl::stack_slot_size + stack_slot_offset;
1465 intptr_t* stack_address = (intptr_t*)((address)unextended_sp() + offset);
1466 if (at_this) {
1467 values.describe(frame_no, stack_address, err_msg("this for #%d", frame_no), 1);
1468 } else {
1469 values.describe(frame_no, stack_address, err_msg("param %d %s for #%d", arg_index, type2name(t), frame_no), 1);
1470 }
1471 }
1472 sig_index += type2size[t];
1473 arg_index += 1;
1474 }
1475 }
1476
1477 if (reg_map != nullptr && is_java_frame()) {
1478 int scope_no = 0;
1479 for (ScopeDesc* scope = nm->scope_desc_at(pc()); scope != nullptr; scope = scope->sender(), scope_no++) {
1480 Method* m = scope->method();
1481 int bci = scope->bci();
1482 values.describe(-1, info_address, err_msg("- #%d scope %s @ %d", scope_no, m->name_and_sig_as_C_string(), bci), 2);
1483
1484 { // mark locals
1485 GrowableArray<ScopeValue*>* scvs = scope->locals();
1486 int scvs_length = scvs != nullptr ? scvs->length() : 0;
1487 for (int i = 0; i < scvs_length; i++) {
1488 intptr_t* stack_address = (intptr_t*)StackValue::stack_value_address(this, reg_map, scvs->at(i));
1489 if (stack_address != nullptr) {
1490 values.describe(frame_no, stack_address, err_msg("local %d for #%d (scope %d)", i, frame_no, scope_no), 1);
1491 }
1492 }
1493 }
|