mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +02:00
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
During the work for 6829187 we have fixed a number of basic bugs which are logically grouped with 6815692 and 6858164 but which must be reviewed and pushed separately. Reviewed-by: kvn, never
This commit is contained in:
parent
14305ba3f4
commit
caf28727eb
32 changed files with 242 additions and 84 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -102,6 +102,9 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||
virtual bool is_compiled_by_c2() const { return false; }
|
||||
virtual bool is_compiled_by_c1() const { return false; }
|
||||
|
||||
// Casting
|
||||
nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : NULL; }
|
||||
|
||||
// Boundaries
|
||||
address header_begin() const { return (address) this; }
|
||||
address header_end() const { return ((address) this) + _header_size; };
|
||||
|
|
|
@ -281,6 +281,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
|
|||
ciMethod* method,
|
||||
int bci,
|
||||
bool reexecute,
|
||||
bool is_method_handle_invoke,
|
||||
DebugToken* locals,
|
||||
DebugToken* expressions,
|
||||
DebugToken* monitors) {
|
||||
|
@ -292,8 +293,9 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
|
|||
int stream_offset = stream()->position();
|
||||
last_pd->set_scope_decode_offset(stream_offset);
|
||||
|
||||
// Record reexecute bit into pcDesc
|
||||
// Record flags into pcDesc.
|
||||
last_pd->set_should_reexecute(reexecute);
|
||||
last_pd->set_is_method_handle_invoke(is_method_handle_invoke);
|
||||
|
||||
// serialize sender stream offest
|
||||
stream()->write_int(sender_stream_offset);
|
||||
|
|
|
@ -88,6 +88,7 @@ class DebugInformationRecorder: public ResourceObj {
|
|||
ciMethod* method,
|
||||
int bci,
|
||||
bool reexecute,
|
||||
bool is_method_handle_invoke = false,
|
||||
DebugToken* locals = NULL,
|
||||
DebugToken* expressions = NULL,
|
||||
DebugToken* monitors = NULL);
|
||||
|
|
|
@ -1763,6 +1763,14 @@ void nmethod::copy_scopes_pcs(PcDesc* pcs, int count) {
|
|||
"must end with a sentinel");
|
||||
#endif //ASSERT
|
||||
|
||||
// Search for MethodHandle invokes and tag the nmethod.
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (pcs[i].is_method_handle_invoke()) {
|
||||
set_has_method_handle_invokes(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int size = count * sizeof(PcDesc);
|
||||
assert(scopes_pcs_size() >= size, "oob");
|
||||
memcpy(scopes_pcs_begin(), pcs, size);
|
||||
|
@ -2029,6 +2037,18 @@ bool nmethod::is_deopt_pc(address pc) {
|
|||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// MethodHandle
|
||||
|
||||
bool nmethod::is_method_handle_return(address return_pc) {
|
||||
if (!has_method_handle_invokes()) return false;
|
||||
PcDesc* pd = pc_desc_at(return_pc);
|
||||
if (pd == NULL)
|
||||
return false;
|
||||
return pd->is_method_handle_invoke();
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Verification
|
||||
|
||||
|
|
|
@ -81,18 +81,19 @@ class PcDescCache VALUE_OBJ_CLASS_SPEC {
|
|||
|
||||
struct nmFlags {
|
||||
friend class VMStructs;
|
||||
unsigned int version:8; // version number (0 = first version)
|
||||
unsigned int level:4; // optimization level
|
||||
unsigned int age:4; // age (in # of sweep steps)
|
||||
unsigned int version:8; // version number (0 = first version)
|
||||
unsigned int level:4; // optimization level
|
||||
unsigned int age:4; // age (in # of sweep steps)
|
||||
|
||||
unsigned int state:2; // {alive, zombie, unloaded)
|
||||
unsigned int state:2; // {alive, zombie, unloaded)
|
||||
|
||||
unsigned int isUncommonRecompiled:1; // recompiled because of uncommon trap?
|
||||
unsigned int isToBeRecompiled:1; // to be recompiled as soon as it matures
|
||||
unsigned int hasFlushedDependencies:1; // Used for maintenance of dependencies
|
||||
unsigned int markedForReclamation:1; // Used by NMethodSweeper
|
||||
unsigned int isUncommonRecompiled:1; // recompiled because of uncommon trap?
|
||||
unsigned int isToBeRecompiled:1; // to be recompiled as soon as it matures
|
||||
unsigned int hasFlushedDependencies:1; // Used for maintenance of dependencies
|
||||
unsigned int markedForReclamation:1; // Used by NMethodSweeper
|
||||
|
||||
unsigned int has_unsafe_access:1; // May fault due to unsafe access.
|
||||
unsigned int has_unsafe_access:1; // May fault due to unsafe access.
|
||||
unsigned int has_method_handle_invokes:1; // Has this method MethodHandle invokes?
|
||||
|
||||
void clear();
|
||||
};
|
||||
|
@ -409,6 +410,9 @@ class nmethod : public CodeBlob {
|
|||
bool has_unsafe_access() const { return flags.has_unsafe_access; }
|
||||
void set_has_unsafe_access(bool z) { flags.has_unsafe_access = z; }
|
||||
|
||||
bool has_method_handle_invokes() const { return flags.has_method_handle_invokes; }
|
||||
void set_has_method_handle_invokes(bool z) { flags.has_method_handle_invokes = z; }
|
||||
|
||||
int level() const { return flags.level; }
|
||||
void set_level(int newLevel) { check_safepoint(); flags.level = newLevel; }
|
||||
|
||||
|
@ -541,6 +545,9 @@ class nmethod : public CodeBlob {
|
|||
address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
|
||||
void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; }
|
||||
|
||||
// MethodHandle
|
||||
bool is_method_handle_return(address return_pc);
|
||||
|
||||
// jvmti support:
|
||||
void post_compiled_method_load_event();
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
|
|||
int word;
|
||||
struct {
|
||||
unsigned int reexecute: 1;
|
||||
unsigned int is_method_handle_invoke: 1;
|
||||
} bits;
|
||||
bool operator ==(const PcDescFlags& other) { return word == other.word; }
|
||||
} _flags;
|
||||
|
@ -72,6 +73,9 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
|
|||
_flags == pd->_flags;
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
// Returns the real pc
|
||||
address real_pc(const nmethod* code) const;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue