8173309: jvmtiDeferredLocalVariableSet may update the wrong frame

Reviewed-by: kvn
This commit is contained in:
Tom Rodriguez 2017-01-25 19:18:43 -08:00
parent 9b352ebabe
commit e56234d68b
2 changed files with 18 additions and 8 deletions

View File

@ -158,7 +158,7 @@ void compiledVFrame::update_local(BasicType type, int index, jvalue value) {
deferred = new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true);
thread()->set_deferred_locals(deferred);
}
deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id()));
deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id(), vframe_id()));
assert(deferred->top()->id() == fr().id(), "Huh? Must match");
deferred->top()->set_local_at(index, type, value);
}
@ -243,6 +243,7 @@ GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, CompiledMethod* nm)
: javaVFrame(fr, reg_map, thread) {
_scope = NULL;
_vframe_id = 0;
// Compiled method (native stub or Java code)
// native wrappers have no scope data, it is implied
if (!nm->is_compiled() || !nm->as_compiled_method()->is_native_method()) {
@ -250,9 +251,10 @@ compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, Java
}
}
compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope)
compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope, int vframe_id)
: javaVFrame(fr, reg_map, thread) {
_scope = scope;
_vframe_id = vframe_id;
guarantee(_scope != NULL, "scope must be present");
}
@ -316,14 +318,15 @@ vframe* compiledVFrame::sender() const {
} else {
return scope()->is_top()
? vframe::sender()
: new compiledVFrame(&f, register_map(), thread(), scope()->sender());
: new compiledVFrame(&f, register_map(), thread(), scope()->sender(), vframe_id() + 1);
}
}
jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id) {
jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id, int vframe_id) {
_method = method;
_bci = bci;
_id = id;
_vframe_id = vframe_id;
// Alway will need at least one, must be on C heap
_locals = new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariable*> (1, true);
}
@ -339,7 +342,11 @@ jvmtiDeferredLocalVariableSet::~jvmtiDeferredLocalVariableSet() {
bool jvmtiDeferredLocalVariableSet::matches(vframe* vf) {
if (!vf->is_compiled_frame()) return false;
compiledVFrame* cvf = (compiledVFrame*)vf;
return cvf->fr().id() == id() && cvf->method() == method() && cvf->bci() == bci();
if (cvf->fr().id() == id() && cvf->vframe_id() == vframe_id()) {
assert(cvf->method() == method() && cvf->bci() == bci(), "must agree");
return true;
}
return false;
}
void jvmtiDeferredLocalVariableSet::set_local_at(int idx, BasicType type, jvalue val) {

View File

@ -36,6 +36,7 @@ class compiledVFrame: public javaVFrame {
StackValueCollection* locals() const;
StackValueCollection* expressions() const;
GrowableArray<MonitorInfo*>* monitors() const;
int vframe_id() const { return _vframe_id; }
void set_locals(StackValueCollection* values) const;
@ -68,14 +69,14 @@ class compiledVFrame: public javaVFrame {
protected:
ScopeDesc* _scope;
int _vframe_id;
//StackValue resolve(ScopeValue* sv) const;
BasicLock* resolve_monitor_lock(Location location) const;
StackValue *create_stack_value(ScopeValue *sv) const;
private:
compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope);
compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope, int vframe_id);
#ifndef PRODUCT
public:
@ -95,6 +96,7 @@ private:
Method* _method;
int _bci;
intptr_t* _id;
int _vframe_id;
GrowableArray<jvmtiDeferredLocalVariable*>* _locals;
public:
@ -102,6 +104,7 @@ private:
Method* method() const { return _method; }
int bci() const { return _bci; }
intptr_t* id() const { return _id; }
int vframe_id() const { return _vframe_id; }
GrowableArray<jvmtiDeferredLocalVariable*>* locals() const { return _locals; }
void set_local_at(int idx, BasicType typ, jvalue val);
@ -111,7 +114,7 @@ private:
void oops_do(OopClosure* f);
// constructor
jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id);
jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id, int vframe_id);
// destructor
~jvmtiDeferredLocalVariableSet();