JDK-8029190 : VM_Version::determine_features() asserts on Fujitsu Sparc64 CPUs
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris
  • CPU: sparc_64
  • Submitted: 2013-11-26
  • Updated: 2015-02-02
  • Resolved: 2013-12-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 Other
7u80Fixed 8Fixed hs25Fixed
Related Reports
Relates :  
Relates :  
Description
The whole CPU detection for SPARC CPUs seems to be targeted solely to Sun/Oracle SPARC CPUs.

If running on a recent Fujitsu Sparc64-X CPU, debug builds immediately crash with:

 assert(is_T_family(features) == is_niagara(features)) failed: Niagara should be T series

This test can not be successful on a Fujitsu Sparc64 CPU because is_niagara(features) tests for the sysinfo string 'SI_MACHINE' which is 'sun4v' on both, Oracle and Fujitsu CPUs while is_T_family(features) checks that the kernel statistics module 'cpu_info.implementation' contains the name "SPARC-T" or "SPARC-M". However, on Fujitsu SPARC64-X CPUs, 'cpu_info.implementation' contains the value "SPARC64-X".

This problem can easily be worked around by changing the above assertion to:

assert((is_T_family(features) == is_niagara(features)) || (features & sparc64_family_m), "Niagara should be T series");

But if we are using a CMS or G1, the VM will immediately crash with the next assertion in arguments.cpp:

    if (VM_Version::is_sun4v() && UseMemSetInBOT) {
      assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");

This is again because 'is_sun4v()' is used with the semantics of 'is_niagara()' and in VM_Version::initialize() in vm_version_sparc.cpp we reset 'UseMemSetInBOT' to false if 'is_niagara()' is true:

  if (is_niagara()) {
    // When using CMS or G1, we cannot use memset() in BOT updates
    // because the sun4v/CMT version in libc_psr uses BIS which
    // exposes "phantom zeros" to concurrent readers. See 6948537.
    if (FLAG_IS_DEFAULT(UseMemSetInBOT) && (UseConcMarkSweepGC || UseG1GC)) {
      FLAG_SET_DEFAULT(UseMemSetInBOT, false);
    }

We could actually fix this in the same way like before, by replacing 'is_sun4v()' with 'is_niagara()' in the assertion, but this would require to make at least the following functions public in vm_version_sparc.hpp:

  static bool is_T_family(int features) { return (features & T_family_m) != 0; }
  static bool is_niagara() { return is_T_family(_features); }

However the bigger problem is that I have no idea of what the semantics of these attributes (i.e. is_niagara, is_T_family, is_M_family) is for Fujitsu Sparc-X CPUs? E.g. do we need to switch of 'UseMemSetInBOT' as well?

There's are also other CPU-features like 'UseBlockCopy' and 'UseBlockZeroing' which are actually detected by looking at the instruction set extensions AND the CPU family. E.g. the above options are only enabled if the CPU supports 'block init instructions' (which is true on both Fujitsu Sparc64-X and new Oracle Sparc-T4 CPUs) AND the CPU family is Sparc-T4 (which is of course only true for Oracle SParc CPUs).

Altogether, I think we need a real SPARC expert which knows both, the Oracle and the Fujitsu Sparc CPUs and who can tell us which of the Oracle Sparc features currently used in the HotSpot are available in Fujitsu CPUs as well. Moreover we should unify the various 'has_xxx()' and 'is_xxx()' functions from vm_version_sparc.hpp to work equally well for both CPU types.

PS: 

- the Fujitsu Sparc64-X I have access to returns the following instruction set extensions vector and CPU features:

getisax(2) returned: 0x400081f0
cpu_info.implementation: SPARC64-X (chipid 0, clock 2800 MHz)
Allocation prefetching: PREFETCH at distance 512, 3 lines of 64 bytes
PrefetchCopyIntervalInBytes 512
PrefetchScanIntervalInBytes 512
ContendedPaddingWidth 128
CPU:total 16 v9, popc, vis1, vis2, blk_init, sun4v, sparc64

- for the Sparc-T4 I've acess to this information looks as follows:

getisax(2) returned: 0x3ffe8df0
cpu_info.implementation: SPARC-T4 (chipid 0, clock 2848 MHz)
Allocation prefetching: BIS at distance 64, 6 lines of 32 bytes
PrefetchCopyIntervalInBytes 512
PrefetchScanIntervalInBytes 512
ContendedPaddingWidth 128
CPU:total 64 v9, popc, vis1, vis2, vis3, blk_init, cbcond, sun4v, niagara_plus

As you probably know, the full meaning of the instruction set extensions vector can be derived by inspecting /usr/includ/sys/auxv_SPARC.h



Comments
Release team: Approved for fixing
03-12-2013

SQE is OK with fixing this in JDK8. As Vladimir said, the fix is necessary to enable testing on Fujitsu Sparc-X
02-12-2013

Critical request: as pointed in Description the bug prevent testing Hotspot on Fujitsu Sparc-X. Changes are small and safe: http://cr.openjdk.java.net/~simonis/webrevs/8029190/
02-12-2013

I agree that is_niagara(features) is a mess. It should be true only for Oracle T-Series SPARC.
26-11-2013

'block init instructions' could be implemented differently on Fujitsu Sparc-X. BIS was on T1 and T2 but we could not use it for UseBlockCopy and UseBlockZeroing because of implementation. I think we should not use BIS on Fujitsu Sparc-X until we know what it does. And it looks like it is the case based on "Allocation prefetching:" value.
26-11-2013

The question about UseMemSetInBOT is difficult. Because we need to know how memset() is implemented on Solaris on Fujitsu Sparc-X. If it also use BIS UseMemSetInBOT should be false.
26-11-2013