- diff -u -r ./hotspot/src_/share/vm/prims/jvmtiEnv.cpp ./hotspot/src/share/vm/prims/jvmtiEnv.cpp
- --- ./hotspot/src_/share/vm/prims/jvmtiEnv.cpp 2013-12-19 01:10:36.297992000 +0100
- +++ ./hotspot/src/share/vm/prims/jvmtiEnv.cpp 2014-02-10 14:52:14.734339000 +0100
- @@ -1982,6 +1982,106 @@
- //
- + // Operand Stack functions
- + //
-
- +// Threads_lock NOT held, java_thread not protected by lock
- +// java_thread - pre-checked
- +// java_thread - unchecked
- +// depth - pre-checked as non-negative
- +// value_ptr - pre-checked for NULL
- +jvmtiError
- +JvmtiEnv::GetOperandObject(JavaThread* java_thread, jint depth, jint slot, jobject* value_ptr) {
- + JavaThread* current_thread = JavaThread::current();
- + // rm object is created to clean up the javaVFrame created in
- + // doit_prologue(), but after doit() is finished with it.
- + ResourceMark rm(current_thread);
-
- + VM_GetOperand op(java_thread, current_thread, depth, slot);
- + VMThread::execute(&op);
- + jvmtiError err = op.result();
- + if (err != JVMTI_ERROR_NONE) {
- + return err;
- + } else {
- + *value_ptr = op.value().l;
- + return JVMTI_ERROR_NONE;
- + }
- +} /* end GetOperandObject */
-
-
- +// Threads_lock NOT held, java_thread not protected by lock
- +// java_thread - pre-checked
- +// java_thread - unchecked
- +// depth - pre-checked as non-negative
- +// value_ptr - pre-checked for NULL
- +jvmtiError
- +JvmtiEnv::GetOperandInt(JavaThread* java_thread, jint depth, jint slot, jint* value_ptr) {
- + // rm object is created to clean up the javaVFrame created in
- + // doit_prologue(), but after doit() is finished with it.
- + ResourceMark rm;
-
- + VM_GetOperand op(java_thread, depth, slot, T_INT);
- + VMThread::execute(&op);
- + *value_ptr = op.value().i;
- + return op.result();
- +} /* end GetOperandInt */
-
-
- +// Threads_lock NOT held, java_thread not protected by lock
- +// java_thread - pre-checked
- +// java_thread - unchecked
- +// depth - pre-checked as non-negative
- +// value_ptr - pre-checked for NULL
- +jvmtiError
- +JvmtiEnv::GetOperandLong(JavaThread* java_thread, jint depth, jint slot, jlong* value_ptr) {
- + // rm object is created to clean up the javaVFrame created in
- + // doit_prologue(), but after doit() is finished with it.
- + ResourceMark rm;
-
- + VM_GetOperand op(java_thread, depth, slot, T_LONG);
- + VMThread::execute(&op);
- + *value_ptr = op.value().j;
- + return op.result();
- +} /* end GetOperandLong */
-
-
- +// Threads_lock NOT held, java_thread not protected by lock
- +// java_thread - pre-checked
- +// java_thread - unchecked
- +// depth - pre-checked as non-negative
- +// value_ptr - pre-checked for NULL
- +jvmtiError
- +JvmtiEnv::GetOperandFloat(JavaThread* java_thread, jint depth, jint slot, jfloat* value_ptr) {
- + // rm object is created to clean up the javaVFrame created in
- + // doit_prologue(), but after doit() is finished with it.
- + ResourceMark rm;
-
- + VM_GetOperand op(java_thread, depth, slot, T_FLOAT);
- + VMThread::execute(&op);
- + *value_ptr = op.value().f;
- + return op.result();
- +} /* end GetOperandFloat */
-
-
- +// Threads_lock NOT held, java_thread not protected by lock
- +// java_thread - pre-checked
- +// java_thread - unchecked
- +// depth - pre-checked as non-negative
- +// value_ptr - pre-checked for NULL
- +jvmtiError
- +JvmtiEnv::GetOperandDouble(JavaThread* java_thread, jint depth, jint slot, jdouble* value_ptr) {
- + // rm object is created to clean up the javaVFrame created in
- + // doit_prologue(), but after doit() is finished with it.
- + ResourceMark rm;
-
- + VM_GetOperand op(java_thread, depth, slot, T_DOUBLE);
- + VMThread::execute(&op);
- + *value_ptr = op.value().d;
- + return op.result();
- +} /* end GetOperandDouble */
-
-
- + //
- // Breakpoint functions
- //
- diff -u -r ./hotspot/src_/share/vm/prims/jvmtiImpl.cpp ./hotspot/src/share/vm/prims/jvmtiImpl.cpp
- --- ./hotspot/src_/share/vm/prims/jvmtiImpl.cpp 2013-12-19 01:10:36.309992000 +0100
- +++ ./hotspot/src/share/vm/prims/jvmtiImpl.cpp 2014-02-10 14:57:14.350344000 +0100
- @@ -827,6 +827,147 @@
- JavaThread* thread, JavaThread* caller_thread, jint depth)
- : VM_GetOrSetLocal(thread, caller_thread, depth, 0) {}
-
- +///////////////////////////////////////////////////////////////
- +//
- +// class VM_GetOperand
- +//
-
- +// Constructor for non-object getter
- +VM_GetOperand::VM_GetOperand(JavaThread* thread, jint depth, int index, BasicType type)
- + : _thread(thread)
- + , _calling_thread(NULL)
- + , _depth(depth)
- + , _index(index)
- + , _type(type)
- + , _jvf(NULL)
- + , _result(JVMTI_ERROR_NONE)
- +{
- +}
-
- +// Constructor for object getter
- +VM_GetOperand::VM_GetOperand(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
- + : _thread(thread)
- + , _calling_thread(calling_thread)
- + , _depth(depth)
- + , _index(index)
- + , _type(T_OBJECT)
- + , _jvf(NULL)
- + , _result(JVMTI_ERROR_NONE)
- +{
- +}
-
- +vframe *VM_GetOperand::get_vframe() {
- + if (!_thread->has_last_Java_frame()) {
- + return NULL;
- + }
- + RegisterMap reg_map(_thread);
- + vframe *vf = _thread->last_java_vframe(®_map);
- + int d = 0;
- + while ((vf != NULL) && (d < _depth)) {
- + vf = vf->java_sender();
- + d++;
- + }
- + return vf;
- +}
-
- +javaVFrame *VM_GetOperand::get_java_vframe() {
- + vframe* vf = get_vframe();
- + if (vf == NULL) {
- + _result = JVMTI_ERROR_NO_MORE_FRAMES;
- + return NULL;
- + }
- + javaVFrame *jvf = (javaVFrame*)vf;
-
- + if (!vf->is_java_frame()) {
- + _result = JVMTI_ERROR_OPAQUE_FRAME;
- + return NULL;
- + }
- + return jvf;
- +}
-
- +// Checks error conditions:
- +// JVMTI_ERROR_INVALID_SLOT
- +// Returns: 'true' - everything is Ok, 'false' - error code
- +bool VM_GetOperand::check_slot_type(javaVFrame* jvf) {
- + // index checking
- + StackValueCollection *expressions = _jvf->expressions();
- + jint size = expressions->size();
- + size -= (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
- +
- + if (_index < 0 || _index >= size) {
- + _result = JVMTI_ERROR_INVALID_SLOT;
- + return false;
- + }
- +
- + // FIXME insert proper type-checking code here
- +
- + return true;
- +}
-
- +bool VM_GetOperand::doit_prologue() {
- + _jvf = get_java_vframe();
- + NULL_CHECK(_jvf, false);
-
- + if (_jvf->method()->is_native()) {
- + if (getting_receiver() && !_jvf->method()->is_static()) {
- + return true;
- + } else {
- + _result = JVMTI_ERROR_OPAQUE_FRAME;
- + return false;
- + }
- + }
-
- + if (!check_slot_type(_jvf)) {
- + return false;
- + }
- + return true;
- +}
-
- +void VM_GetOperand::doit() {
- + // get
- + if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
- + assert(getting_receiver(), "Can only get here when getting receiver");
- + oop receiver = _jvf->fr().get_native_receiver();
- + _value.l = JNIHandles::make_local(_calling_thread, receiver);
- + } else {
- + StackValueCollection *expressions = _jvf->expressions();
-
- + if (expressions->at(_index)->type() == T_CONFLICT) {
- + memset(&_value, 0, sizeof(_value));
- + _value.l = NULL;
- + return;
- + }
-
- + switch (_type) {
- + case T_INT: _value.i = expressions->int_at (_index); break;
- + case T_LONG: _value.j = expressions->long_at (_index); break;
- + case T_FLOAT: _value.f = expressions->float_at (_index); break;
- + case T_DOUBLE: _value.d = expressions->double_at(_index); break;
- + case T_OBJECT: {
- + // Wrap the oop to be returned in a local JNI handle since
- + // oops_do() no longer applies after doit() is finished.
- + intptr_t temp = expressions->at(_index)->get_int();
- + intptr_t *addr = &temp;
- + _value.l = JNIHandles::make_local(_calling_thread, *(oop *)addr);
- + break;
- + }
- + default: ShouldNotReachHere();
- + }
- + }
- +}
-
-
- +bool VM_GetOperand::allow_nested_vm_operations() const {
- + return true; // May need to deoptimize
- +}
-
-
- +VM_GetOperandReceiver::VM_GetOperandReceiver(
- + JavaThread* thread, JavaThread* caller_thread, jint depth)
- + : VM_GetOperand(thread, caller_thread, depth, 0) {}
-
-
- /////////////////////////////////////////////////////////////////////////////////////////
- //
- diff -u -r ./hotspot/src_/share/vm/prims/jvmtiImpl.hpp ./hotspot/src/share/vm/prims/jvmtiImpl.hpp
- --- ./hotspot/src_/share/vm/prims/jvmtiImpl.hpp 2013-12-19 01:10:36.309992000 +0100
- +++ ./hotspot/src/share/vm/prims/jvmtiImpl.hpp 2014-02-10 14:54:03.762341000 +0100
- @@ -400,6 +400,58 @@
- ///////////////////////////////////////////////////////////////
- +// This is a copy of VM_GetOrSetLocal modified to access operands
- +// instead of local variables.
- +//
- +class VM_GetOperand : public VM_Operation {
- + protected:
- + JavaThread* _thread;
- + JavaThread* _calling_thread;
- + jint _depth;
- + jint _index;
- + BasicType _type;
- + jvalue _value;
- + javaVFrame* _jvf;
-
- + // It is possible to get the receiver out of a non-static native wrapper
- + // frame. Use VM_GetReceiver to do this.
- + virtual bool getting_receiver() const { return false; }
-
- + jvmtiError _result;
-
- + vframe* get_vframe();
- + javaVFrame* get_java_vframe();
- + bool check_slot_type(javaVFrame* vf);
-
- +public:
- + // Constructor for non-object getter
- + VM_GetOperand(JavaThread* thread, jint depth, jint index, BasicType type);
-
- + // Constructor for object getter
- + VM_GetOperand(JavaThread* thread, JavaThread* calling_thread, jint depth,
- + int index);
-
- + VMOp_Type type() const { return VMOp_GetOperand; }
- + jvalue value() { return _value; }
- + jvmtiError result() { return _result; }
-
- + bool doit_prologue();
- + void doit();
- + bool allow_nested_vm_operations() const;
- + const char* name() const { return "get operands"; }
- +};
-
- +class VM_GetOperandReceiver : public VM_GetOperand {
- + protected:
- + virtual bool getting_receiver() const { return true; }
-
- + public:
- + VM_GetOperandReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth);
- + const char* name() const { return "get operand receiver"; }
- +};
-
-
- +///////////////////////////////////////////////////////////////
- //
- // class JvmtiSuspendControl
- //
- diff -u -r ./hotspot/src_/share/vm/prims/jvmti.xml ./hotspot/src/share/vm/prims/jvmti.xml
- --- ./hotspot/src_/share/vm/prims/jvmti.xml 2013-12-19 01:10:36.293992000 +0100
- +++ ./hotspot/src/share/vm/prims/jvmti.xml 2014-02-10 14:50:31.750337000 +0100
- @@ -6137,6 +6137,266 @@
- +
- +
-
- +
- + These functions are used to retrieve or set the value of an operand stack slot.
- + The slot is identified by the depth of the frame containing its
- + value and the slot's number within that frame.
- +
- +
- +
- + Get Operand Stack Value - Object
- +
- + This function can be used to retrieve the value of an operand
- + stack slot whose type is
Object
or a subclass of Object
.
- +
- + jvmdi
- +
- +
- +
- +
- +
- +
- +
- + The thread of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The depth of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The slot's number.
- +
- +
- +
- +
- +
- + On return, points to the slot's value.
- +
- +
- +
- +
- +
- + Invalid
slot
.
- +
- +
- + The slot's type is not
- +
Object
or a subclass of Object
.
- +
- +
- + Not a visible frame
- +
- +
- +
- +
- +
- + Get Operand Stack Value - Int
- +
- + This function can be used to retrieve the value of an operand
- + stack slot whose type is
int
,
- +
short
, char
, byte
, or
- +
boolean
.
- +
- + jvmdi
- +
- +
- +
- +
- +
- +
- +
- + The thread of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The depth of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The slot's number.
- +
- +
- +
- +
- +
- + On return, points to the slot's value.
- +
- +
- +
- +
- +
- + Invalid
slot
.
- +
- +
- + The slot's type is not
- +
int
, short
,
- +
char
, byte
, or
- +
boolean
.
- +
- +
- + Not a visible frame
- +
- +
- +
- +
- +
- + Get Operand Stack Value - Long
- +
- + This function can be used to retrieve the value of an operand
- + stack slot whose type is
long
.
- +
- + jvmdi
- +
- +
- +
- +
- +
- +
- +
- + The thread of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The depth of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The slot's number.
- +
- +
- +
- +
- +
- + On return, points to the slot's value.
- +
- +
- +
- +
- +
- + Invalid
slot
.
- +
- +
- + The variable type is not
long
.
- +
- +
- + Not a visible frame
- +
- +
- +
- +
- +
- + Get Operand Stack Value - Float
- +
- + This function can be used to retrieve the value of an operand
- + stack slot whose type is
float
.
- +
- + jvmdi
- +
- +
- +
- +
- +
- +
- +
- + The thread of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The depth of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The slot's number.
- +
- +
- +
- +
- +
- + On return, points to the slot's value.
- +
- +
- +
- +
- +
- + Invalid
slot
.
- +
- +
- + The variable type is not
float
.
- +
- +
- + Not a visible frame
- +
- +
- +
- +
- +
- + Get Operand Stack Value - Double
- +
- + This function can be used to retrieve the value of an operand
- + stack slot whose type is
double
.
- +
- + jvmdi
- +
- +
- +
- +
- +
- +
- +
- + The thread of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The depth of the frame containing the slot's value.
- +
- +
- +
- +
- +
- + The slot's number.
- +
- +
- +
- +
- +
- + On return, points to the slot's value.
- +
- +
- +
- +
- +
- + Invalid
slot
.
- +
- +
- + The variable type is not
double
.
- +
- +
- + Not a visible frame
- +
- +
- +
- +
- diff -u -r ./hotspot/src_/share/vm/runtime/vm_operations.hpp ./hotspot/src/share/vm/runtime/vm_operations.hpp
- --- ./hotspot/src_/share/vm/runtime/vm_operations.hpp 2013-12-19 01:10:36.377992000 +0100
- +++ ./hotspot/src/share/vm/runtime/vm_operations.hpp 2014-02-10 14:48:02.346335000 +0100
- @@ -87,6 +87,7 @@
- template(GetFrameLocation) \
- template(ChangeBreakpoints) \
- template(GetOrSetLocal) \
- + template(GetOperand) \
- template(GetCurrentLocation) \
- template(EnterInterpOnlyMode) \
- template(ChangeSingleStep) \