6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")

Mark in PcDesc call sites which return oop and save the result oop across objects reallocation during deoptimization.

Reviewed-by: never
This commit is contained in:
Vladimir Kozlov 2010-02-09 01:31:13 -08:00
parent 3f7a94c3f2
commit 22409a5704
12 changed files with 133 additions and 11 deletions

View file

@ -282,6 +282,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
int bci,
bool reexecute,
bool is_method_handle_invoke,
bool return_oop,
DebugToken* locals,
DebugToken* expressions,
DebugToken* monitors) {
@ -296,6 +297,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
// Record flags into pcDesc.
last_pd->set_should_reexecute(reexecute);
last_pd->set_is_method_handle_invoke(is_method_handle_invoke);
last_pd->set_return_oop(return_oop);
// serialize sender stream offest
stream()->write_int(sender_stream_offset);

View file

@ -89,6 +89,7 @@ class DebugInformationRecorder: public ResourceObj {
int bci,
bool reexecute,
bool is_method_handle_invoke = false,
bool return_oop = false,
DebugToken* locals = NULL,
DebugToken* expressions = NULL,
DebugToken* monitors = NULL);

View file

@ -988,7 +988,8 @@ ScopeDesc* nmethod::scope_desc_at(address pc) {
PcDesc* pd = pc_desc_at(pc);
guarantee(pd != NULL, "scope must be present");
return new ScopeDesc(this, pd->scope_decode_offset(),
pd->obj_decode_offset(), pd->should_reexecute());
pd->obj_decode_offset(), pd->should_reexecute(),
pd->return_oop());
}
@ -2159,7 +2160,8 @@ void nmethod::verify_interrupt_point(address call_site) {
PcDesc* pd = pc_desc_at(ic->end_of_call());
assert(pd != NULL, "PcDesc must exist");
for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
pd->obj_decode_offset(), pd->should_reexecute());
pd->obj_decode_offset(), pd->should_reexecute(),
pd->return_oop());
!sd->is_top(); sd = sd->sender()) {
sd->verify();
}
@ -2424,7 +2426,8 @@ ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
PcDesc* p = pc_desc_near(begin+1);
if (p != NULL && p->real_pc(this) <= end) {
return new ScopeDesc(this, p->scope_decode_offset(),
p->obj_decode_offset(), p->should_reexecute());
p->obj_decode_offset(), p->should_reexecute(),
p->return_oop());
}
return NULL;
}

View file

@ -39,6 +39,7 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
struct {
unsigned int reexecute: 1;
unsigned int is_method_handle_invoke: 1;
unsigned int return_oop: 1;
} bits;
bool operator ==(const PcDescFlags& other) { return word == other.word; }
} _flags;
@ -76,6 +77,9 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
bool is_method_handle_invoke() const { return _flags.bits.is_method_handle_invoke; }
void set_is_method_handle_invoke(bool z) { _flags.bits.is_method_handle_invoke = z; }
bool return_oop() const { return _flags.bits.return_oop; }
void set_return_oop(bool z) { _flags.bits.return_oop = z; }
// Returns the real pc
address real_pc(const nmethod* code) const;

View file

@ -26,19 +26,21 @@
# include "incls/_scopeDesc.cpp.incl"
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute) {
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) {
_code = code;
_decode_offset = decode_offset;
_objects = decode_object_values(obj_decode_offset);
_reexecute = reexecute;
_return_oop = return_oop;
decode_body();
}
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute) {
ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) {
_code = code;
_decode_offset = decode_offset;
_objects = decode_object_values(DebugInformationRecorder::serialized_null);
_reexecute = reexecute;
_return_oop = return_oop;
decode_body();
}
@ -48,6 +50,7 @@ ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
_decode_offset = parent->_sender_decode_offset;
_objects = parent->_objects;
_reexecute = false; //reexecute only applies to the first scope
_return_oop = false;
decode_body();
}

View file

@ -52,17 +52,18 @@ class SimpleScopeDesc : public StackObj {
class ScopeDesc : public ResourceObj {
public:
// Constructor
ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute);
ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop);
// Calls above, giving default value of "serialized_null" to the
// "obj_decode_offset" argument. (We don't use a default argument to
// avoid a .hpp-.hpp dependency.)
ScopeDesc(const nmethod* code, int decode_offset, bool reexecute);
ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop);
// JVM state
methodHandle method() const { return _method; }
int bci() const { return _bci; }
bool should_reexecute() const { return _reexecute; }
bool return_oop() const { return _return_oop; }
GrowableArray<ScopeValue*>* locals();
GrowableArray<ScopeValue*>* expressions();
@ -88,6 +89,7 @@ class ScopeDesc : public ResourceObj {
methodHandle _method;
int _bci;
bool _reexecute;
bool _return_oop;
// Decoding offsets
int _decode_offset;