8182711: Re/Introduce private interface for HW-specific prefetch options in SPARC VM_Version
authorneliasso
Tue, 27 Jun 2017 15:22:23 +0200
changeset 46591 3f3105af599e
parent 46567 30efdd5f0dc9
child 46592 6e357e2c8143
8182711: Re/Introduce private interface for HW-specific prefetch options in SPARC VM_Version Summary: Re/Introduce private interface for HW-specific prefetch options in SPARC VM_Version Reviewed-by: kvn, neliasso Contributed-by: phedlin@oracle.com
hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Tue Jun 27 07:52:50 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Tue Jun 27 15:22:23 2017 +0200
@@ -38,46 +38,36 @@
   assert(_features != 0, "System pre-initialization is not complete.");
   guarantee(VM_Version::has_v9(), "only SPARC v9 is supported");
 
-  if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) {
-    FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, prefetch_copy_interval_in_bytes());
-  }
-  if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) {
-    FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, prefetch_scan_interval_in_bytes());
-  }
-  if (FLAG_IS_DEFAULT(PrefetchFieldsAhead)) {
-    FLAG_SET_DEFAULT(PrefetchFieldsAhead, prefetch_fields_ahead());
-  }
+  PrefetchCopyIntervalInBytes = prefetch_copy_interval_in_bytes();
+  PrefetchScanIntervalInBytes = prefetch_scan_interval_in_bytes();
+  PrefetchFieldsAhead         = prefetch_fields_ahead();
 
   // Allocation prefetch settings
+
+  AllocatePrefetchDistance = allocate_prefetch_distance();
+  AllocatePrefetchStyle    = allocate_prefetch_style();
+
   intx cache_line_size = prefetch_data_size();
-  if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize) &&
-      (cache_line_size > AllocatePrefetchStepSize)) {
-    FLAG_SET_DEFAULT(AllocatePrefetchStepSize, cache_line_size);
+
+  if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) {
+    AllocatePrefetchStepSize = MAX2(AllocatePrefetchStepSize, cache_line_size);
   }
 
-  if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) {
-    FLAG_SET_DEFAULT(AllocatePrefetchDistance, 512);
-  }
-
-  if ((AllocatePrefetchDistance == 0) && (AllocatePrefetchStyle != 0)) {
-    assert(!FLAG_IS_DEFAULT(AllocatePrefetchDistance), "default value should not be 0");
-    if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
-      warning("AllocatePrefetchDistance is set to 0 which disable prefetching. Ignoring AllocatePrefetchStyle flag.");
+  if (AllocatePrefetchInstr == 1) {
+    if (!has_blk_init()) {
+      warning("BIS instructions required for AllocatePrefetchInstr 1 unavailable");
+      FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
     }
-    FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0);
+    if (cache_line_size <= 0) {
+      warning("Cache-line size must be known for AllocatePrefetchInstr 1 to work");
+      FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
+    }
   }
 
-  if ((AllocatePrefetchInstr == 1) && (!has_blk_init() || cache_line_size <= 0)) {
-    if (!FLAG_IS_DEFAULT(AllocatePrefetchInstr)) {
-      warning("BIS instructions required for AllocatePrefetchInstr 1 unavailable");
-    }
-    FLAG_SET_DEFAULT(AllocatePrefetchInstr, 0);
-  }
+  UseSSE = false;                   // Only used on x86 and x64.
 
-  UseSSE = 0; // Only on x86 and x64
-
-  _supports_cx8 = has_v9();
-  _supports_atomic_getset4 = true; // swap instruction
+  _supports_cx8 = true;             // All SPARC V9 implementations.
+  _supports_atomic_getset4 = true;  // Using the 'swap' instruction.
 
   if (is_niagara()) {
     // Indirect branch is the same cost as direct
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Tue Jun 27 07:52:50 2017 +0200
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp	Tue Jun 27 15:22:23 2017 +0200
@@ -178,17 +178,51 @@
   // default prefetch block size on sparc
   static intx prefetch_data_size()      { return L2_data_cache_line_size();  }
 
-  // Prefetch
+ private:
+  // Prefetch policy and characteristics:
+  //
+  // These support routines are used in order to isolate any CPU/core specific
+  // logic from the actual flag/option processing.  They should reflect the HW
+  // characteristics for the associated options on the current platform.
+  //
+  // The three Prefetch* options below (assigned -1 in the configuration) are
+  // treated according to (given the accepted range [-1..<maxint>]):
+  //  -1: Determine a proper HW-specific value for the current HW.
+  //   0: Off
+  //  >0: Command-line supplied value to use.
+  //
+  // FIXME: The documentation string in the configuration is wrong, saying that
+  //        -1 is also interpreted as off.
+  //
   static intx prefetch_copy_interval_in_bytes() {
-    return (has_v9() ? 512 : 0);
+    intx bytes = PrefetchCopyIntervalInBytes;
+    return bytes < 0 ? 512 : bytes;
   }
   static intx prefetch_scan_interval_in_bytes() {
-    return (has_v9() ? 512 : 0);
+    intx bytes = PrefetchScanIntervalInBytes;
+    return bytes < 0 ? 512 : bytes;
   }
   static intx prefetch_fields_ahead() {
-    return (is_ultra3() ? 1 : 0);
+    intx count = PrefetchFieldsAhead;
+    return count < 0 ? 0 : count;
   }
 
+  // AllocatePrefetchDistance is treated under the same interpretation as the
+  // Prefetch* options above (i.e., -1, 0, >0).
+  static intx allocate_prefetch_distance() {
+    intx count = AllocatePrefetchDistance;
+    return count < 0 ? 512 : count;
+  }
+
+  // AllocatePrefetchStyle is guaranteed to be in range [0..3] defined by the
+  // configuration.
+  static intx allocate_prefetch_style() {
+    intx distance = allocate_prefetch_distance();
+    // Return 0 (off/none) if AllocatePrefetchDistance was not defined.
+    return distance > 0 ? AllocatePrefetchStyle : 0;
+  }
+
+ public:
   // Assembler testing
   static void allow_all();
   static void revert();