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