378 // Print stack
379 for (i = 0; i < (uint)stk_size(); i++) {
380 if ((uint)(_stkoff + i) >= mcall->len())
381 st->print(" oob ");
382 else
383 format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs );
384 }
385 for (i = 0; (int)i < nof_monitors(); i++) {
386 Node *box = mcall->monitor_box(this, i);
387 Node *obj = mcall->monitor_obj(this, i);
388 if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
389 while( !box->is_BoxLock() ) box = box->in(1);
390 format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
391 } else {
392 OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
393 st->print(" MON-BOX%d=%s+%d",
394 i,
395 OptoReg::regname(OptoReg::c_frame_pointer),
396 regalloc->reg2offset(box_reg));
397 }
398 format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
399 }
400
401 for (i = 0; i < (uint)scobjs.length(); i++) {
402 // Scalar replaced objects.
403 st->print_cr("");
404 st->print(" # ScObj" INT32_FORMAT " ", i);
405 SafePointScalarObjectNode* spobj = scobjs.at(i);
406 ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass();
407 assert(cik->is_instance_klass() ||
408 cik->is_array_klass(), "Not supported allocation.");
409 ciInstanceKlass *iklass = NULL;
410 if (cik->is_instance_klass()) {
411 cik->print_name_on(st);
412 iklass = cik->as_instance_klass();
413 } else if (cik->is_type_array_klass()) {
414 cik->as_array_klass()->base_element_type()->print_name_on(st);
415 st->print("[%d]=", spobj->n_fields());
416 } else if (cik->is_obj_array_klass()) {
417 ciType* cie = cik->as_array_klass()->base_element_type();
418 int ndim = 1;
419 while (cie->is_obj_array_klass()) {
891 Node* top = Compile::current()->top();
892 for (uint i = 0; i < grow_by; i++) {
893 ins_req(monoff, top);
894 }
895 jvms->set_monoff(monoff + grow_by);
896 jvms->set_scloff(scloff + grow_by);
897 jvms->set_endoff(endoff + grow_by);
898 }
899
900 void SafePointNode::push_monitor(const FastLockNode *lock) {
901 // Add a LockNode, which points to both the original BoxLockNode (the
902 // stack space for the monitor) and the Object being locked.
903 const int MonitorEdges = 2;
904 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
905 assert(req() == jvms()->endoff(), "correct sizing");
906 int nextmon = jvms()->scloff();
907 if (GenerateSynchronizationCode) {
908 add_req(lock->box_node());
909 add_req(lock->obj_node());
910 } else {
911 add_req(NULL);
912 add_req(NULL);
913 }
914 jvms()->set_scloff(nextmon+MonitorEdges);
915 jvms()->set_endoff(req());
916 }
917
918 void SafePointNode::pop_monitor() {
919 // Delete last monitor from debug info
920 debug_only(int num_before_pop = jvms()->nof_monitors());
921 const int MonitorEdges = (1<<JVMState::logMonitorEdges);
922 int scloff = jvms()->scloff();
923 int endoff = jvms()->endoff();
924 int new_scloff = scloff - MonitorEdges;
925 int new_endoff = endoff - MonitorEdges;
926 jvms()->set_scloff(new_scloff);
927 jvms()->set_endoff(new_endoff);
928 while (scloff > new_scloff) del_req(--scloff);
929 assert(jvms()->nof_monitors() == num_before_pop-1, "");
930 }
931
932 Node *SafePointNode::peek_monitor_box() const {
1365 _counter->set_tag(NamedCounter::EliminatedLockCounter);
1366 }
1367 #endif
1368 }
1369
1370 //=============================================================================
1371 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1372
1373 // perform any generic optimizations first (returns 'this' or NULL)
1374 Node *result = SafePointNode::Ideal(phase, can_reshape);
1375
1376 // Now see if we can optimize away this lock. We don't actually
1377 // remove the locking here, we simply set the _eliminate flag which
1378 // prevents macro expansion from expanding the lock. Since we don't
1379 // modify the graph, the value returned from this function is the
1380 // one computed above.
1381 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
1382 //
1383 // If we are locking an unescaped object, the lock/unlock is unnecessary
1384 //
1385 ConnectionGraph *cgr = Compile::current()->congraph();
1386 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
1387 if (cgr != NULL)
1388 es = cgr->escape_state(obj_node(), phase);
1389 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
1390 // Mark it eliminated to update any counters
1391 this->set_eliminated();
1392 return result;
1393 }
1394
1395 //
1396 // Try lock coarsening
1397 //
1398 PhaseIterGVN* iter = phase->is_IterGVN();
1399 if (iter != NULL) {
1400
1401 GrowableArray<AbstractLockNode*> lock_ops;
1402
1403 Node *ctrl = next_control(in(0));
1404
1405 // now search back for a matching Unlock
1433 AbstractLockNode* lock = lock_ops.at(i);
1434 if (lock->Opcode() == Op_Lock)
1435 locks++;
1436 else
1437 unlocks++;
1438 if (Verbose) {
1439 lock->dump(1);
1440 }
1441 }
1442 tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks);
1443 }
1444 #endif
1445
1446 // for each of the identified locks, mark them
1447 // as eliminatable
1448 for (int i = 0; i < lock_ops.length(); i++) {
1449 AbstractLockNode* lock = lock_ops.at(i);
1450
1451 // Mark it eliminated to update any counters
1452 lock->set_eliminated();
1453 }
1454 } else if (result != NULL && ctrl->is_Region() &&
1455 iter->_worklist.member(ctrl)) {
1456 // We weren't able to find any opportunities but the region this
1457 // lock is control dependent on hasn't been processed yet so put
1458 // this lock back on the worklist so we can check again once any
1459 // region simplification has occurred.
1460 iter->_worklist.push(this);
1461 }
1462 }
1463 }
1464
1465 return result;
1466 }
1467
1468 //=============================================================================
1469 uint UnlockNode::size_of() const { return sizeof(*this); }
1470
1471 //=============================================================================
1472 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1473
1474 // perform any generic optimizations first (returns 'this' or NULL)
1475 Node * result = SafePointNode::Ideal(phase, can_reshape);
1476
1477 // Now see if we can optimize away this unlock. We don't actually
1478 // remove the unlocking here, we simply set the _eliminate flag which
1479 // prevents macro expansion from expanding the unlock. Since we don't
1480 // modify the graph, the value returned from this function is the
1481 // one computed above.
1482 // Escape state is defined after Parse phase.
1483 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
1484 //
1485 // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
1486 //
1487 ConnectionGraph *cgr = Compile::current()->congraph();
1488 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
1489 if (cgr != NULL)
1490 es = cgr->escape_state(obj_node(), phase);
1491 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
1492 // Mark it eliminated to update any counters
1493 this->set_eliminated();
1494 }
1495 }
1496 return result;
1497 }
|
378 // Print stack
379 for (i = 0; i < (uint)stk_size(); i++) {
380 if ((uint)(_stkoff + i) >= mcall->len())
381 st->print(" oob ");
382 else
383 format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs );
384 }
385 for (i = 0; (int)i < nof_monitors(); i++) {
386 Node *box = mcall->monitor_box(this, i);
387 Node *obj = mcall->monitor_obj(this, i);
388 if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
389 while( !box->is_BoxLock() ) box = box->in(1);
390 format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
391 } else {
392 OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
393 st->print(" MON-BOX%d=%s+%d",
394 i,
395 OptoReg::regname(OptoReg::c_frame_pointer),
396 regalloc->reg2offset(box_reg));
397 }
398 const char* obj_msg = "MON-OBJ[";
399 if (EliminateLocks) {
400 while( !box->is_BoxLock() ) box = box->in(1);
401 if (box->as_BoxLock()->is_eliminated())
402 obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
403 }
404 format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
405 }
406
407 for (i = 0; i < (uint)scobjs.length(); i++) {
408 // Scalar replaced objects.
409 st->print_cr("");
410 st->print(" # ScObj" INT32_FORMAT " ", i);
411 SafePointScalarObjectNode* spobj = scobjs.at(i);
412 ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass();
413 assert(cik->is_instance_klass() ||
414 cik->is_array_klass(), "Not supported allocation.");
415 ciInstanceKlass *iklass = NULL;
416 if (cik->is_instance_klass()) {
417 cik->print_name_on(st);
418 iklass = cik->as_instance_klass();
419 } else if (cik->is_type_array_klass()) {
420 cik->as_array_klass()->base_element_type()->print_name_on(st);
421 st->print("[%d]=", spobj->n_fields());
422 } else if (cik->is_obj_array_klass()) {
423 ciType* cie = cik->as_array_klass()->base_element_type();
424 int ndim = 1;
425 while (cie->is_obj_array_klass()) {
897 Node* top = Compile::current()->top();
898 for (uint i = 0; i < grow_by; i++) {
899 ins_req(monoff, top);
900 }
901 jvms->set_monoff(monoff + grow_by);
902 jvms->set_scloff(scloff + grow_by);
903 jvms->set_endoff(endoff + grow_by);
904 }
905
906 void SafePointNode::push_monitor(const FastLockNode *lock) {
907 // Add a LockNode, which points to both the original BoxLockNode (the
908 // stack space for the monitor) and the Object being locked.
909 const int MonitorEdges = 2;
910 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges");
911 assert(req() == jvms()->endoff(), "correct sizing");
912 int nextmon = jvms()->scloff();
913 if (GenerateSynchronizationCode) {
914 add_req(lock->box_node());
915 add_req(lock->obj_node());
916 } else {
917 Node* top = Compile::current()->top();
918 add_req(top);
919 add_req(top);
920 }
921 jvms()->set_scloff(nextmon+MonitorEdges);
922 jvms()->set_endoff(req());
923 }
924
925 void SafePointNode::pop_monitor() {
926 // Delete last monitor from debug info
927 debug_only(int num_before_pop = jvms()->nof_monitors());
928 const int MonitorEdges = (1<<JVMState::logMonitorEdges);
929 int scloff = jvms()->scloff();
930 int endoff = jvms()->endoff();
931 int new_scloff = scloff - MonitorEdges;
932 int new_endoff = endoff - MonitorEdges;
933 jvms()->set_scloff(new_scloff);
934 jvms()->set_endoff(new_endoff);
935 while (scloff > new_scloff) del_req(--scloff);
936 assert(jvms()->nof_monitors() == num_before_pop-1, "");
937 }
938
939 Node *SafePointNode::peek_monitor_box() const {
1372 _counter->set_tag(NamedCounter::EliminatedLockCounter);
1373 }
1374 #endif
1375 }
1376
1377 //=============================================================================
1378 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1379
1380 // perform any generic optimizations first (returns 'this' or NULL)
1381 Node *result = SafePointNode::Ideal(phase, can_reshape);
1382
1383 // Now see if we can optimize away this lock. We don't actually
1384 // remove the locking here, we simply set the _eliminate flag which
1385 // prevents macro expansion from expanding the lock. Since we don't
1386 // modify the graph, the value returned from this function is the
1387 // one computed above.
1388 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
1389 //
1390 // If we are locking an unescaped object, the lock/unlock is unnecessary
1391 //
1392 ConnectionGraph *cgr = phase->C->congraph();
1393 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
1394 if (cgr != NULL)
1395 es = cgr->escape_state(obj_node(), phase);
1396 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
1397 // Mark it eliminated to update any counters
1398 this->set_eliminated();
1399 return result;
1400 }
1401
1402 //
1403 // Try lock coarsening
1404 //
1405 PhaseIterGVN* iter = phase->is_IterGVN();
1406 if (iter != NULL) {
1407
1408 GrowableArray<AbstractLockNode*> lock_ops;
1409
1410 Node *ctrl = next_control(in(0));
1411
1412 // now search back for a matching Unlock
1440 AbstractLockNode* lock = lock_ops.at(i);
1441 if (lock->Opcode() == Op_Lock)
1442 locks++;
1443 else
1444 unlocks++;
1445 if (Verbose) {
1446 lock->dump(1);
1447 }
1448 }
1449 tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks);
1450 }
1451 #endif
1452
1453 // for each of the identified locks, mark them
1454 // as eliminatable
1455 for (int i = 0; i < lock_ops.length(); i++) {
1456 AbstractLockNode* lock = lock_ops.at(i);
1457
1458 // Mark it eliminated to update any counters
1459 lock->set_eliminated();
1460 lock->set_coarsened();
1461 }
1462 } else if (result != NULL && ctrl->is_Region() &&
1463 iter->_worklist.member(ctrl)) {
1464 // We weren't able to find any opportunities but the region this
1465 // lock is control dependent on hasn't been processed yet so put
1466 // this lock back on the worklist so we can check again once any
1467 // region simplification has occurred.
1468 iter->_worklist.push(this);
1469 }
1470 }
1471 }
1472
1473 return result;
1474 }
1475
1476 //=============================================================================
1477 uint UnlockNode::size_of() const { return sizeof(*this); }
1478
1479 //=============================================================================
1480 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1481
1482 // perform any generic optimizations first (returns 'this' or NULL)
1483 Node * result = SafePointNode::Ideal(phase, can_reshape);
1484
1485 // Now see if we can optimize away this unlock. We don't actually
1486 // remove the unlocking here, we simply set the _eliminate flag which
1487 // prevents macro expansion from expanding the unlock. Since we don't
1488 // modify the graph, the value returned from this function is the
1489 // one computed above.
1490 // Escape state is defined after Parse phase.
1491 if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) {
1492 //
1493 // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
1494 //
1495 ConnectionGraph *cgr = phase->C->congraph();
1496 PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
1497 if (cgr != NULL)
1498 es = cgr->escape_state(obj_node(), phase);
1499 if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
1500 // Mark it eliminated to update any counters
1501 this->set_eliminated();
1502 }
1503 }
1504 return result;
1505 }
|