This commit is contained in:
Igor Veresov 2010-01-06 22:21:39 -08:00
commit 5bec0d60ab
144 changed files with 4007 additions and 823 deletions

View file

@ -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; };

View file

@ -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);

View file

@ -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);

View file

@ -1170,7 +1170,7 @@ void nmethod::log_state_change() const {
}
// Common functionality for both make_not_entrant and make_zombie
bool nmethod::make_not_entrant_or_zombie(int state) {
bool nmethod::make_not_entrant_or_zombie(unsigned int state) {
assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
// If the method is already zombie there is nothing to do
@ -1724,9 +1724,9 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
if (!method()->is_native()) {
SimpleScopeDesc ssd(this, fr.pc());
Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
bool is_static = call->is_invokestatic();
bool has_receiver = call->has_receiver();
symbolOop signature = call->signature();
fr.oops_compiled_arguments_do(signature, is_static, reg_map, f);
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
}
}
@ -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

View file

@ -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();
};
@ -254,7 +255,7 @@ class nmethod : public CodeBlob {
const char* reloc_string_for(u_char* begin, u_char* end);
// Returns true if this thread changed the state of the nmethod or
// false if another thread performed the transition.
bool make_not_entrant_or_zombie(int state);
bool make_not_entrant_or_zombie(unsigned int state);
void inc_decompile_count();
// used to check that writes to nmFlags are done consistently.
@ -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();

View file

@ -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;