mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +02:00
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:
parent
3f7a94c3f2
commit
22409a5704
12 changed files with 133 additions and 11 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue