--- a/hotspot/src/share/vm/opto/locknode.cpp Sat Jan 07 10:39:23 2012 -0800
+++ b/hotspot/src/share/vm/opto/locknode.cpp Sat Jan 07 13:26:43 2012 -0800
@@ -49,18 +49,22 @@
//-----------------------------hash--------------------------------------------
uint BoxLockNode::hash() const {
+ if (EliminateNestedLocks)
+ return NO_HASH; // Each locked region has own BoxLock node
return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
}
//------------------------------cmp--------------------------------------------
uint BoxLockNode::cmp( const Node &n ) const {
+ if (EliminateNestedLocks)
+ return (&n == this); // Always fail except on self
const BoxLockNode &bn = (const BoxLockNode &)n;
return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
}
-OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
+BoxLockNode* BoxLockNode::box_node(Node* box) {
// Chase down the BoxNode
- while (!box_node->is_BoxLock()) {
+ while (!box->is_BoxLock()) {
// if (box_node->is_SpillCopy()) {
// Node *m = box_node->in(1);
// if (m->is_Mach() && m->as_Mach()->ideal_Opcode() == Op_StoreP) {
@@ -68,10 +72,80 @@
// continue;
// }
// }
- assert(box_node->is_SpillCopy() || box_node->is_Phi(), "Bad spill of Lock.");
- box_node = box_node->in(1);
+ assert(box->is_SpillCopy() || box->is_Phi(), "Bad spill of Lock.");
+ // Only BoxLock nodes with the same stack slot are merged.
+ // So it is enough to trace one path to find the slot value.
+ box = box->in(1);
}
- return box_node->in_RegMask(0).find_first_elem();
+ return box->as_BoxLock();
+}
+
+OptoReg::Name BoxLockNode::reg(Node* box) {
+ return box_node(box)->in_RegMask(0).find_first_elem();
+}
+
+bool BoxLockNode::same_slot(Node* box1, Node* box2) {
+ return box_node(box1)->_slot == box_node(box2)->_slot;
+}
+
+// Is BoxLock node used for one simple lock region (same box and obj)?
+bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj) {
+ LockNode* lock = NULL;
+ bool has_one_lock = false;
+ for (uint i = 0; i < this->outcnt(); i++) {
+ Node* n = this->raw_out(i);
+ if (n->is_Phi())
+ return false; // Merged regions
+ if (n->is_AbstractLock()) {
+ AbstractLockNode* alock = n->as_AbstractLock();
+ // Check lock's box since box could be referenced by Lock's debug info.
+ if (alock->box_node() == this) {
+ if (alock->obj_node() == obj) {
+ if ((unique_lock != NULL) && alock->is_Lock()) {
+ if (lock == NULL) {
+ lock = alock->as_Lock();
+ has_one_lock = true;
+ } else if (lock != alock->as_Lock()) {
+ has_one_lock = false;
+ }
+ }
+ } else {
+ return false; // Different objects
+ }
+ }
+ }
+ }
+#ifdef ASSERT
+ // Verify that FastLock and Safepoint reference only this lock region.
+ for (uint i = 0; i < this->outcnt(); i++) {
+ Node* n = this->raw_out(i);
+ if (n->is_FastLock()) {
+ FastLockNode* flock = n->as_FastLock();
+ assert((flock->box_node() == this) && (flock->obj_node() == obj),"");
+ }
+ if (n->is_SafePoint() && n->as_SafePoint()->jvms()) {
+ SafePointNode* sfn = n->as_SafePoint();
+ JVMState* youngest_jvms = sfn->jvms();
+ int max_depth = youngest_jvms->depth();
+ for (int depth = 1; depth <= max_depth; depth++) {
+ JVMState* jvms = youngest_jvms->of_depth(depth);
+ int num_mon = jvms->nof_monitors();
+ // Loop over monitors
+ for (int idx = 0; idx < num_mon; idx++) {
+ Node* obj_node = sfn->monitor_obj(jvms, idx);
+ Node* box_node = sfn->monitor_box(jvms, idx);
+ if (box_node == this) {
+ assert(obj_node == obj,"");
+ }
+ }
+ }
+ }
+ }
+#endif
+ if (unique_lock != NULL && has_one_lock) {
+ *unique_lock = lock;
+ }
+ return true;
}
//=============================================================================