This commit is contained in:
Keith McGuigan 2008-04-04 10:48:43 -04:00
commit dcfe7d7fc6
7 changed files with 52 additions and 26 deletions

View File

@ -6023,7 +6023,7 @@ instruct cmovII_imm(cmpOp cmp, flagsReg icc, iRegI dst, immI11 src) %{
ins_pipe(ialu_imm);
%}
instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{
instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
@ -6032,7 +6032,7 @@ instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{
ins_pipe(ialu_reg);
%}
instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{
instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{
match(Set dst (CMoveI (Binary cmp icc) (Binary dst src)));
ins_cost(140);
size(4);

View File

@ -1122,6 +1122,12 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
// Split through Phi (see original code in loopopts.cpp).
assert(phase->C->have_alias_type(addr_t), "instance should have alias type");
// Do nothing here if Identity will find a value
// (to avoid infinite chain of value phis generation).
if ( !phase->eqv(this, this->Identity(phase)) )
return NULL;
const Type* this_type = this->bottom_type();
int this_index = phase->C->get_alias_index(addr_t);
int this_offset = addr_t->offset();

View File

@ -143,6 +143,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
// relock objects if synchronization on them was eliminated.
if (DoEscapeAnalysis) {
if (EliminateAllocations) {
assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
bool reallocated = false;
if (objects != NULL) {
@ -162,19 +163,26 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
}
}
if (EliminateLocks) {
#ifndef PRODUCT
bool first = true;
#endif
for (int i = 0; i < chunk->length(); i++) {
GrowableArray<MonitorValue*>* monitors = chunk->at(i)->scope()->monitors();
if (monitors != NULL) {
relock_objects(&deoptee, &map, monitors);
compiledVFrame* cvf = chunk->at(i);
assert (cvf->scope() != NULL,"expect only compiled java frames");
GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
if (monitors->is_nonempty()) {
relock_objects(monitors, thread);
#ifndef PRODUCT
if (TraceDeoptimization) {
ttyLocker ttyl;
tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread);
for (int j = 0; j < monitors->length(); j++) {
MonitorValue* mv = monitors->at(j);
if (mv->eliminated()) {
StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner());
tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()());
MonitorInfo* mi = monitors->at(j);
if (mi->eliminated()) {
if (first) {
first = false;
tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread);
}
tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner());
}
}
}
@ -799,18 +807,27 @@ void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableAr
// relock objects for which synchronization was eliminated
void Deoptimization::relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray<MonitorValue*>* monitors) {
void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread) {
for (int i = 0; i < monitors->length(); i++) {
MonitorValue* mv = monitors->at(i);
StackValue* owner = StackValue::create_stack_value(fr, reg_map, mv->owner());
if (mv->eliminated()) {
Handle obj = owner->get_obj();
assert(obj.not_null(), "reallocation was missed");
BasicLock* lock = StackValue::resolve_monitor_lock(fr, mv->basic_lock());
lock->set_displaced_header(obj->mark());
obj->set_mark((markOop) lock);
MonitorInfo* mon_info = monitors->at(i);
if (mon_info->eliminated()) {
assert(mon_info->owner() != NULL, "reallocation was missed");
Handle obj = Handle(mon_info->owner());
markOop mark = obj->mark();
if (UseBiasedLocking && mark->has_bias_pattern()) {
// New allocated objects may have the mark set to anonymously biased.
// Also the deoptimized method may called methods with synchronization
// where the thread-local object is bias locked to the current thread.
assert(mark->is_biased_anonymously() ||
mark->biased_locker() == thread, "should be locked to current thread");
// Reset mark word to unbiased prototype.
markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
obj->set_mark(unbiased_prototype);
}
BasicLock* lock = mon_info->lock();
ObjectSynchronizer::slow_enter(obj, lock, thread);
}
assert(owner->get_obj()->is_locked(), "object must be locked now");
assert(mon_info->owner()->is_locked(), "object must be locked now");
}
}
@ -916,7 +933,7 @@ static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects
GrowableArray<MonitorInfo*>* monitors = cvf->monitors();
for (int i = 0; i < monitors->length(); i++) {
MonitorInfo* mon_info = monitors->at(i);
if (mon_info->owner() != NULL) {
if (mon_info->owner() != NULL && !mon_info->eliminated()) {
objects_to_revoke->append(Handle(mon_info->owner()));
}
}

View File

@ -105,7 +105,7 @@ class Deoptimization : AllStatic {
static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type);
static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj);
static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects);
static void relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray<MonitorValue*>* monitors);
static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread);
NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects);)
#endif // COMPILER2

View File

@ -206,7 +206,7 @@ GrowableArray<MonitorInfo*>* interpretedVFrame::monitors() const {
for (BasicObjectLock* current = (fr().previous_monitor_in_interpreter_frame(fr().interpreter_frame_monitor_begin()));
current >= fr().interpreter_frame_monitor_end();
current = fr().previous_monitor_in_interpreter_frame(current)) {
result->push(new MonitorInfo(current->obj(), current->lock()));
result->push(new MonitorInfo(current->obj(), current->lock(), false));
}
return result;
}

View File

@ -230,15 +230,18 @@ class MonitorInfo : public ResourceObj {
private:
oop _owner; // the object owning the monitor
BasicLock* _lock;
bool _eliminated;
public:
// Constructor
MonitorInfo(oop owner, BasicLock* lock) {
MonitorInfo(oop owner, BasicLock* lock, bool eliminated) {
_owner = owner;
_lock = lock;
_eliminated = eliminated;
}
// Accessors
oop owner() const { return _owner; }
BasicLock* lock() const { return _lock; }
bool eliminated() const { return _eliminated; }
};
class vframeStreamCommon : StackObj {

View File

@ -190,7 +190,7 @@ GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
// Casting away const
frame& fr = (frame&) _fr;
MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm),
fr.compiled_synchronized_native_monitor(nm));
fr.compiled_synchronized_native_monitor(nm), false);
monitors->push(info);
return monitors;
}
@ -202,7 +202,7 @@ GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
for (int index = 0; index < monitors->length(); index++) {
MonitorValue* mv = monitors->at(index);
StackValue *owner_sv = create_stack_value(mv->owner()); // it is an oop
result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock())));
result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()), mv->eliminated()));
}
return result;
}