< prev index next >

src/share/vm/runtime/synchronizer.cpp

Print this page




   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/vmSymbols.hpp"

  27 #include "jfr/jfrEvents.hpp"

  28 #include "memory/resourceArea.hpp"
  29 #include "oops/markOop.hpp"
  30 #include "oops/oop.inline.hpp"
  31 #include "runtime/biasedLocking.hpp"
  32 #include "runtime/handles.inline.hpp"
  33 #include "runtime/interfaceSupport.hpp"
  34 #include "runtime/mutexLocker.hpp"
  35 #include "runtime/objectMonitor.hpp"
  36 #include "runtime/objectMonitor.inline.hpp"
  37 #include "runtime/osThread.hpp"
  38 #include "runtime/stubRoutines.hpp"
  39 #include "runtime/synchronizer.hpp"
  40 #include "runtime/thread.inline.hpp"
  41 #include "utilities/dtrace.hpp"
  42 #include "utilities/events.hpp"
  43 #include "utilities/preserveException.hpp"
  44 #ifdef TARGET_OS_FAMILY_linux
  45 # include "os_linux.inline.hpp"
  46 #endif
  47 #ifdef TARGET_OS_FAMILY_solaris


1162       guarantee (InUseTail != NULL && InUseList != NULL, "invariant");
1163     }
1164 
1165     Thread::muxAcquire (&ListLock, "omFlush") ;
1166     if (Tail != NULL) {
1167       Tail->FreeNext = gFreeList ;
1168       gFreeList = List ;
1169       MonitorFreeCount += Tally;
1170     }
1171 
1172     if (InUseTail != NULL) {
1173       InUseTail->FreeNext = gOmInUseList;
1174       gOmInUseList = InUseList;
1175       gOmInUseCount += InUseTally;
1176     }
1177 
1178     Thread::muxRelease (&ListLock) ;
1179     TEVENT (omFlush) ;
1180 }
1181 

1182 static void post_monitor_inflate_event(EventJavaMonitorInflate* event,
1183                                        const oop obj) {
1184   assert(event != NULL, "invariant");
1185   assert(event->should_commit(), "invariant");
1186   event->set_monitorClass(obj->klass());
1187   event->set_address((uintptr_t)(void*)obj);
1188   // XXX no such counters. implement?
1189 //  event->set_cause((u1)cause);
1190   event->commit();
1191 }

1192 
1193 // Fast path code shared by multiple functions
1194 ObjectMonitor* ObjectSynchronizer::inflate_helper(oop obj) {
1195   markOop mark = obj->mark();
1196   if (mark->has_monitor()) {
1197     assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid");
1198     assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header");
1199     return mark->monitor();
1200   }
1201   return ObjectSynchronizer::inflate(Thread::current(), obj);
1202 }
1203 
1204 
1205 // Note that we could encounter some performance loss through false-sharing as
1206 // multiple locks occupy the same $ line.  Padding might be appropriate.
1207 
1208 
1209 ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) {
1210   // Inflate mutates the heap ...
1211   // Relaxing assertion for bug 6320749.
1212   assert (Universe::verify_in_progress() ||
1213           !SafepointSynchronize::is_at_safepoint(), "invariant") ;
1214 

1215   EventJavaMonitorInflate event;

1216 
1217   for (;;) {
1218       const markOop mark = object->mark() ;
1219       assert (!mark->has_bias_pattern(), "invariant") ;
1220 
1221       // The mark can be in one of the following states:
1222       // *  Inflated     - just return
1223       // *  Stack-locked - coerce it to inflated
1224       // *  INFLATING    - busy wait for conversion to complete
1225       // *  Neutral      - aggressively inflate the object.
1226       // *  BIASED       - Illegal.  We should never see this
1227 
1228       // CASE: inflated
1229       if (mark->has_monitor()) {
1230           ObjectMonitor * inf = mark->monitor() ;
1231           assert (inf->header()->is_neutral(), "invariant");
1232           assert (inf->object() == object, "invariant") ;
1233           assert (ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid");
1234           return inf ;
1235       }


1327           m->set_object(object);
1328           // TODO-FIXME: assert BasicLock->dhw != 0.
1329 
1330           // Must preserve store ordering. The monitor state must
1331           // be stable at the time of publishing the monitor address.
1332           guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ;
1333           object->release_set_mark(markOopDesc::encode(m));
1334 
1335           // Hopefully the performance counters are allocated on distinct cache lines
1336           // to avoid false sharing on MP systems ...
1337           if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
1338           TEVENT(Inflate: overwrite stacklock) ;
1339           if (TraceMonitorInflation) {
1340             if (object->is_instance()) {
1341               ResourceMark rm;
1342               tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
1343                 (void *) object, (intptr_t) object->mark(),
1344                 object->klass()->external_name());
1345             }
1346           }

1347           if (event.should_commit()) {
1348             post_monitor_inflate_event(&event, object);
1349           }

1350           return m ;
1351       }
1352 
1353       // CASE: neutral
1354       // TODO-FIXME: for entry we currently inflate and then try to CAS _owner.
1355       // If we know we're inflating for entry it's better to inflate by swinging a
1356       // pre-locked objectMonitor pointer into the object header.   A successful
1357       // CAS inflates the object *and* confers ownership to the inflating thread.
1358       // In the current implementation we use a 2-step mechanism where we CAS()
1359       // to inflate and then CAS() again to try to swing _owner from NULL to Self.
1360       // An inflateTry() method that we could call from fast_enter() and slow_enter()
1361       // would be useful.
1362 
1363       assert (mark->is_neutral(), "invariant");
1364       ObjectMonitor * m = omAlloc (Self) ;
1365       // prepare m for installation - set monitor to initial state
1366       m->Recycle();
1367       m->set_header(mark);
1368       m->set_owner(NULL);
1369       m->set_object(object);


1380           omRelease (Self, m, true) ;
1381           m = NULL ;
1382           continue ;
1383           // interference - the markword changed - just retry.
1384           // The state-transitions are one-way, so there's no chance of
1385           // live-lock -- "Inflated" is an absorbing state.
1386       }
1387 
1388       // Hopefully the performance counters are allocated on distinct
1389       // cache lines to avoid false sharing on MP systems ...
1390       if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
1391       TEVENT(Inflate: overwrite neutral) ;
1392       if (TraceMonitorInflation) {
1393         if (object->is_instance()) {
1394           ResourceMark rm;
1395           tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
1396             (void *) object, (intptr_t) object->mark(),
1397             object->klass()->external_name());
1398         }
1399       }

1400       if (event.should_commit()) {
1401         post_monitor_inflate_event(&event, object);
1402       }

1403       return m ;
1404   }
1405 }
1406 
1407 // Note that we could encounter some performance loss through false-sharing as
1408 // multiple locks occupy the same $ line.  Padding might be appropriate.
1409 
1410 
1411 // Deflate_idle_monitors() is called at all safepoints, immediately
1412 // after all mutators are stopped, but before any objects have moved.
1413 // It traverses the list of known monitors, deflating where possible.
1414 // The scavenged monitor are returned to the monitor free list.
1415 //
1416 // Beware that we scavenge at *every* stop-the-world point.
1417 // Having a large number of monitors in-circulation negatively
1418 // impacts the performance of some applications (e.g., PointBase).
1419 // Broadly, we want to minimize the # of monitors in circulation.
1420 //
1421 // We have added a flag, MonitorInUseLists, which creates a list
1422 // of active monitors for each thread. deflate_idle_monitors()




   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/vmSymbols.hpp"
  27 #if INCLUDE_JFR
  28 #include "jfr/jfrEvents.hpp"
  29 #endif
  30 #include "memory/resourceArea.hpp"
  31 #include "oops/markOop.hpp"
  32 #include "oops/oop.inline.hpp"
  33 #include "runtime/biasedLocking.hpp"
  34 #include "runtime/handles.inline.hpp"
  35 #include "runtime/interfaceSupport.hpp"
  36 #include "runtime/mutexLocker.hpp"
  37 #include "runtime/objectMonitor.hpp"
  38 #include "runtime/objectMonitor.inline.hpp"
  39 #include "runtime/osThread.hpp"
  40 #include "runtime/stubRoutines.hpp"
  41 #include "runtime/synchronizer.hpp"
  42 #include "runtime/thread.inline.hpp"
  43 #include "utilities/dtrace.hpp"
  44 #include "utilities/events.hpp"
  45 #include "utilities/preserveException.hpp"
  46 #ifdef TARGET_OS_FAMILY_linux
  47 # include "os_linux.inline.hpp"
  48 #endif
  49 #ifdef TARGET_OS_FAMILY_solaris


1164       guarantee (InUseTail != NULL && InUseList != NULL, "invariant");
1165     }
1166 
1167     Thread::muxAcquire (&ListLock, "omFlush") ;
1168     if (Tail != NULL) {
1169       Tail->FreeNext = gFreeList ;
1170       gFreeList = List ;
1171       MonitorFreeCount += Tally;
1172     }
1173 
1174     if (InUseTail != NULL) {
1175       InUseTail->FreeNext = gOmInUseList;
1176       gOmInUseList = InUseList;
1177       gOmInUseCount += InUseTally;
1178     }
1179 
1180     Thread::muxRelease (&ListLock) ;
1181     TEVENT (omFlush) ;
1182 }
1183 
1184 #if INCLUDE_JFR
1185 static void post_monitor_inflate_event(EventJavaMonitorInflate* event,
1186                                        const oop obj) {
1187   assert(event != NULL, "invariant");
1188   assert(event->should_commit(), "invariant");
1189   event->set_monitorClass(obj->klass());
1190   event->set_address((uintptr_t)(void*)obj);
1191   // XXX no such counters. implement?
1192 //  event->set_cause((u1)cause);
1193   event->commit();
1194 }
1195 #endif
1196 
1197 // Fast path code shared by multiple functions
1198 ObjectMonitor* ObjectSynchronizer::inflate_helper(oop obj) {
1199   markOop mark = obj->mark();
1200   if (mark->has_monitor()) {
1201     assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid");
1202     assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header");
1203     return mark->monitor();
1204   }
1205   return ObjectSynchronizer::inflate(Thread::current(), obj);
1206 }
1207 
1208 
1209 // Note that we could encounter some performance loss through false-sharing as
1210 // multiple locks occupy the same $ line.  Padding might be appropriate.
1211 
1212 
1213 ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) {
1214   // Inflate mutates the heap ...
1215   // Relaxing assertion for bug 6320749.
1216   assert (Universe::verify_in_progress() ||
1217           !SafepointSynchronize::is_at_safepoint(), "invariant") ;
1218 
1219 #if INCLUDE_JFR
1220   EventJavaMonitorInflate event;
1221 #endif
1222 
1223   for (;;) {
1224       const markOop mark = object->mark() ;
1225       assert (!mark->has_bias_pattern(), "invariant") ;
1226 
1227       // The mark can be in one of the following states:
1228       // *  Inflated     - just return
1229       // *  Stack-locked - coerce it to inflated
1230       // *  INFLATING    - busy wait for conversion to complete
1231       // *  Neutral      - aggressively inflate the object.
1232       // *  BIASED       - Illegal.  We should never see this
1233 
1234       // CASE: inflated
1235       if (mark->has_monitor()) {
1236           ObjectMonitor * inf = mark->monitor() ;
1237           assert (inf->header()->is_neutral(), "invariant");
1238           assert (inf->object() == object, "invariant") ;
1239           assert (ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid");
1240           return inf ;
1241       }


1333           m->set_object(object);
1334           // TODO-FIXME: assert BasicLock->dhw != 0.
1335 
1336           // Must preserve store ordering. The monitor state must
1337           // be stable at the time of publishing the monitor address.
1338           guarantee (object->mark() == markOopDesc::INFLATING(), "invariant") ;
1339           object->release_set_mark(markOopDesc::encode(m));
1340 
1341           // Hopefully the performance counters are allocated on distinct cache lines
1342           // to avoid false sharing on MP systems ...
1343           if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
1344           TEVENT(Inflate: overwrite stacklock) ;
1345           if (TraceMonitorInflation) {
1346             if (object->is_instance()) {
1347               ResourceMark rm;
1348               tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
1349                 (void *) object, (intptr_t) object->mark(),
1350                 object->klass()->external_name());
1351             }
1352           }
1353 #if INCLUDE_JFR
1354           if (event.should_commit()) {
1355             post_monitor_inflate_event(&event, object);
1356           }
1357 #endif
1358           return m ;
1359       }
1360 
1361       // CASE: neutral
1362       // TODO-FIXME: for entry we currently inflate and then try to CAS _owner.
1363       // If we know we're inflating for entry it's better to inflate by swinging a
1364       // pre-locked objectMonitor pointer into the object header.   A successful
1365       // CAS inflates the object *and* confers ownership to the inflating thread.
1366       // In the current implementation we use a 2-step mechanism where we CAS()
1367       // to inflate and then CAS() again to try to swing _owner from NULL to Self.
1368       // An inflateTry() method that we could call from fast_enter() and slow_enter()
1369       // would be useful.
1370 
1371       assert (mark->is_neutral(), "invariant");
1372       ObjectMonitor * m = omAlloc (Self) ;
1373       // prepare m for installation - set monitor to initial state
1374       m->Recycle();
1375       m->set_header(mark);
1376       m->set_owner(NULL);
1377       m->set_object(object);


1388           omRelease (Self, m, true) ;
1389           m = NULL ;
1390           continue ;
1391           // interference - the markword changed - just retry.
1392           // The state-transitions are one-way, so there's no chance of
1393           // live-lock -- "Inflated" is an absorbing state.
1394       }
1395 
1396       // Hopefully the performance counters are allocated on distinct
1397       // cache lines to avoid false sharing on MP systems ...
1398       if (ObjectMonitor::_sync_Inflations != NULL) ObjectMonitor::_sync_Inflations->inc() ;
1399       TEVENT(Inflate: overwrite neutral) ;
1400       if (TraceMonitorInflation) {
1401         if (object->is_instance()) {
1402           ResourceMark rm;
1403           tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
1404             (void *) object, (intptr_t) object->mark(),
1405             object->klass()->external_name());
1406         }
1407       }
1408 #if INCLUDE_JFR
1409       if (event.should_commit()) {
1410         post_monitor_inflate_event(&event, object);
1411       }
1412 #endif
1413       return m ;
1414   }
1415 }
1416 
1417 // Note that we could encounter some performance loss through false-sharing as
1418 // multiple locks occupy the same $ line.  Padding might be appropriate.
1419 
1420 
1421 // Deflate_idle_monitors() is called at all safepoints, immediately
1422 // after all mutators are stopped, but before any objects have moved.
1423 // It traverses the list of known monitors, deflating where possible.
1424 // The scavenged monitor are returned to the monitor free list.
1425 //
1426 // Beware that we scavenge at *every* stop-the-world point.
1427 // Having a large number of monitors in-circulation negatively
1428 // impacts the performance of some applications (e.g., PointBase).
1429 // Broadly, we want to minimize the # of monitors in circulation.
1430 //
1431 // We have added a flag, MonitorInUseLists, which creates a list
1432 // of active monitors for each thread. deflate_idle_monitors()


< prev index next >