Merge

Fri, 28 Apr 2017 14:18:52 -0700

author
asaha
date
Fri, 28 Apr 2017 14:18:52 -0700
changeset 8973
b5eef1d97c9e
parent 8963
2163b7e4a74f
parent 8972
012f8c6cee9a
child 8974
eb250b03d163

Merge

.hgtags file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Fri Apr 28 14:03:33 2017 -0700
     1.2 +++ b/.hgtags	Fri Apr 28 14:18:52 2017 -0700
     1.3 @@ -965,6 +965,8 @@
     1.4  56e71d16083904ceddfdd1d66312582a42781646 jdk8u131-b09
     1.5  1da23ae49386608550596502d90a381ee6c1dfaa jdk8u131-b10
     1.6  829ea9b92cda9545652f1b309f56c57383024ebb jdk8u131-b11
     1.7 +41e0713bcca27cef5d6a9afd44c7ca4811937713 jdk8u131-b31
     1.8 +e318654a4fa352a06935dd56eebf88ae387b31f9 jdk8u131-b32
     1.9  692bc6b674dcab72453de08ee9da0856a7e41c0f jdk8u141-b00
    1.10  0cee0db0180b64655751e7058c251103f9660f85 jdk8u141-b01
    1.11  82435799636c8b50a090aebcb5af49946afa7bb5 jdk8u141-b02
     2.1 --- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Fri Apr 28 14:03:33 2017 -0700
     2.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Fri Apr 28 14:18:52 2017 -0700
     2.3 @@ -236,7 +236,7 @@
     2.4    assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
     2.5  
     2.6    char buf[512];
     2.7 -  jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
     2.8 +  jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
     2.9                 (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")),
    2.10                 (has_hardware_popc() ? ", popc" : ""),
    2.11                 (has_vis1() ? ", vis1" : ""),
    2.12 @@ -249,6 +249,7 @@
    2.13                 (has_sha256() ? ", sha256" : ""),
    2.14                 (has_sha512() ? ", sha512" : ""),
    2.15                 (is_ultra3() ? ", ultra3" : ""),
    2.16 +               (has_sparc5_instr() ? ", sparc5" : ""),
    2.17                 (is_sun4v() ? ", sun4v" : ""),
    2.18                 (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")),
    2.19                 (is_sparc64() ? ", sparc64" : ""),
    2.20 @@ -364,6 +365,7 @@
    2.21  
    2.22  #ifndef PRODUCT
    2.23    if (PrintMiscellaneous && Verbose) {
    2.24 +    tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
    2.25      tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
    2.26      tty->print("Allocation");
    2.27      if (AllocatePrefetchStyle <= 0) {
    2.28 @@ -447,9 +449,10 @@
    2.29  
    2.30  unsigned int VM_Version::calc_parallel_worker_threads() {
    2.31    unsigned int result;
    2.32 -  if (is_M_series()) {
    2.33 -    // for now, use same gc thread calculation for M-series as for niagara-plus
    2.34 -    // in future, we may want to tweak parameters for nof_parallel_worker_thread
    2.35 +  if (is_M_series() || is_S_series()) {
    2.36 +    // for now, use same gc thread calculation for M-series and S-series as for
    2.37 +    // niagara-plus. In future, we may want to tweak parameters for
    2.38 +    // nof_parallel_worker_thread
    2.39      result = nof_parallel_worker_threads(5, 16, 8);
    2.40    } else if (is_niagara_plus()) {
    2.41      result = nof_parallel_worker_threads(5, 16, 8);
    2.42 @@ -458,3 +461,37 @@
    2.43    }
    2.44    return result;
    2.45  }
    2.46 +
    2.47 +
    2.48 +int VM_Version::parse_features(const char* implementation) {
    2.49 +  int features = unknown_m;
    2.50 +  // Convert to UPPER case before compare.
    2.51 +  char* impl = os::strdup(implementation);
    2.52 +
    2.53 +  for (int i = 0; impl[i] != 0; i++)
    2.54 +    impl[i] = (char)toupper((uint)impl[i]);
    2.55 +
    2.56 +  if (strstr(impl, "SPARC64") != NULL) {
    2.57 +    features |= sparc64_family_m;
    2.58 +  } else if (strstr(impl, "SPARC-M") != NULL) {
    2.59 +    // M-series SPARC is based on T-series.
    2.60 +    features |= (M_family_m | T_family_m);
    2.61 +  } else if (strstr(impl, "SPARC-S") != NULL) {
    2.62 +    // S-series SPARC is based on T-series.
    2.63 +    features |= (S_family_m | T_family_m);
    2.64 +  } else if (strstr(impl, "SPARC-T") != NULL) {
    2.65 +    features |= T_family_m;
    2.66 +    if (strstr(impl, "SPARC-T1") != NULL) {
    2.67 +      features |= T1_model_m;
    2.68 +    }
    2.69 +  } else if (strstr(impl, "SUN4V-CPU") != NULL) {
    2.70 +    // Generic or migration class LDOM
    2.71 +    features |= T_family_m;
    2.72 +  } else {
    2.73 +#ifndef PRODUCT
    2.74 +    warning("Failed to parse CPU implementation = '%s'", impl);
    2.75 +#endif
    2.76 +  }
    2.77 +  os::free((void*)impl);
    2.78 +  return features;
    2.79 +}
     3.1 --- a/src/cpu/sparc/vm/vm_version_sparc.hpp	Fri Apr 28 14:03:33 2017 -0700
     3.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp	Fri Apr 28 14:18:52 2017 -0700
     3.3 @@ -47,13 +47,14 @@
     3.4      cbcond_instructions  = 13,
     3.5      sparc64_family       = 14,
     3.6      M_family             = 15,
     3.7 -    T_family             = 16,
     3.8 -    T1_model             = 17,
     3.9 -    sparc5_instructions  = 18,
    3.10 -    aes_instructions     = 19,
    3.11 -    sha1_instruction     = 20,
    3.12 -    sha256_instruction   = 21,
    3.13 -    sha512_instruction   = 22
    3.14 +    S_family             = 16,
    3.15 +    T_family             = 17,
    3.16 +    T1_model             = 18,
    3.17 +    sparc5_instructions  = 19,
    3.18 +    aes_instructions     = 20,
    3.19 +    sha1_instruction     = 21,
    3.20 +    sha256_instruction   = 22,
    3.21 +    sha512_instruction   = 23
    3.22    };
    3.23  
    3.24    enum Feature_Flag_Set {
    3.25 @@ -76,6 +77,7 @@
    3.26      cbcond_instructions_m   = 1 << cbcond_instructions,
    3.27      sparc64_family_m        = 1 << sparc64_family,
    3.28      M_family_m              = 1 << M_family,
    3.29 +    S_family_m              = 1 << S_family,
    3.30      T_family_m              = 1 << T_family,
    3.31      T1_model_m              = 1 << T1_model,
    3.32      sparc5_instructions_m   = 1 << sparc5_instructions,
    3.33 @@ -105,6 +107,7 @@
    3.34  
    3.35    // Returns true if the platform is in the niagara line (T series)
    3.36    static bool is_M_family(int features) { return (features & M_family_m) != 0; }
    3.37 +  static bool is_S_family(int features) { return (features & S_family_m) != 0; }
    3.38    static bool is_T_family(int features) { return (features & T_family_m) != 0; }
    3.39    static bool is_niagara() { return is_T_family(_features); }
    3.40  #ifdef ASSERT
    3.41 @@ -119,7 +122,7 @@
    3.42    static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
    3.43  
    3.44    static int maximum_niagara1_processor_count() { return 32; }
    3.45 -
    3.46 +  static int parse_features(const char* implementation);
    3.47  public:
    3.48    // Initialization
    3.49    static void initialize();
    3.50 @@ -152,6 +155,7 @@
    3.51    static bool is_niagara_plus()         { return is_T_family(_features) && !is_T1_model(_features); }
    3.52  
    3.53    static bool is_M_series()             { return is_M_family(_features); }
    3.54 +  static bool is_S_series()             { return is_S_family(_features); }
    3.55    static bool is_T4()                   { return is_T_family(_features) && has_cbcond(); }
    3.56    static bool is_T7()                   { return is_T_family(_features) && has_sparc5_instr(); }
    3.57  
     4.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp	Fri Apr 28 14:03:33 2017 -0700
     4.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp	Fri Apr 28 14:18:52 2017 -0700
     4.3 @@ -406,6 +406,8 @@
     4.4    _stepping = 0;
     4.5    _cpuFeatures = 0;
     4.6    _logical_processors_per_package = 1;
     4.7 +  // i486 internal cache is both I&D and has a 16-byte line size
     4.8 +  _L1_data_cache_line_size = 16;
     4.9  
    4.10    if (!Use486InstrsOnly) {
    4.11      // Get raw processor info
    4.12 @@ -424,6 +426,7 @@
    4.13        // Logical processors are only available on P4s and above,
    4.14        // and only if hyperthreading is available.
    4.15        _logical_processors_per_package = logical_processor_count();
    4.16 +      _L1_data_cache_line_size = L1_line_size();
    4.17      }
    4.18    }
    4.19  
    4.20 @@ -1034,6 +1037,7 @@
    4.21    if (PrintMiscellaneous && Verbose) {
    4.22      tty->print_cr("Logical CPUs per core: %u",
    4.23                    logical_processors_per_package());
    4.24 +    tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
    4.25      tty->print("UseSSE=%d", (int) UseSSE);
    4.26      if (UseAVX > 0) {
    4.27        tty->print("  UseAVX=%d", (int) UseAVX);
     5.1 --- a/src/cpu/x86/vm/vm_version_x86.hpp	Fri Apr 28 14:03:33 2017 -0700
     5.2 +++ b/src/cpu/x86/vm/vm_version_x86.hpp	Fri Apr 28 14:18:52 2017 -0700
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -595,7 +595,7 @@
    5.11      return (result == 0 ? 1 : result);
    5.12    }
    5.13  
    5.14 -  static intx prefetch_data_size()  {
    5.15 +  static intx L1_line_size()  {
    5.16      intx result = 0;
    5.17      if (is_intel()) {
    5.18        result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1);
    5.19 @@ -607,6 +607,10 @@
    5.20      return result;
    5.21    }
    5.22  
    5.23 +  static intx prefetch_data_size()  {
    5.24 +    return L1_line_size();
    5.25 +  }
    5.26 +
    5.27    //
    5.28    // Feature identification
    5.29    //
     6.1 --- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Fri Apr 28 14:03:33 2017 -0700
     6.2 +++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Fri Apr 28 14:18:52 2017 -0700
     6.3 @@ -262,6 +262,7 @@
     6.4  
     6.5  // We need to keep these here as long as we have to build on Solaris
     6.6  // versions before 10.
     6.7 +
     6.8  #ifndef SI_ARCHITECTURE_32
     6.9  #define SI_ARCHITECTURE_32      516     /* basic 32-bit SI_ARCHITECTURE */
    6.10  #endif
    6.11 @@ -270,231 +271,233 @@
    6.12  #define SI_ARCHITECTURE_64      517     /* basic 64-bit SI_ARCHITECTURE */
    6.13  #endif
    6.14  
    6.15 -static void do_sysinfo(int si, const char* string, int* features, int mask) {
    6.16 -  char   tmp;
    6.17 -  size_t bufsize = sysinfo(si, &tmp, 1);
    6.18 +#ifndef SI_CPUBRAND
    6.19 +#define SI_CPUBRAND             523     /* return cpu brand string */
    6.20 +#endif
    6.21  
    6.22 -  // All SI defines used below must be supported.
    6.23 -  guarantee(bufsize != -1, "must be supported");
    6.24 +class Sysinfo {
    6.25 +  char* _string;
    6.26 +public:
    6.27 +  Sysinfo(int si) : _string(NULL) {
    6.28 +    char   tmp;
    6.29 +    size_t bufsize = sysinfo(si, &tmp, 1);
    6.30  
    6.31 -  char* buf = (char*) malloc(bufsize);
    6.32 +    if (bufsize != -1) {
    6.33 +      char* buf = (char*) os::malloc(bufsize, mtInternal);
    6.34 +      if (buf != NULL) {
    6.35 +        if (sysinfo(si, buf, bufsize) == bufsize) {
    6.36 +          _string = buf;
    6.37 +        } else {
    6.38 +          os::free(buf);
    6.39 +        }
    6.40 +      }
    6.41 +     }
    6.42 +   }
    6.43  
    6.44 -  if (buf == NULL)
    6.45 -    return;
    6.46 -
    6.47 -  if (sysinfo(si, buf, bufsize) == bufsize) {
    6.48 -    // Compare the string.
    6.49 -    if (strcmp(buf, string) == 0) {
    6.50 -      *features |= mask;
    6.51 +  ~Sysinfo() {
    6.52 +    if (_string != NULL) {
    6.53 +      os::free(_string);
    6.54      }
    6.55    }
    6.56  
    6.57 -  free(buf);
    6.58 -}
    6.59 +  const char* value() const {
    6.60 +    return _string;
    6.61 +  }
    6.62 +
    6.63 +  bool valid() const {
    6.64 +    return _string != NULL;
    6.65 +  }
    6.66 +
    6.67 +  bool match(const char* s) const {
    6.68 +    return valid() ? strcmp(_string, s) == 0 : false;
    6.69 +  }
    6.70 +
    6.71 +  bool match_substring(const char* s) const {
    6.72 +    return valid() ? strstr(_string, s) != NULL : false;
    6.73 +  }
    6.74 +};
    6.75 +
    6.76 +class Sysconf {
    6.77 +  int _value;
    6.78 +public:
    6.79 +  Sysconf(int sc) : _value(-1) {
    6.80 +    _value = sysconf(sc);
    6.81 +  }
    6.82 +  bool valid() const {
    6.83 +    return _value != -1;
    6.84 +  }
    6.85 +  int value() const {
    6.86 +    return _value;
    6.87 +  }
    6.88 +};
    6.89 +
    6.90 +
    6.91 +#ifndef _SC_DCACHE_LINESZ
    6.92 +#define _SC_DCACHE_LINESZ       508     /* Data cache line size */
    6.93 +#endif
    6.94 +
    6.95 +#ifndef _SC_L2CACHE_LINESZ
    6.96 +#define _SC_L2CACHE_LINESZ      527     /* Size of L2 cache line */
    6.97 +#endif
    6.98 +
    6.99  
   6.100  int VM_Version::platform_features(int features) {
   6.101 -  // getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are
   6.102 -  // supported on Solaris 10 and later.
   6.103 -  if (os::Solaris::supports_getisax()) {
   6.104 +  assert(os::Solaris::supports_getisax(), "getisax() must be available");
   6.105  
   6.106 -    // Check 32-bit architecture.
   6.107 -    do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m);
   6.108 +  // Check 32-bit architecture.
   6.109 +  if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) {
   6.110 +    features |= v8_instructions_m;
   6.111 +  }
   6.112  
   6.113 -    // Check 64-bit architecture.
   6.114 -    do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m);
   6.115 +  // Check 64-bit architecture.
   6.116 +  if (Sysinfo(SI_ARCHITECTURE_64).match("sparcv9")) {
   6.117 +    features |= generic_v9_m;
   6.118 +  }
   6.119  
   6.120 -    // Extract valid instruction set extensions.
   6.121 -    uint_t avs[2];
   6.122 -    uint_t avn = os::Solaris::getisax(avs, 2);
   6.123 -    assert(avn <= 2, "should return two or less av's");
   6.124 -    uint_t av = avs[0];
   6.125 +  // Extract valid instruction set extensions.
   6.126 +  uint_t avs[2];
   6.127 +  uint_t avn = os::Solaris::getisax(avs, 2);
   6.128 +  assert(avn <= 2, "should return two or less av's");
   6.129 +  uint_t av = avs[0];
   6.130  
   6.131  #ifndef PRODUCT
   6.132 -    if (PrintMiscellaneous && Verbose) {
   6.133 -      tty->print("getisax(2) returned: " PTR32_FORMAT, av);
   6.134 -      if (avn > 1) {
   6.135 -        tty->print(", " PTR32_FORMAT, avs[1]);
   6.136 -      }
   6.137 -      tty->cr();
   6.138 +  if (PrintMiscellaneous && Verbose) {
   6.139 +    tty->print("getisax(2) returned: " PTR32_FORMAT, av);
   6.140 +    if (avn > 1) {
   6.141 +      tty->print(", " PTR32_FORMAT, avs[1]);
   6.142      }
   6.143 +    tty->cr();
   6.144 +  }
   6.145  #endif
   6.146  
   6.147 -    if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
   6.148 -    if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
   6.149 -    if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
   6.150 -    if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m;
   6.151 -    if (av & AV_SPARC_POPC)   features |= hardware_popc_m;
   6.152 -    if (av & AV_SPARC_VIS)    features |= vis1_instructions_m;
   6.153 -    if (av & AV_SPARC_VIS2)   features |= vis2_instructions_m;
   6.154 -    if (avn > 1) {
   6.155 -      uint_t av2 = avs[1];
   6.156 +  if (av & AV_SPARC_MUL32)  features |= hardware_mul32_m;
   6.157 +  if (av & AV_SPARC_DIV32)  features |= hardware_div32_m;
   6.158 +  if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m;
   6.159 +  if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m;
   6.160 +  if (av & AV_SPARC_POPC)   features |= hardware_popc_m;
   6.161 +  if (av & AV_SPARC_VIS)    features |= vis1_instructions_m;
   6.162 +  if (av & AV_SPARC_VIS2)   features |= vis2_instructions_m;
   6.163 +  if (avn > 1) {
   6.164 +    uint_t av2 = avs[1];
   6.165  #ifndef AV2_SPARC_SPARC5
   6.166  #define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */
   6.167  #endif
   6.168 -      if (av2 & AV2_SPARC_SPARC5)       features |= sparc5_instructions_m;
   6.169 -    }
   6.170 +    if (av2 & AV2_SPARC_SPARC5)       features |= sparc5_instructions_m;
   6.171 +  }
   6.172  
   6.173 -    // Next values are not defined before Solaris 10
   6.174 -    // but Solaris 8 is used for jdk6 update builds.
   6.175 +  // We only build on Solaris 10 and up, but some of the values below
   6.176 +  // are not defined on all versions of Solaris 10, so we define them,
   6.177 +  // if necessary.
   6.178  #ifndef AV_SPARC_ASI_BLK_INIT
   6.179  #define AV_SPARC_ASI_BLK_INIT 0x0080  /* ASI_BLK_INIT_xxx ASI */
   6.180  #endif
   6.181 -    if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
   6.182 +  if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m;
   6.183  
   6.184  #ifndef AV_SPARC_FMAF
   6.185  #define AV_SPARC_FMAF 0x0100        /* Fused Multiply-Add */
   6.186  #endif
   6.187 -    if (av & AV_SPARC_FMAF)         features |= fmaf_instructions_m;
   6.188 +  if (av & AV_SPARC_FMAF)         features |= fmaf_instructions_m;
   6.189  
   6.190  #ifndef AV_SPARC_FMAU
   6.191 -#define    AV_SPARC_FMAU    0x0200  /* Unfused Multiply-Add */
   6.192 +#define AV_SPARC_FMAU    0x0200  /* Unfused Multiply-Add */
   6.193  #endif
   6.194 -    if (av & AV_SPARC_FMAU)         features |= fmau_instructions_m;
   6.195 +  if (av & AV_SPARC_FMAU)         features |= fmau_instructions_m;
   6.196  
   6.197  #ifndef AV_SPARC_VIS3
   6.198 -#define    AV_SPARC_VIS3    0x0400  /* VIS3 instruction set extensions */
   6.199 +#define AV_SPARC_VIS3    0x0400  /* VIS3 instruction set extensions */
   6.200  #endif
   6.201 -    if (av & AV_SPARC_VIS3)         features |= vis3_instructions_m;
   6.202 +  if (av & AV_SPARC_VIS3)         features |= vis3_instructions_m;
   6.203  
   6.204  #ifndef AV_SPARC_CBCOND
   6.205  #define AV_SPARC_CBCOND 0x10000000  /* compare and branch instrs supported */
   6.206  #endif
   6.207 -    if (av & AV_SPARC_CBCOND)       features |= cbcond_instructions_m;
   6.208 +  if (av & AV_SPARC_CBCOND)       features |= cbcond_instructions_m;
   6.209  
   6.210  #ifndef AV_SPARC_AES
   6.211  #define AV_SPARC_AES 0x00020000  /* aes instrs supported */
   6.212  #endif
   6.213 -    if (av & AV_SPARC_AES)       features |= aes_instructions_m;
   6.214 +  if (av & AV_SPARC_AES)       features |= aes_instructions_m;
   6.215  
   6.216  #ifndef AV_SPARC_SHA1
   6.217  #define AV_SPARC_SHA1   0x00400000  /* sha1 instruction supported */
   6.218  #endif
   6.219 -    if (av & AV_SPARC_SHA1)         features |= sha1_instruction_m;
   6.220 +  if (av & AV_SPARC_SHA1)         features |= sha1_instruction_m;
   6.221  
   6.222  #ifndef AV_SPARC_SHA256
   6.223  #define AV_SPARC_SHA256 0x00800000  /* sha256 instruction supported */
   6.224  #endif
   6.225 -    if (av & AV_SPARC_SHA256)       features |= sha256_instruction_m;
   6.226 +  if (av & AV_SPARC_SHA256)       features |= sha256_instruction_m;
   6.227  
   6.228  #ifndef AV_SPARC_SHA512
   6.229  #define AV_SPARC_SHA512 0x01000000  /* sha512 instruction supported */
   6.230  #endif
   6.231 -    if (av & AV_SPARC_SHA512)       features |= sha512_instruction_m;
   6.232 +  if (av & AV_SPARC_SHA512)       features |= sha512_instruction_m;
   6.233  
   6.234 +  // Determine the machine type.
   6.235 +  if (Sysinfo(SI_MACHINE).match("sun4v")) {
   6.236 +    features |= sun4v_m;
   6.237 +  }
   6.238 +
   6.239 +  // If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
   6.240 +  // is available to us as well
   6.241 +  Sysinfo cpu_info(SI_CPUBRAND);
   6.242 +  bool use_solaris_12_api = cpu_info.valid();
   6.243 +  const char* impl;
   6.244 +  int impl_m = 0;
   6.245 +  if (use_solaris_12_api) {
   6.246 +    impl = cpu_info.value();
   6.247 +#ifndef PRODUCT
   6.248 +  if (PrintMiscellaneous && Verbose) {
   6.249 +    tty->print_cr("Parsing CPU implementation from %s", impl);
   6.250 +  }
   6.251 +#endif
   6.252 +    impl_m = parse_features(impl);
   6.253    } else {
   6.254 -    // getisax(2) failed, use the old legacy code.
   6.255 +    // Otherwise use kstat to determine the machine type.
   6.256 +    kstat_ctl_t* kc = kstat_open();
   6.257 +    if (kc != NULL) {
   6.258 +      kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
   6.259 +      if (ksp != NULL) {
   6.260 +        if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
   6.261 +          kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
   6.262 +          for (int i = 0; i < ksp->ks_ndata; i++) {
   6.263 +            if (strcmp((const char*)&(knm[i].name), "implementation") == 0) {
   6.264 +              impl = KSTAT_NAMED_STR_PTR(&knm[i]);
   6.265  #ifndef PRODUCT
   6.266 -    if (PrintMiscellaneous && Verbose)
   6.267 -      tty->print_cr("getisax(2) is not supported.");
   6.268 +              if (PrintMiscellaneous && Verbose) {
   6.269 +                tty->print_cr("Parsing CPU implementation from %s", impl);
   6.270 +              }
   6.271  #endif
   6.272 -
   6.273 -    char   tmp;
   6.274 -    size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1);
   6.275 -    char*  buf     = (char*) malloc(bufsize);
   6.276 -
   6.277 -    if (buf != NULL) {
   6.278 -      if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) {
   6.279 -        // Figure out what kind of sparc we have
   6.280 -        char *sparc_string = strstr(buf, "sparc");
   6.281 -        if (sparc_string != NULL) {              features |= v8_instructions_m;
   6.282 -          if (sparc_string[5] == 'v') {
   6.283 -            if (sparc_string[6] == '8') {
   6.284 -              if (sparc_string[7] == '-') {      features |= hardware_mul32_m;
   6.285 -                                                 features |= hardware_div32_m;
   6.286 -              } else if (sparc_string[7] == 'p') features |= generic_v9_m;
   6.287 -              else                               features |= generic_v8_m;
   6.288 -            } else if (sparc_string[6] == '9')   features |= generic_v9_m;
   6.289 +              impl_m = parse_features(impl);
   6.290 +              break;
   6.291 +            }
   6.292            }
   6.293          }
   6.294 -
   6.295 -        // Check for visualization instructions
   6.296 -        char *vis = strstr(buf, "vis");
   6.297 -        if (vis != NULL) {                       features |= vis1_instructions_m;
   6.298 -          if (vis[3] == '2')                     features |= vis2_instructions_m;
   6.299 -        }
   6.300        }
   6.301 -      free(buf);
   6.302 +      kstat_close(kc);
   6.303      }
   6.304    }
   6.305 +  assert(impl_m != 0, err_msg("Unknown CPU implementation %s", impl));
   6.306 +  features |= impl_m;
   6.307  
   6.308 -  // Determine the machine type.
   6.309 -  do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m);
   6.310 +  bool is_sun4v = (features & sun4v_m) != 0;
   6.311 +  if (use_solaris_12_api && is_sun4v) {
   6.312 +    // If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes
   6.313 +    Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
   6.314 +    if (l1_dcache_line_size.valid()) {
   6.315 +      _L1_data_cache_line_size =  l1_dcache_line_size.value();
   6.316 +    }
   6.317  
   6.318 -  {
   6.319 -    // Using kstat to determine the machine type.
   6.320 -    kstat_ctl_t* kc = kstat_open();
   6.321 -    kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
   6.322 -    const char* implementation = "UNKNOWN";
   6.323 -    if (ksp != NULL) {
   6.324 -      if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
   6.325 -        kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
   6.326 -        for (int i = 0; i < ksp->ks_ndata; i++) {
   6.327 -          if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
   6.328 -#ifndef KSTAT_DATA_STRING
   6.329 -#define KSTAT_DATA_STRING   9
   6.330 -#endif
   6.331 -            if (knm[i].data_type == KSTAT_DATA_CHAR) {
   6.332 -              // VM is running on Solaris 8 which does not have value.str.
   6.333 -              implementation = &(knm[i].value.c[0]);
   6.334 -            } else if (knm[i].data_type == KSTAT_DATA_STRING) {
   6.335 -              // VM is running on Solaris 10.
   6.336 -#ifndef KSTAT_NAMED_STR_PTR
   6.337 -              // Solaris 8 was used to build VM, define the structure it misses.
   6.338 -              struct str_t {
   6.339 -                union {
   6.340 -                  char *ptr;     /* NULL-term string */
   6.341 -                  char __pad[8]; /* 64-bit padding */
   6.342 -                } addr;
   6.343 -                uint32_t len;    /* # bytes for strlen + '\0' */
   6.344 -              };
   6.345 -#define KSTAT_NAMED_STR_PTR(knptr) (( (str_t*)&((knptr)->value) )->addr.ptr)
   6.346 -#endif
   6.347 -              implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
   6.348 -            }
   6.349 -#ifndef PRODUCT
   6.350 -            if (PrintMiscellaneous && Verbose) {
   6.351 -              tty->print_cr("cpu_info.implementation: %s", implementation);
   6.352 -            }
   6.353 -#endif
   6.354 -            // Convert to UPPER case before compare.
   6.355 -            char* impl = strdup(implementation);
   6.356 -
   6.357 -            for (int i = 0; impl[i] != 0; i++)
   6.358 -              impl[i] = (char)toupper((uint)impl[i]);
   6.359 -            if (strstr(impl, "SPARC64") != NULL) {
   6.360 -              features |= sparc64_family_m;
   6.361 -            } else if (strstr(impl, "SPARC-M") != NULL) {
   6.362 -              // M-series SPARC is based on T-series.
   6.363 -              features |= (M_family_m | T_family_m);
   6.364 -            } else if (strstr(impl, "SPARC-T") != NULL) {
   6.365 -              features |= T_family_m;
   6.366 -              if (strstr(impl, "SPARC-T1") != NULL) {
   6.367 -                features |= T1_model_m;
   6.368 -              }
   6.369 -            } else {
   6.370 -              if (strstr(impl, "SPARC") == NULL) {
   6.371 -#ifndef PRODUCT
   6.372 -                // kstat on Solaris 8 virtual machines (branded zones)
   6.373 -                // returns "(unsupported)" implementation.
   6.374 -                warning("kstat cpu_info implementation = '%s', should contain SPARC", impl);
   6.375 -#endif
   6.376 -                implementation = "SPARC";
   6.377 -              }
   6.378 -            }
   6.379 -            free((void*)impl);
   6.380 -            break;
   6.381 -          }
   6.382 -        } // for(
   6.383 -      }
   6.384 +    Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
   6.385 +    if (l2_dcache_line_size.valid()) {
   6.386 +      _L2_data_cache_line_size = l2_dcache_line_size.value();
   6.387      }
   6.388 -    assert(strcmp(implementation, "UNKNOWN") != 0,
   6.389 -           "unknown cpu info (changed kstat interface?)");
   6.390 -    kstat_close(kc);
   6.391 +  } else {
   6.392 +    // Otherwise figure out the cache line sizes using PICL
   6.393 +    bool is_fujitsu = (features & sparc64_family_m) != 0;
   6.394 +    PICL picl(is_fujitsu, is_sun4v);
   6.395 +    _L1_data_cache_line_size = picl.L1_data_cache_line_size();
   6.396 +    _L2_data_cache_line_size = picl.L2_data_cache_line_size();
   6.397    }
   6.398 -
   6.399 -  // Figure out cache line sizes using PICL
   6.400 -  PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0);
   6.401 -  _L2_data_cache_line_size = picl.L2_data_cache_line_size();
   6.402 -
   6.403    return features;
   6.404  }
     7.1 --- a/src/share/vm/code/nmethod.cpp	Fri Apr 28 14:03:33 2017 -0700
     7.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Apr 28 14:18:52 2017 -0700
     7.3 @@ -1151,6 +1151,7 @@
     7.4  // Clear ICStubs of all compiled ICs
     7.5  void nmethod::clear_ic_stubs() {
     7.6    assert_locked_or_safepoint(CompiledIC_lock);
     7.7 +  ResourceMark rm;
     7.8    RelocIterator iter(this);
     7.9    while(iter.next()) {
    7.10      if (iter.type() == relocInfo::virtual_call_type) {
     8.1 --- a/src/share/vm/prims/jni.cpp	Fri Apr 28 14:03:33 2017 -0700
     8.2 +++ b/src/share/vm/prims/jni.cpp	Fri Apr 28 14:18:52 2017 -0700
     8.3 @@ -5129,6 +5129,7 @@
     8.4      run_unit_test(TestKlass_test());
     8.5      run_unit_test(Test_linked_list());
     8.6      run_unit_test(TestChunkedList_test());
     8.7 +    run_unit_test(ObjectMonitor::sanity_checks());
     8.8  #if INCLUDE_VM_STRUCTS
     8.9      run_unit_test(VMStructs::test());
    8.10  #endif
     9.1 --- a/src/share/vm/runtime/objectMonitor.cpp	Fri Apr 28 14:03:33 2017 -0700
     9.2 +++ b/src/share/vm/runtime/objectMonitor.cpp	Fri Apr 28 14:18:52 2017 -0700
     9.3 @@ -2529,6 +2529,10 @@
     9.4    SETKNOB(FastHSSEC) ;
     9.5    #undef SETKNOB
     9.6  
     9.7 +  if (Knob_Verbose) {
     9.8 +    sanity_checks();
     9.9 +  }
    9.10 +
    9.11    if (os::is_MP()) {
    9.12       BackOffMask = (1 << Knob_SpinBackOff) - 1 ;
    9.13       if (Knob_ReportSettings) ::printf ("BackOffMask=%X\n", BackOffMask) ;
    9.14 @@ -2549,6 +2553,66 @@
    9.15    InitDone = 1 ;
    9.16  }
    9.17  
    9.18 +void ObjectMonitor::sanity_checks() {
    9.19 +  int error_cnt = 0;
    9.20 +  int warning_cnt = 0;
    9.21 +  bool verbose = Knob_Verbose != 0 NOT_PRODUCT(|| VerboseInternalVMTests);
    9.22 +
    9.23 +  if (verbose) {
    9.24 +    tty->print_cr("INFO: sizeof(ObjectMonitor)=" SIZE_FORMAT,
    9.25 +                  sizeof(ObjectMonitor));
    9.26 +  }
    9.27 +
    9.28 +  uint cache_line_size = VM_Version::L1_data_cache_line_size();
    9.29 +  if (verbose) {
    9.30 +    tty->print_cr("INFO: L1_data_cache_line_size=%u", cache_line_size);
    9.31 +  }
    9.32 +
    9.33 +  ObjectMonitor dummy;
    9.34 +  u_char *addr_begin  = (u_char*)&dummy;
    9.35 +  u_char *addr_header = (u_char*)&dummy._header;
    9.36 +  u_char *addr_owner  = (u_char*)&dummy._owner;
    9.37 +
    9.38 +  uint offset_header = (uint)(addr_header - addr_begin);
    9.39 +  if (verbose) tty->print_cr("INFO: offset(_header)=%u", offset_header);
    9.40 +
    9.41 +  uint offset_owner = (uint)(addr_owner - addr_begin);
    9.42 +  if (verbose) tty->print_cr("INFO: offset(_owner)=%u", offset_owner);
    9.43 +
    9.44 +  if ((uint)(addr_header - addr_begin) != 0) {
    9.45 +    tty->print_cr("ERROR: offset(_header) must be zero (0).");
    9.46 +    error_cnt++;
    9.47 +  }
    9.48 +
    9.49 +  if (cache_line_size != 0) {
    9.50 +    // We were able to determine the L1 data cache line size so
    9.51 +    // do some cache line specific sanity checks
    9.52 +
    9.53 +    if ((offset_owner - offset_header) < cache_line_size) {
    9.54 +      tty->print_cr("WARNING: the _header and _owner fields are closer "
    9.55 +                    "than a cache line which permits false sharing.");
    9.56 +      warning_cnt++;
    9.57 +    }
    9.58 +
    9.59 +    if ((sizeof(ObjectMonitor) % cache_line_size) != 0) {
    9.60 +      tty->print_cr("WARNING: ObjectMonitor size is not a multiple of "
    9.61 +                    "a cache line which permits false sharing.");
    9.62 +      warning_cnt++;
    9.63 +    }
    9.64 +  }
    9.65 +
    9.66 +  ObjectSynchronizer::sanity_checks(verbose, cache_line_size, &error_cnt,
    9.67 +                                    &warning_cnt);
    9.68 +
    9.69 +  if (verbose || error_cnt != 0 || warning_cnt != 0) {
    9.70 +    tty->print_cr("INFO: error_cnt=%d", error_cnt);
    9.71 +    tty->print_cr("INFO: warning_cnt=%d", warning_cnt);
    9.72 +  }
    9.73 +
    9.74 +  guarantee(error_cnt == 0,
    9.75 +            "Fatal error(s) found in ObjectMonitor::sanity_checks()");
    9.76 +}
    9.77 +
    9.78  #ifndef PRODUCT
    9.79  void ObjectMonitor::verify() {
    9.80  }
    10.1 --- a/src/share/vm/runtime/objectMonitor.hpp	Fri Apr 28 14:03:33 2017 -0700
    10.2 +++ b/src/share/vm/runtime/objectMonitor.hpp	Fri Apr 28 14:18:52 2017 -0700
    10.3 @@ -189,6 +189,8 @@
    10.4    bool      check(TRAPS);       // true if the thread owns the monitor.
    10.5    void      check_slow(TRAPS);
    10.6    void      clear();
    10.7 +  static void sanity_checks();  // public for -XX:+ExecuteInternalVMTests
    10.8 +                                // in PRODUCT for -XX:SyncKnobs=Verbose=1
    10.9  #ifndef PRODUCT
   10.10    void      verify();
   10.11    void      print();
   10.12 @@ -234,8 +236,6 @@
   10.13  
   10.14    // WARNING: this must be the very first word of ObjectMonitor
   10.15    // This means this class can't use any virtual member functions.
   10.16 -  // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the
   10.17 -  // implicit 0 offset in emitted code.
   10.18  
   10.19    volatile markOop   _header;       // displaced object header word - mark
   10.20    void*     volatile _object;       // backward object pointer - strong root
    11.1 --- a/src/share/vm/runtime/sweeper.cpp	Fri Apr 28 14:03:33 2017 -0700
    11.2 +++ b/src/share/vm/runtime/sweeper.cpp	Fri Apr 28 14:18:52 2017 -0700
    11.3 @@ -319,6 +319,7 @@
    11.4  }
    11.5  
    11.6  void NMethodSweeper::sweep_code_cache() {
    11.7 +  ResourceMark rm;
    11.8    Ticks sweep_start_counter = Ticks::now();
    11.9  
   11.10    _flushed_count                = 0;
   11.11 @@ -626,6 +627,7 @@
   11.12  // state of the code cache if it's requested.
   11.13  void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
   11.14    if (PrintMethodFlushing) {
   11.15 +    ResourceMark rm;
   11.16      stringStream s;
   11.17      // Dump code cache state into a buffer before locking the tty,
   11.18      // because log_state() will use locks causing lock conflicts.
   11.19 @@ -643,6 +645,7 @@
   11.20    }
   11.21  
   11.22    if (LogCompilation && (xtty != NULL)) {
   11.23 +    ResourceMark rm;
   11.24      stringStream s;
   11.25      // Dump code cache state into a buffer before locking the tty,
   11.26      // because log_state() will use locks causing lock conflicts.
    12.1 --- a/src/share/vm/runtime/synchronizer.cpp	Fri Apr 28 14:03:33 2017 -0700
    12.2 +++ b/src/share/vm/runtime/synchronizer.cpp	Fri Apr 28 14:18:52 2017 -0700
    12.3 @@ -437,19 +437,22 @@
    12.4  // Hash Code handling
    12.5  //
    12.6  // Performance concern:
    12.7 -// OrderAccess::storestore() calls release() which STs 0 into the global volatile
    12.8 -// OrderAccess::Dummy variable.  This store is unnecessary for correctness.
    12.9 -// Many threads STing into a common location causes considerable cache migration
   12.10 -// or "sloshing" on large SMP system.  As such, I avoid using OrderAccess::storestore()
   12.11 -// until it's repaired.  In some cases OrderAccess::fence() -- which incurs local
   12.12 -// latency on the executing processor -- is a better choice as it scales on SMP
   12.13 -// systems.  See http://blogs.sun.com/dave/entry/biased_locking_in_hotspot for a
   12.14 -// discussion of coherency costs.  Note that all our current reference platforms
   12.15 -// provide strong ST-ST order, so the issue is moot on IA32, x64, and SPARC.
   12.16 +// OrderAccess::storestore() calls release() which at one time stored 0
   12.17 +// into the global volatile OrderAccess::dummy variable. This store was
   12.18 +// unnecessary for correctness. Many threads storing into a common location
   12.19 +// causes considerable cache migration or "sloshing" on large SMP systems.
   12.20 +// As such, I avoided using OrderAccess::storestore(). In some cases
   12.21 +// OrderAccess::fence() -- which incurs local latency on the executing
   12.22 +// processor -- is a better choice as it scales on SMP systems.
   12.23 +//
   12.24 +// See http://blogs.oracle.com/dave/entry/biased_locking_in_hotspot for
   12.25 +// a discussion of coherency costs. Note that all our current reference
   12.26 +// platforms provide strong ST-ST order, so the issue is moot on IA32,
   12.27 +// x64, and SPARC.
   12.28  //
   12.29  // As a general policy we use "volatile" to control compiler-based reordering
   12.30 -// and explicit fences (barriers) to control for architectural reordering performed
   12.31 -// by the CPU(s) or platform.
   12.32 +// and explicit fences (barriers) to control for architectural reordering
   12.33 +// performed by the CPU(s) or platform.
   12.34  
   12.35  struct SharedGlobals {
   12.36      // These are highly shared mostly-read variables.
   12.37 @@ -1636,7 +1639,55 @@
   12.38  }
   12.39  
   12.40  //------------------------------------------------------------------------------
   12.41 -// Non-product code
   12.42 +// Debugging code
   12.43 +
   12.44 +void ObjectSynchronizer::sanity_checks(const bool verbose,
   12.45 +                                       const uint cache_line_size,
   12.46 +                                       int *error_cnt_ptr,
   12.47 +                                       int *warning_cnt_ptr) {
   12.48 +  u_char *addr_begin      = (u_char*)&GVars;
   12.49 +  u_char *addr_stwRandom  = (u_char*)&GVars.stwRandom;
   12.50 +  u_char *addr_hcSequence = (u_char*)&GVars.hcSequence;
   12.51 +
   12.52 +  if (verbose) {
   12.53 +    tty->print_cr("INFO: sizeof(SharedGlobals)=" SIZE_FORMAT,
   12.54 +                  sizeof(SharedGlobals));
   12.55 +  }
   12.56 +
   12.57 +  uint offset_stwRandom = (uint)(addr_stwRandom - addr_begin);
   12.58 +  if (verbose) tty->print_cr("INFO: offset(stwRandom)=%u", offset_stwRandom);
   12.59 +
   12.60 +  uint offset_hcSequence = (uint)(addr_hcSequence - addr_begin);
   12.61 +  if (verbose) {
   12.62 +    tty->print_cr("INFO: offset(_hcSequence)=%u", offset_hcSequence);
   12.63 +  }
   12.64 +
   12.65 +  if (cache_line_size != 0) {
   12.66 +    // We were able to determine the L1 data cache line size so
   12.67 +    // do some cache line specific sanity checks
   12.68 +
   12.69 +    if (offset_stwRandom < cache_line_size) {
   12.70 +      tty->print_cr("WARNING: the SharedGlobals.stwRandom field is closer "
   12.71 +                    "to the struct beginning than a cache line which permits "
   12.72 +                    "false sharing.");
   12.73 +      (*warning_cnt_ptr)++;
   12.74 +    }
   12.75 +
   12.76 +    if ((offset_hcSequence - offset_stwRandom) < cache_line_size) {
   12.77 +      tty->print_cr("WARNING: the SharedGlobals.stwRandom and "
   12.78 +                    "SharedGlobals.hcSequence fields are closer than a cache "
   12.79 +                    "line which permits false sharing.");
   12.80 +      (*warning_cnt_ptr)++;
   12.81 +    }
   12.82 +
   12.83 +    if ((sizeof(SharedGlobals) - offset_hcSequence) < cache_line_size) {
   12.84 +      tty->print_cr("WARNING: the SharedGlobals.hcSequence field is closer "
   12.85 +                    "to the struct end than a cache line which permits false "
   12.86 +                    "sharing.");
   12.87 +      (*warning_cnt_ptr)++;
   12.88 +    }
   12.89 +  }
   12.90 +}
   12.91  
   12.92  #ifndef PRODUCT
   12.93  
    13.1 --- a/src/share/vm/runtime/synchronizer.hpp	Fri Apr 28 14:03:33 2017 -0700
    13.2 +++ b/src/share/vm/runtime/synchronizer.hpp	Fri Apr 28 14:18:52 2017 -0700
    13.3 @@ -121,6 +121,9 @@
    13.4    static void oops_do(OopClosure* f);
    13.5  
    13.6    // debugging
    13.7 +  static void sanity_checks(const bool verbose,
    13.8 +                            const unsigned int cache_line_size,
    13.9 +                            int *error_cnt_ptr, int *warning_cnt_ptr);
   13.10    static void verify() PRODUCT_RETURN;
   13.11    static int  verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0;
   13.12  
    14.1 --- a/src/share/vm/runtime/vm_version.cpp	Fri Apr 28 14:03:33 2017 -0700
    14.2 +++ b/src/share/vm/runtime/vm_version.cpp	Fri Apr 28 14:18:52 2017 -0700
    14.3 @@ -50,6 +50,7 @@
    14.4  bool Abstract_VM_Version::_supports_atomic_getadd4 = false;
    14.5  bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
    14.6  unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
    14.7 +unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
    14.8  int Abstract_VM_Version::_reserve_for_allocation_prefetch = 0;
    14.9  
   14.10  #ifndef HOTSPOT_RELEASE_VERSION
    15.1 --- a/src/share/vm/runtime/vm_version.hpp	Fri Apr 28 14:03:33 2017 -0700
    15.2 +++ b/src/share/vm/runtime/vm_version.hpp	Fri Apr 28 14:18:52 2017 -0700
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
    15.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.8   *
    15.9   * This code is free software; you can redistribute it and/or modify it
   15.10 @@ -42,6 +42,7 @@
   15.11    static bool         _supports_atomic_getadd4;
   15.12    static bool         _supports_atomic_getadd8;
   15.13    static unsigned int _logical_processors_per_package;
   15.14 +  static unsigned int _L1_data_cache_line_size;
   15.15    static int          _vm_major_version;
   15.16    static int          _vm_minor_version;
   15.17    static int          _vm_build_number;
   15.18 @@ -114,6 +115,10 @@
   15.19      return _logical_processors_per_package;
   15.20    }
   15.21  
   15.22 +  static unsigned int L1_data_cache_line_size() {
   15.23 +    return _L1_data_cache_line_size;
   15.24 +  }
   15.25 +
   15.26    // Need a space at the end of TLAB for prefetch instructions
   15.27    // which may fault when accessing memory outside of heap.
   15.28    static int reserve_for_allocation_prefetch() {

mercurial