aoqi@0: /* aoqi@0: * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #ifndef SHARE_VM_RUNTIME_RTMLOCKING_HPP aoqi@0: #define SHARE_VM_RUNTIME_RTMLOCKING_HPP aoqi@0: aoqi@0: // Generate RTM (Restricted Transactional Memory) locking code for all inflated aoqi@0: // locks when "UseRTMLocking" option is on with normal locking mechanism as fall back aoqi@0: // handler. aoqi@0: // aoqi@0: // On abort/lock busy the lock will be retried a fixed number of times under RTM aoqi@0: // as specified by "RTMRetryCount" option. The locks which abort too often aoqi@0: // can be auto tuned or manually tuned. aoqi@0: // aoqi@0: // Auto-tuning can be done on an option like UseRTMDeopt and it will need abort aoqi@0: // ratio calculation for each lock. The abort ratio will be calculated after aoqi@0: // "RTMAbortThreshold" number of aborts is reached. The formulas are: aoqi@0: // aoqi@0: // Aborted transactions = abort_count * 100 aoqi@0: // All transactions = total_count * RTMTotalCountIncrRate aoqi@0: // aoqi@0: // Aborted transactions >= All transactions * RTMAbortRatio aoqi@0: // aoqi@0: // If "UseRTMDeopt" is on and the aborts ratio reaches "RTMAbortRatio" aoqi@0: // the method containing the lock will be deoptimized and recompiled with aoqi@0: // all locks as normal locks. If the abort ratio continues to remain low after aoqi@0: // "RTMLockingThreshold" locks are attempted, then the method will be deoptimized aoqi@0: // and recompiled with all locks as RTM locks without abort ratio calculation code. aoqi@0: // The abort ratio calculation can be delayed by specifying flag aoqi@0: // -XX:RTMLockingCalculationDelay in millisecond. aoqi@0: // aoqi@0: // For manual tuning the abort statistics for each lock needs to be provided aoqi@0: // to the user on some JVM option like "PrintPreciseRTMLockingStatistics". aoqi@0: // Based on the abort statistics users can create a .hotspot_compiler file aoqi@0: // or use -XX:CompileCommand=option,class::method,NoRTMLockEliding aoqi@0: // to specify for which methods to disable RTM locking. aoqi@0: // aoqi@0: // When UseRTMForStackLocks option is enabled along with UseRTMLocking option, aoqi@0: // the RTM locking code is generated for stack locks too. aoqi@0: // The retries, auto-tuning support and rtm locking statistics are all aoqi@0: // supported for stack locks just like inflated locks. aoqi@0: aoqi@0: // RTM locking counters aoqi@0: class RTMLockingCounters VALUE_OBJ_CLASS_SPEC { aoqi@0: private: aoqi@0: uintx _total_count; // Total RTM locks count aoqi@0: uintx _abort_count; // Total aborts count aoqi@0: aoqi@0: public: aoqi@0: enum { ABORT_STATUS_LIMIT = 6 }; aoqi@0: // Counters per RTM Abort Status. Incremented with +PrintPreciseRTMLockingStatistics aoqi@0: // RTM uses the EAX register to communicate abort status to software. aoqi@0: // Following an RTM abort the EAX register has the following definition. aoqi@0: // aoqi@0: // EAX register bit position Meaning aoqi@0: // 0 Set if abort caused by XABORT instruction. aoqi@0: // 1 If set, the transaction may succeed on a retry. This bit is always clear if bit 0 is set. aoqi@0: // 2 Set if another logical processor conflicted with a memory address that was part of the transaction that aborted. aoqi@0: // 3 Set if an internal buffer overflowed. aoqi@0: // 4 Set if a debug breakpoint was hit. aoqi@0: // 5 Set if an abort occurred during execution of a nested transaction. aoqi@0: private: aoqi@0: uintx _abortX_count[ABORT_STATUS_LIMIT]; aoqi@0: aoqi@0: public: aoqi@0: static uintx _calculation_flag; aoqi@0: static uintx* rtm_calculation_flag_addr() { return &_calculation_flag; } aoqi@0: aoqi@0: static void init(); aoqi@0: aoqi@0: RTMLockingCounters() : _total_count(0), _abort_count(0) { aoqi@0: for (int i = 0; i < ABORT_STATUS_LIMIT; i++) { aoqi@0: _abortX_count[i] = 0; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: uintx* total_count_addr() { return &_total_count; } aoqi@0: uintx* abort_count_addr() { return &_abort_count; } aoqi@0: uintx* abortX_count_addr() { return &_abortX_count[0]; } aoqi@0: aoqi@0: static int total_count_offset() { return (int)offset_of(RTMLockingCounters, _total_count); } aoqi@0: static int abort_count_offset() { return (int)offset_of(RTMLockingCounters, _abort_count); } aoqi@0: static int abortX_count_offset() { return (int)offset_of(RTMLockingCounters, _abortX_count[0]); } aoqi@0: aoqi@0: aoqi@0: bool nonzero() { return (_abort_count + _total_count) > 0; } aoqi@0: aoqi@0: void print_on(outputStream* st); aoqi@0: void print() { print_on(tty); } aoqi@0: }; aoqi@0: aoqi@0: #endif // SHARE_VM_RUNTIME_RTMLOCKING_HPP