src/cpu/sparc/vm/vm_version_sparc.cpp

Fri, 26 Aug 2011 08:52:22 -0700

author
kvn
date
Fri, 26 Aug 2011 08:52:22 -0700
changeset 3092
baf763f388e6
parent 3052
1af104d6cf99
child 3103
2f9b79ddb05c
permissions
-rw-r--r--

7059037: Use BIS for zeroing on T4
Summary: Use BIS for zeroing new allocated big (2Kb and more) objects and arrays.
Reviewed-by: never, twisti, ysr

duke@435 1 /*
kvn@2269 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "assembler_sparc.inline.hpp"
stefank@2314 27 #include "memory/resourceArea.hpp"
stefank@2314 28 #include "runtime/java.hpp"
stefank@2314 29 #include "runtime/stubCodeGenerator.hpp"
stefank@2314 30 #include "vm_version_sparc.hpp"
stefank@2314 31 #ifdef TARGET_OS_FAMILY_linux
stefank@2314 32 # include "os_linux.inline.hpp"
stefank@2314 33 #endif
stefank@2314 34 #ifdef TARGET_OS_FAMILY_solaris
stefank@2314 35 # include "os_solaris.inline.hpp"
stefank@2314 36 #endif
duke@435 37
duke@435 38 int VM_Version::_features = VM_Version::unknown_m;
duke@435 39 const char* VM_Version::_features_str = "";
duke@435 40
duke@435 41 void VM_Version::initialize() {
duke@435 42 _features = determine_features();
duke@435 43 PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
duke@435 44 PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes();
duke@435 45 PrefetchFieldsAhead = prefetch_fields_ahead();
duke@435 46
kvn@3052 47 assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 1, "invalid value");
kvn@3052 48 if( AllocatePrefetchInstr < 0 ) AllocatePrefetchInstr = 0;
kvn@3052 49 if( AllocatePrefetchInstr > 1 ) AllocatePrefetchInstr = 0;
kvn@3052 50
duke@435 51 // Allocation prefetch settings
kvn@3052 52 intx cache_line_size = prefetch_data_size();
duke@435 53 if( cache_line_size > AllocatePrefetchStepSize )
duke@435 54 AllocatePrefetchStepSize = cache_line_size;
kvn@3052 55
kvn@3052 56 assert(AllocatePrefetchLines > 0, "invalid value");
kvn@3052 57 if( AllocatePrefetchLines < 1 ) // set valid value in product VM
kvn@3052 58 AllocatePrefetchLines = 3;
kvn@3052 59 assert(AllocateInstancePrefetchLines > 0, "invalid value");
kvn@3052 60 if( AllocateInstancePrefetchLines < 1 ) // set valid value in product VM
kvn@3052 61 AllocateInstancePrefetchLines = 1;
duke@435 62
duke@435 63 AllocatePrefetchDistance = allocate_prefetch_distance();
duke@435 64 AllocatePrefetchStyle = allocate_prefetch_style();
duke@435 65
kvn@3052 66 assert((AllocatePrefetchDistance % AllocatePrefetchStepSize) == 0 &&
kvn@3052 67 (AllocatePrefetchDistance > 0), "invalid value");
kvn@3052 68 if ((AllocatePrefetchDistance % AllocatePrefetchStepSize) != 0 ||
kvn@3052 69 (AllocatePrefetchDistance <= 0)) {
kvn@3052 70 AllocatePrefetchDistance = AllocatePrefetchStepSize;
kvn@3052 71 }
duke@435 72
kvn@3037 73 if (AllocatePrefetchStyle == 3 && !has_blk_init()) {
kvn@3037 74 warning("BIS instructions are not available on this CPU");
kvn@3037 75 FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
kvn@3037 76 }
kvn@3037 77
duke@435 78 UseSSE = 0; // Only on x86 and x64
duke@435 79
kvn@3052 80 _supports_cx8 = has_v9();
duke@435 81
kvn@2403 82 if (is_niagara()) {
duke@435 83 // Indirect branch is the same cost as direct
duke@435 84 if (FLAG_IS_DEFAULT(UseInlineCaches)) {
kvn@1110 85 FLAG_SET_DEFAULT(UseInlineCaches, false);
duke@435 86 }
kvn@2403 87 // Align loops on a single instruction boundary.
kvn@2403 88 if (FLAG_IS_DEFAULT(OptoLoopAlignment)) {
kvn@2403 89 FLAG_SET_DEFAULT(OptoLoopAlignment, 4);
kvn@2403 90 }
kvn@2403 91 // When using CMS, we cannot use memset() in BOT updates because
kvn@2403 92 // the sun4v/CMT version in libc_psr uses BIS which exposes
kvn@2403 93 // "phantom zeros" to concurrent readers. See 6948537.
kvn@2403 94 if (FLAG_IS_DEFAULT(UseMemSetInBOT) && UseConcMarkSweepGC) {
kvn@2403 95 FLAG_SET_DEFAULT(UseMemSetInBOT, false);
kvn@2403 96 }
coleenp@548 97 #ifdef _LP64
kvn@1077 98 // 32-bit oops don't make sense for the 64-bit VM on sparc
kvn@1077 99 // since the 32-bit VM has the same registers and smaller objects.
kvn@1077 100 Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
coleenp@548 101 #endif // _LP64
duke@435 102 #ifdef COMPILER2
duke@435 103 // Indirect branch is the same cost as direct
duke@435 104 if (FLAG_IS_DEFAULT(UseJumpTables)) {
kvn@1110 105 FLAG_SET_DEFAULT(UseJumpTables, true);
duke@435 106 }
duke@435 107 // Single-issue, so entry and loop tops are
duke@435 108 // aligned on a single instruction boundary
duke@435 109 if (FLAG_IS_DEFAULT(InteriorEntryAlignment)) {
kvn@1110 110 FLAG_SET_DEFAULT(InteriorEntryAlignment, 4);
duke@435 111 }
kvn@2403 112 if (is_niagara_plus()) {
kvn@3052 113 if (has_blk_init() && UseTLAB &&
kvn@3052 114 FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
kvn@3052 115 // Use BIS instruction for TLAB allocation prefetch.
kvn@3052 116 FLAG_SET_ERGO(intx, AllocatePrefetchInstr, 1);
kvn@3052 117 if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
kvn@3052 118 FLAG_SET_ERGO(intx, AllocatePrefetchStyle, 3);
kvn@3052 119 }
kvn@1802 120 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
kvn@3052 121 // Use smaller prefetch distance with BIS
kvn@1802 122 FLAG_SET_DEFAULT(AllocatePrefetchDistance, 64);
kvn@1802 123 }
kvn@1802 124 }
kvn@3052 125 if (is_T4()) {
kvn@3052 126 // Double number of prefetched cache lines on T4
kvn@3052 127 // since L2 cache line size is smaller (32 bytes).
kvn@3052 128 if (FLAG_IS_DEFAULT(AllocatePrefetchLines)) {
kvn@3052 129 FLAG_SET_ERGO(intx, AllocatePrefetchLines, AllocatePrefetchLines*2);
kvn@3052 130 }
kvn@3052 131 if (FLAG_IS_DEFAULT(AllocateInstancePrefetchLines)) {
kvn@3052 132 FLAG_SET_ERGO(intx, AllocateInstancePrefetchLines, AllocateInstancePrefetchLines*2);
kvn@3052 133 }
kvn@3052 134 }
kvn@1802 135 if (AllocatePrefetchStyle != 3 && FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
kvn@1802 136 // Use different prefetch distance without BIS
kvn@1802 137 FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
kvn@1802 138 }
kvn@3052 139 if (AllocatePrefetchInstr == 1) {
kvn@3052 140 // Need a space at the end of TLAB for BIS since it
kvn@3052 141 // will fault when accessing memory outside of heap.
kvn@3052 142
kvn@3052 143 // +1 for rounding up to next cache line, +1 to be safe
kvn@3052 144 int lines = AllocatePrefetchLines + 2;
kvn@3052 145 int step_size = AllocatePrefetchStepSize;
kvn@3052 146 int distance = AllocatePrefetchDistance;
kvn@3052 147 _reserve_for_allocation_prefetch = (distance + step_size*lines)/(int)HeapWordSize;
kvn@3052 148 }
duke@435 149 }
duke@435 150 #endif
duke@435 151 }
duke@435 152
twisti@1078 153 // Use hardware population count instruction if available.
twisti@1078 154 if (has_hardware_popc()) {
twisti@1078 155 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
kvn@1110 156 FLAG_SET_DEFAULT(UsePopCountInstruction, true);
twisti@1078 157 }
kvn@3037 158 } else if (UsePopCountInstruction) {
kvn@3037 159 warning("POPC instruction is not available on this CPU");
kvn@3037 160 FLAG_SET_DEFAULT(UsePopCountInstruction, false);
kvn@3037 161 }
kvn@3037 162
kvn@3037 163 // T4 and newer Sparc cpus have new compare and branch instruction.
kvn@3037 164 if (has_cbcond()) {
kvn@3037 165 if (FLAG_IS_DEFAULT(UseCBCond)) {
kvn@3037 166 FLAG_SET_DEFAULT(UseCBCond, true);
kvn@3037 167 }
kvn@3037 168 } else if (UseCBCond) {
kvn@3037 169 warning("CBCOND instruction is not available on this CPU");
kvn@3037 170 FLAG_SET_DEFAULT(UseCBCond, false);
twisti@1078 171 }
twisti@1078 172
kvn@3092 173 assert(BlockZeroingLowLimit > 0, "invalid value");
kvn@3092 174 if (has_block_zeroing()) {
kvn@3092 175 if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
kvn@3092 176 FLAG_SET_DEFAULT(UseBlockZeroing, true);
kvn@3092 177 }
kvn@3092 178 } else if (UseBlockZeroing) {
kvn@3092 179 warning("BIS zeroing instructions are not available on this CPU");
kvn@3092 180 FLAG_SET_DEFAULT(UseBlockZeroing, false);
kvn@3092 181 }
kvn@3092 182
never@2085 183 #ifdef COMPILER2
kvn@3037 184 // T4 and newer Sparc cpus have fast RDPC.
kvn@3037 185 if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
kvn@3037 186 // FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
kvn@3037 187 }
kvn@3037 188
never@2085 189 // Currently not supported anywhere.
never@2085 190 FLAG_SET_DEFAULT(UseFPUForSpilling, false);
kvn@3049 191
kvn@3049 192 assert((InteriorEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
never@2085 193 #endif
never@2085 194
kvn@3049 195 assert((CodeEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
kvn@3049 196 assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
kvn@3049 197
duke@435 198 char buf[512];
kvn@3037 199 jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
kvn@3037 200 (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
twisti@1078 201 (has_hardware_popc() ? ", popc" : ""),
kvn@3037 202 (has_vis1() ? ", vis1" : ""),
kvn@3037 203 (has_vis2() ? ", vis2" : ""),
kvn@3037 204 (has_vis3() ? ", vis3" : ""),
kvn@3037 205 (has_blk_init() ? ", blk_init" : ""),
kvn@3037 206 (has_cbcond() ? ", cbcond" : ""),
kvn@3037 207 (is_ultra3() ? ", ultra3" : ""),
kvn@3037 208 (is_sun4v() ? ", sun4v" : ""),
kvn@3037 209 (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
kvn@3037 210 (is_sparc64() ? ", sparc64" : ""),
twisti@1076 211 (!has_hardware_mul32() ? ", no-mul32" : ""),
twisti@1076 212 (!has_hardware_div32() ? ", no-div32" : ""),
duke@435 213 (!has_hardware_fsmuld() ? ", no-fsmuld" : ""));
duke@435 214
duke@435 215 // buf is started with ", " or is empty
duke@435 216 _features_str = strdup(strlen(buf) > 2 ? buf + 2 : buf);
duke@435 217
kvn@3001 218 // UseVIS is set to the smallest of what hardware supports and what
kvn@3001 219 // the command line requires. I.e., you cannot set UseVIS to 3 on
kvn@3001 220 // older UltraSparc which do not support it.
kvn@3001 221 if (UseVIS > 3) UseVIS=3;
kvn@3001 222 if (UseVIS < 0) UseVIS=0;
kvn@3001 223 if (!has_vis3()) // Drop to 2 if no VIS3 support
kvn@3001 224 UseVIS = MIN2((intx)2,UseVIS);
kvn@3001 225 if (!has_vis2()) // Drop to 1 if no VIS2 support
kvn@3001 226 UseVIS = MIN2((intx)1,UseVIS);
kvn@3001 227 if (!has_vis1()) // Drop to 0 if no VIS1 support
kvn@3001 228 UseVIS = 0;
kvn@3001 229
duke@435 230 #ifndef PRODUCT
duke@435 231 if (PrintMiscellaneous && Verbose) {
kvn@3052 232 tty->print("Allocation");
duke@435 233 if (AllocatePrefetchStyle <= 0) {
kvn@3052 234 tty->print_cr(": no prefetching");
duke@435 235 } else {
kvn@3052 236 tty->print(" prefetching: ");
kvn@3052 237 if (AllocatePrefetchInstr == 0) {
kvn@3052 238 tty->print("PREFETCH");
kvn@3052 239 } else if (AllocatePrefetchInstr == 1) {
kvn@3052 240 tty->print("BIS");
kvn@3052 241 }
duke@435 242 if (AllocatePrefetchLines > 1) {
kvn@3052 243 tty->print_cr(" at distance %d, %d lines of %d bytes", AllocatePrefetchDistance, AllocatePrefetchLines, AllocatePrefetchStepSize);
duke@435 244 } else {
kvn@3052 245 tty->print_cr(" at distance %d, one line of %d bytes", AllocatePrefetchDistance, AllocatePrefetchStepSize);
duke@435 246 }
duke@435 247 }
duke@435 248 if (PrefetchCopyIntervalInBytes > 0) {
duke@435 249 tty->print_cr("PrefetchCopyIntervalInBytes %d", PrefetchCopyIntervalInBytes);
duke@435 250 }
duke@435 251 if (PrefetchScanIntervalInBytes > 0) {
duke@435 252 tty->print_cr("PrefetchScanIntervalInBytes %d", PrefetchScanIntervalInBytes);
duke@435 253 }
duke@435 254 if (PrefetchFieldsAhead > 0) {
duke@435 255 tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
duke@435 256 }
duke@435 257 }
duke@435 258 #endif // PRODUCT
duke@435 259 }
duke@435 260
duke@435 261 void VM_Version::print_features() {
duke@435 262 tty->print_cr("Version:%s", cpu_features());
duke@435 263 }
duke@435 264
duke@435 265 int VM_Version::determine_features() {
duke@435 266 if (UseV8InstrsOnly) {
duke@435 267 NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-V8");)
duke@435 268 return generic_v8_m;
duke@435 269 }
duke@435 270
duke@435 271 int features = platform_features(unknown_m); // platform_features() is os_arch specific
duke@435 272
duke@435 273 if (features == unknown_m) {
duke@435 274 features = generic_v9_m;
duke@435 275 warning("Cannot recognize SPARC version. Default to V9");
duke@435 276 }
duke@435 277
kvn@2403 278 assert(is_T_family(features) == is_niagara(features), "Niagara should be T series");
kvn@2403 279 if (UseNiagaraInstrs) { // Force code generation for Niagara
kvn@2403 280 if (is_T_family(features)) {
duke@435 281 // Happy to accomodate...
duke@435 282 } else {
duke@435 283 NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-Niagara");)
kvn@2403 284 features |= T_family_m;
duke@435 285 }
duke@435 286 } else {
kvn@2403 287 if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) {
duke@435 288 NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Version is Forced-Not-Niagara");)
kvn@2403 289 features &= ~(T_family_m | T1_model_m);
duke@435 290 } else {
duke@435 291 // Happy to accomodate...
duke@435 292 }
duke@435 293 }
duke@435 294
duke@435 295 return features;
duke@435 296 }
duke@435 297
duke@435 298 static int saved_features = 0;
duke@435 299
duke@435 300 void VM_Version::allow_all() {
duke@435 301 saved_features = _features;
duke@435 302 _features = all_features_m;
duke@435 303 }
duke@435 304
duke@435 305 void VM_Version::revert() {
duke@435 306 _features = saved_features;
duke@435 307 }
jmasa@445 308
jmasa@445 309 unsigned int VM_Version::calc_parallel_worker_threads() {
jmasa@445 310 unsigned int result;
kvn@2403 311 if (is_niagara_plus()) {
jmasa@445 312 result = nof_parallel_worker_threads(5, 16, 8);
jmasa@445 313 } else {
jmasa@445 314 result = nof_parallel_worker_threads(5, 8, 8);
jmasa@445 315 }
jmasa@445 316 return result;
jmasa@445 317 }

mercurial