--- old/src/hotspot/share/runtime/frame.cpp 2019-03-11 14:27:12.414354239 +0100 +++ new/src/hotspot/share/runtime/frame.cpp 2019-03-11 14:27:12.138354243 +0100 @@ -36,6 +36,7 @@ #include "oops/method.hpp" #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" +#include "oops/valueKlass.hpp" #include "oops/verifyOopClosure.hpp" #include "prims/methodHandles.hpp" #include "runtime/frame.inline.hpp" @@ -732,7 +733,7 @@ public: InterpreterFrameClosure(frame* fr, int max_locals, int max_stack, - OopClosure* f) { + OopClosure* f, BufferedValueClosure* bvt_f) { _fr = fr; _max_locals = max_locals; _max_stack = max_stack; @@ -744,7 +745,9 @@ if (offset < _max_locals) { addr = (oop*) _fr->interpreter_frame_local_at(offset); assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame"); - _f->do_oop(addr); + if (_f != NULL) { + _f->do_oop(addr); + } } else { addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals)); // In case of exceptions, the expression stack is invalid and the esp will be reset to express @@ -756,7 +759,9 @@ in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address(); } if (in_stack) { - _f->do_oop(addr); + if (_f != NULL) { + _f->do_oop(addr); + } } } } @@ -775,7 +780,7 @@ void set(int size, BasicType type) { _offset -= size; - if (type == T_OBJECT || type == T_ARRAY) oop_offset_do(); + if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) oop_offset_do(); } void oop_offset_do() { @@ -828,7 +833,7 @@ void set(int size, BasicType type) { assert (_offset >= 0, "illegal offset"); - if (type == T_OBJECT || type == T_ARRAY) oop_at_offset_do(_offset); + if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) oop_at_offset_do(_offset); _offset -= size; } @@ -929,7 +934,7 @@ } } - InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f); + InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f, NULL); // process locals & expression stack InterpreterOopMap mask; @@ -941,6 +946,23 @@ mask.iterate_oop(&blk); } +void frame::buffered_values_interpreted_do(BufferedValueClosure* f) { + assert(is_interpreted_frame(), "Not an interpreted frame"); + Thread *thread = Thread::current(); + methodHandle m (thread, interpreter_frame_method()); + jint bci = interpreter_frame_bci(); + + assert(m->is_method(), "checking frame value"); + assert(!m->is_native() && bci >= 0 && bci < m->code_size(), + "invalid bci value"); + + InterpreterFrameClosure blk(this, m->max_locals(), m->max_stack(), NULL, f); + + // process locals & expression stack + InterpreterOopMap mask; + m->mask_for(bci, &mask); + mask.iterate_oop(&blk); +} void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) { InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); @@ -979,20 +1001,21 @@ VMRegPair* _regs; // VMReg list of arguments void set(int size, BasicType type) { - if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset(); + if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) handle_oop_offset(); _offset += size; } virtual void handle_oop_offset() { // Extract low order register number from register array. // In LP64-land, the high-order bits are valid but unhelpful. + assert(_offset < _arg_size, "out of bounds"); VMReg reg = _regs[_offset].first(); oop *loc = _fr.oopmapreg_to_location(reg, _reg_map); _f->do_oop(loc); } public: - CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map) + CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map) : SignatureInfo(signature) { // initialize CompiledArgumentOopFinder @@ -1002,11 +1025,7 @@ _has_appendix = has_appendix; _fr = fr; _reg_map = (RegisterMap*)reg_map; - _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0); - - int arg_size; - _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size); - assert(arg_size == _arg_size, "wrong arg size"); + _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &_arg_size); } void oops_do() {