Fri, 30 Jun 2017 23:56:45 -0700
Merge
.hgtags | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Mon Jun 26 14:49:58 2017 -0700 1.2 +++ b/.hgtags Fri Jun 30 23:56:45 2017 -0700 1.3 @@ -931,6 +931,8 @@ 1.4 b28d012a24cab8f4ceeee0c9d3252969757423ed jdk8u112-b15 1.5 e134dc1879b72124e478be01680b0646a2fbf585 jdk8u112-b16 1.6 87440ed4e1de7753a436f957d35555d8b4e26f1d jdk8u112-b31 1.7 +ba25f5833a128b8062e597f794efda26b30f095d jdk8u112-b32 1.8 +919ffdca10c2721ee0f6f233e704709174556510 jdk8u112-b33 1.9 3b0e5f01891f5ebbf67797b1aae786196f1bb4f6 jdk8u121-b00 1.10 251a2493b1857f2ff4f11eab2dfd8b2fe8ed441b jdk8u121-b01 1.11 70c4a50f576a01ec975d0a02b3642ee33db39ed8 jdk8u121-b02 1.12 @@ -945,6 +947,12 @@ 1.13 11f91811e4d7e5ddfaf938dcf386ec8fe5bf7b7c jdk8u121-b11 1.14 b132b08b28bf23a26329928cf6b4ffda5857f4d3 jdk8u121-b12 1.15 90f94521c3515e5f27af0ab9b31d036e88bb322a jdk8u121-b13 1.16 +351bf1d4ff9a41137f91e2ec97ec59ed29a38d8b jdk8u121-b31 1.17 +41daac438a2ac5a80755dc3de88b76e4ac66750a jdk8u121-b32 1.18 +eb9e617d6f64d4ad689feac0707b5e4335b00ce2 jdk8u121-b33 1.19 +c60b0994e8eee152666252c3ba4105db65c004db jdk8u121-b34 1.20 +0612a789929b88612509668bea4b3138613e91e4 jdk8u121-b35 1.21 +0ea269e49511a890e6fabfd468638dd1c0ed0be3 jdk8u121-b36 1.22 c0a1ba0df20fda10ddb8599e888eb56ad98b3874 jdk8u131-b00 1.23 0b85ccd6240991e1a501602ff5addec6b88ae0af jdk8u131-b01 1.24 ef90c721a4e59b01ca36f25619010a1afe9ed4d5 jdk8u131-b02 1.25 @@ -957,6 +965,10 @@ 1.26 56e71d16083904ceddfdd1d66312582a42781646 jdk8u131-b09 1.27 1da23ae49386608550596502d90a381ee6c1dfaa jdk8u131-b10 1.28 829ea9b92cda9545652f1b309f56c57383024ebb jdk8u131-b11 1.29 +41e0713bcca27cef5d6a9afd44c7ca4811937713 jdk8u131-b31 1.30 +e318654a4fa352a06935dd56eebf88ae387b31f9 jdk8u131-b32 1.31 +32998fc932dc58c6bbac185cc17d2752fa6dba4c jdk8u131-b33 1.32 +50b3fa6791f46bc582528bdc7f6311b3b6832c51 jdk8u131-b34 1.33 692bc6b674dcab72453de08ee9da0856a7e41c0f jdk8u141-b00 1.34 0cee0db0180b64655751e7058c251103f9660f85 jdk8u141-b01 1.35 82435799636c8b50a090aebcb5af49946afa7bb5 jdk8u141-b02
2.1 --- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp Mon Jun 26 14:49:58 2017 -0700 2.2 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp Fri Jun 30 23:56:45 2017 -0700 2.3 @@ -4261,6 +4261,7 @@ 2.4 assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing"); 2.5 Register end = count; 2.6 int cache_line_size = VM_Version::prefetch_data_size(); 2.7 + assert(cache_line_size > 0, "cache line size should be known for this code"); 2.8 // Minimum count when BIS zeroing can be used since 2.9 // it needs membar which is expensive. 2.10 int block_zero_size = MAX2(cache_line_size*3, (int)BlockZeroingLowLimit);
3.1 --- a/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Jun 26 14:49:58 2017 -0700 3.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Jun 30 23:56:45 2017 -0700 3.3 @@ -74,7 +74,7 @@ 3.4 AllocatePrefetchDistance = AllocatePrefetchStepSize; 3.5 } 3.6 3.7 - if (AllocatePrefetchStyle == 3 && !has_blk_init()) { 3.8 + if (AllocatePrefetchStyle == 3 && (!has_blk_init() || cache_line_size <= 0)) { 3.9 warning("BIS instructions are not available on this CPU"); 3.10 FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1); 3.11 } 3.12 @@ -138,7 +138,7 @@ 3.13 FLAG_SET_DEFAULT(InteriorEntryAlignment, 4); 3.14 } 3.15 if (is_niagara_plus()) { 3.16 - if (has_blk_init() && UseTLAB && 3.17 + if (has_blk_init() && (cache_line_size > 0) && UseTLAB && 3.18 FLAG_IS_DEFAULT(AllocatePrefetchInstr)) { 3.19 // Use BIS instruction for TLAB allocation prefetch. 3.20 FLAG_SET_ERGO(intx, AllocatePrefetchInstr, 1); 3.21 @@ -236,7 +236,7 @@ 3.22 assert((OptoLoopAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size"); 3.23 3.24 char buf[512]; 3.25 - jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 3.26 + jio_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 3.27 (has_v9() ? ", v9" : (has_v8() ? ", v8" : "")), 3.28 (has_hardware_popc() ? ", popc" : ""), 3.29 (has_vis1() ? ", vis1" : ""), 3.30 @@ -249,6 +249,7 @@ 3.31 (has_sha256() ? ", sha256" : ""), 3.32 (has_sha512() ? ", sha512" : ""), 3.33 (is_ultra3() ? ", ultra3" : ""), 3.34 + (has_sparc5_instr() ? ", sparc5" : ""), 3.35 (is_sun4v() ? ", sun4v" : ""), 3.36 (is_niagara_plus() ? ", niagara_plus" : (is_niagara() ? ", niagara" : "")), 3.37 (is_sparc64() ? ", sparc64" : ""), 3.38 @@ -364,6 +365,7 @@ 3.39 3.40 #ifndef PRODUCT 3.41 if (PrintMiscellaneous && Verbose) { 3.42 + tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); 3.43 tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size()); 3.44 tty->print("Allocation"); 3.45 if (AllocatePrefetchStyle <= 0) { 3.46 @@ -447,9 +449,10 @@ 3.47 3.48 unsigned int VM_Version::calc_parallel_worker_threads() { 3.49 unsigned int result; 3.50 - if (is_M_series()) { 3.51 - // for now, use same gc thread calculation for M-series as for niagara-plus 3.52 - // in future, we may want to tweak parameters for nof_parallel_worker_thread 3.53 + if (is_M_series() || is_S_series()) { 3.54 + // for now, use same gc thread calculation for M-series and S-series as for 3.55 + // niagara-plus. In future, we may want to tweak parameters for 3.56 + // nof_parallel_worker_thread 3.57 result = nof_parallel_worker_threads(5, 16, 8); 3.58 } else if (is_niagara_plus()) { 3.59 result = nof_parallel_worker_threads(5, 16, 8); 3.60 @@ -458,3 +461,37 @@ 3.61 } 3.62 return result; 3.63 } 3.64 + 3.65 + 3.66 +int VM_Version::parse_features(const char* implementation) { 3.67 + int features = unknown_m; 3.68 + // Convert to UPPER case before compare. 3.69 + char* impl = os::strdup(implementation); 3.70 + 3.71 + for (int i = 0; impl[i] != 0; i++) 3.72 + impl[i] = (char)toupper((uint)impl[i]); 3.73 + 3.74 + if (strstr(impl, "SPARC64") != NULL) { 3.75 + features |= sparc64_family_m; 3.76 + } else if (strstr(impl, "SPARC-M") != NULL) { 3.77 + // M-series SPARC is based on T-series. 3.78 + features |= (M_family_m | T_family_m); 3.79 + } else if (strstr(impl, "SPARC-S") != NULL) { 3.80 + // S-series SPARC is based on T-series. 3.81 + features |= (S_family_m | T_family_m); 3.82 + } else if (strstr(impl, "SPARC-T") != NULL) { 3.83 + features |= T_family_m; 3.84 + if (strstr(impl, "SPARC-T1") != NULL) { 3.85 + features |= T1_model_m; 3.86 + } 3.87 + } else if (strstr(impl, "SUN4V-CPU") != NULL) { 3.88 + // Generic or migration class LDOM 3.89 + features |= T_family_m; 3.90 + } else { 3.91 +#ifndef PRODUCT 3.92 + warning("Failed to parse CPU implementation = '%s'", impl); 3.93 +#endif 3.94 + } 3.95 + os::free((void*)impl); 3.96 + return features; 3.97 +}
4.1 --- a/src/cpu/sparc/vm/vm_version_sparc.hpp Mon Jun 26 14:49:58 2017 -0700 4.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp Fri Jun 30 23:56:45 2017 -0700 4.3 @@ -47,13 +47,14 @@ 4.4 cbcond_instructions = 13, 4.5 sparc64_family = 14, 4.6 M_family = 15, 4.7 - T_family = 16, 4.8 - T1_model = 17, 4.9 - sparc5_instructions = 18, 4.10 - aes_instructions = 19, 4.11 - sha1_instruction = 20, 4.12 - sha256_instruction = 21, 4.13 - sha512_instruction = 22 4.14 + S_family = 16, 4.15 + T_family = 17, 4.16 + T1_model = 18, 4.17 + sparc5_instructions = 19, 4.18 + aes_instructions = 20, 4.19 + sha1_instruction = 21, 4.20 + sha256_instruction = 22, 4.21 + sha512_instruction = 23 4.22 }; 4.23 4.24 enum Feature_Flag_Set { 4.25 @@ -76,6 +77,7 @@ 4.26 cbcond_instructions_m = 1 << cbcond_instructions, 4.27 sparc64_family_m = 1 << sparc64_family, 4.28 M_family_m = 1 << M_family, 4.29 + S_family_m = 1 << S_family, 4.30 T_family_m = 1 << T_family, 4.31 T1_model_m = 1 << T1_model, 4.32 sparc5_instructions_m = 1 << sparc5_instructions, 4.33 @@ -105,6 +107,7 @@ 4.34 4.35 // Returns true if the platform is in the niagara line (T series) 4.36 static bool is_M_family(int features) { return (features & M_family_m) != 0; } 4.37 + static bool is_S_family(int features) { return (features & S_family_m) != 0; } 4.38 static bool is_T_family(int features) { return (features & T_family_m) != 0; } 4.39 static bool is_niagara() { return is_T_family(_features); } 4.40 #ifdef ASSERT 4.41 @@ -119,7 +122,7 @@ 4.42 static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); } 4.43 4.44 static int maximum_niagara1_processor_count() { return 32; } 4.45 - 4.46 + static int parse_features(const char* implementation); 4.47 public: 4.48 // Initialization 4.49 static void initialize(); 4.50 @@ -152,6 +155,7 @@ 4.51 static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); } 4.52 4.53 static bool is_M_series() { return is_M_family(_features); } 4.54 + static bool is_S_series() { return is_S_family(_features); } 4.55 static bool is_T4() { return is_T_family(_features) && has_cbcond(); } 4.56 static bool is_T7() { return is_T_family(_features) && has_sparc5_instr(); } 4.57
5.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp Mon Jun 26 14:49:58 2017 -0700 5.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Fri Jun 30 23:56:45 2017 -0700 5.3 @@ -406,6 +406,8 @@ 5.4 _stepping = 0; 5.5 _cpuFeatures = 0; 5.6 _logical_processors_per_package = 1; 5.7 + // i486 internal cache is both I&D and has a 16-byte line size 5.8 + _L1_data_cache_line_size = 16; 5.9 5.10 if (!Use486InstrsOnly) { 5.11 // Get raw processor info 5.12 @@ -424,6 +426,7 @@ 5.13 // Logical processors are only available on P4s and above, 5.14 // and only if hyperthreading is available. 5.15 _logical_processors_per_package = logical_processor_count(); 5.16 + _L1_data_cache_line_size = L1_line_size(); 5.17 } 5.18 } 5.19 5.20 @@ -1034,6 +1037,7 @@ 5.21 if (PrintMiscellaneous && Verbose) { 5.22 tty->print_cr("Logical CPUs per core: %u", 5.23 logical_processors_per_package()); 5.24 + tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); 5.25 tty->print("UseSSE=%d", (int) UseSSE); 5.26 if (UseAVX > 0) { 5.27 tty->print(" UseAVX=%d", (int) UseAVX);
6.1 --- a/src/cpu/x86/vm/vm_version_x86.hpp Mon Jun 26 14:49:58 2017 -0700 6.2 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Fri Jun 30 23:56:45 2017 -0700 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -595,7 +595,7 @@ 6.11 return (result == 0 ? 1 : result); 6.12 } 6.13 6.14 - static intx prefetch_data_size() { 6.15 + static intx L1_line_size() { 6.16 intx result = 0; 6.17 if (is_intel()) { 6.18 result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); 6.19 @@ -607,6 +607,10 @@ 6.20 return result; 6.21 } 6.22 6.23 + static intx prefetch_data_size() { 6.24 + return L1_line_size(); 6.25 + } 6.26 + 6.27 // 6.28 // Feature identification 6.29 //
7.1 --- a/src/os/linux/vm/os_linux.cpp Mon Jun 26 14:49:58 2017 -0700 7.2 +++ b/src/os/linux/vm/os_linux.cpp Fri Jun 30 23:56:45 2017 -0700 7.3 @@ -2859,7 +2859,7 @@ 7.4 // in the library. 7.5 const size_t BitsPerCLong = sizeof(long) * CHAR_BIT; 7.6 7.7 - size_t cpu_num = os::active_processor_count(); 7.8 + size_t cpu_num = processor_count(); 7.9 size_t cpu_map_size = NCPUS / BitsPerCLong; 7.10 size_t cpu_map_valid_size = 7.11 MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
8.1 --- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Mon Jun 26 14:49:58 2017 -0700 8.2 +++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Fri Jun 30 23:56:45 2017 -0700 8.3 @@ -262,6 +262,7 @@ 8.4 8.5 // We need to keep these here as long as we have to build on Solaris 8.6 // versions before 10. 8.7 + 8.8 #ifndef SI_ARCHITECTURE_32 8.9 #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ 8.10 #endif 8.11 @@ -270,231 +271,233 @@ 8.12 #define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */ 8.13 #endif 8.14 8.15 -static void do_sysinfo(int si, const char* string, int* features, int mask) { 8.16 - char tmp; 8.17 - size_t bufsize = sysinfo(si, &tmp, 1); 8.18 +#ifndef SI_CPUBRAND 8.19 +#define SI_CPUBRAND 523 /* return cpu brand string */ 8.20 +#endif 8.21 8.22 - // All SI defines used below must be supported. 8.23 - guarantee(bufsize != -1, "must be supported"); 8.24 +class Sysinfo { 8.25 + char* _string; 8.26 +public: 8.27 + Sysinfo(int si) : _string(NULL) { 8.28 + char tmp; 8.29 + size_t bufsize = sysinfo(si, &tmp, 1); 8.30 8.31 - char* buf = (char*) malloc(bufsize); 8.32 + if (bufsize != -1) { 8.33 + char* buf = (char*) os::malloc(bufsize, mtInternal); 8.34 + if (buf != NULL) { 8.35 + if (sysinfo(si, buf, bufsize) == bufsize) { 8.36 + _string = buf; 8.37 + } else { 8.38 + os::free(buf); 8.39 + } 8.40 + } 8.41 + } 8.42 + } 8.43 8.44 - if (buf == NULL) 8.45 - return; 8.46 - 8.47 - if (sysinfo(si, buf, bufsize) == bufsize) { 8.48 - // Compare the string. 8.49 - if (strcmp(buf, string) == 0) { 8.50 - *features |= mask; 8.51 + ~Sysinfo() { 8.52 + if (_string != NULL) { 8.53 + os::free(_string); 8.54 } 8.55 } 8.56 8.57 - free(buf); 8.58 -} 8.59 + const char* value() const { 8.60 + return _string; 8.61 + } 8.62 + 8.63 + bool valid() const { 8.64 + return _string != NULL; 8.65 + } 8.66 + 8.67 + bool match(const char* s) const { 8.68 + return valid() ? strcmp(_string, s) == 0 : false; 8.69 + } 8.70 + 8.71 + bool match_substring(const char* s) const { 8.72 + return valid() ? strstr(_string, s) != NULL : false; 8.73 + } 8.74 +}; 8.75 + 8.76 +class Sysconf { 8.77 + int _value; 8.78 +public: 8.79 + Sysconf(int sc) : _value(-1) { 8.80 + _value = sysconf(sc); 8.81 + } 8.82 + bool valid() const { 8.83 + return _value != -1; 8.84 + } 8.85 + int value() const { 8.86 + return _value; 8.87 + } 8.88 +}; 8.89 + 8.90 + 8.91 +#ifndef _SC_DCACHE_LINESZ 8.92 +#define _SC_DCACHE_LINESZ 508 /* Data cache line size */ 8.93 +#endif 8.94 + 8.95 +#ifndef _SC_L2CACHE_LINESZ 8.96 +#define _SC_L2CACHE_LINESZ 527 /* Size of L2 cache line */ 8.97 +#endif 8.98 + 8.99 8.100 int VM_Version::platform_features(int features) { 8.101 - // getisax(2), SI_ARCHITECTURE_32, and SI_ARCHITECTURE_64 are 8.102 - // supported on Solaris 10 and later. 8.103 - if (os::Solaris::supports_getisax()) { 8.104 + assert(os::Solaris::supports_getisax(), "getisax() must be available"); 8.105 8.106 - // Check 32-bit architecture. 8.107 - do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m); 8.108 + // Check 32-bit architecture. 8.109 + if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) { 8.110 + features |= v8_instructions_m; 8.111 + } 8.112 8.113 - // Check 64-bit architecture. 8.114 - do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m); 8.115 + // Check 64-bit architecture. 8.116 + if (Sysinfo(SI_ARCHITECTURE_64).match("sparcv9")) { 8.117 + features |= generic_v9_m; 8.118 + } 8.119 8.120 - // Extract valid instruction set extensions. 8.121 - uint_t avs[2]; 8.122 - uint_t avn = os::Solaris::getisax(avs, 2); 8.123 - assert(avn <= 2, "should return two or less av's"); 8.124 - uint_t av = avs[0]; 8.125 + // Extract valid instruction set extensions. 8.126 + uint_t avs[2]; 8.127 + uint_t avn = os::Solaris::getisax(avs, 2); 8.128 + assert(avn <= 2, "should return two or less av's"); 8.129 + uint_t av = avs[0]; 8.130 8.131 #ifndef PRODUCT 8.132 - if (PrintMiscellaneous && Verbose) { 8.133 - tty->print("getisax(2) returned: " PTR32_FORMAT, av); 8.134 - if (avn > 1) { 8.135 - tty->print(", " PTR32_FORMAT, avs[1]); 8.136 - } 8.137 - tty->cr(); 8.138 + if (PrintMiscellaneous && Verbose) { 8.139 + tty->print("getisax(2) returned: " PTR32_FORMAT, av); 8.140 + if (avn > 1) { 8.141 + tty->print(", " PTR32_FORMAT, avs[1]); 8.142 } 8.143 + tty->cr(); 8.144 + } 8.145 #endif 8.146 8.147 - if (av & AV_SPARC_MUL32) features |= hardware_mul32_m; 8.148 - if (av & AV_SPARC_DIV32) features |= hardware_div32_m; 8.149 - if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m; 8.150 - if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m; 8.151 - if (av & AV_SPARC_POPC) features |= hardware_popc_m; 8.152 - if (av & AV_SPARC_VIS) features |= vis1_instructions_m; 8.153 - if (av & AV_SPARC_VIS2) features |= vis2_instructions_m; 8.154 - if (avn > 1) { 8.155 - uint_t av2 = avs[1]; 8.156 + if (av & AV_SPARC_MUL32) features |= hardware_mul32_m; 8.157 + if (av & AV_SPARC_DIV32) features |= hardware_div32_m; 8.158 + if (av & AV_SPARC_FSMULD) features |= hardware_fsmuld_m; 8.159 + if (av & AV_SPARC_V8PLUS) features |= v9_instructions_m; 8.160 + if (av & AV_SPARC_POPC) features |= hardware_popc_m; 8.161 + if (av & AV_SPARC_VIS) features |= vis1_instructions_m; 8.162 + if (av & AV_SPARC_VIS2) features |= vis2_instructions_m; 8.163 + if (avn > 1) { 8.164 + uint_t av2 = avs[1]; 8.165 #ifndef AV2_SPARC_SPARC5 8.166 #define AV2_SPARC_SPARC5 0x00000008 /* The 29 new fp and sub instructions */ 8.167 #endif 8.168 - if (av2 & AV2_SPARC_SPARC5) features |= sparc5_instructions_m; 8.169 - } 8.170 + if (av2 & AV2_SPARC_SPARC5) features |= sparc5_instructions_m; 8.171 + } 8.172 8.173 - // Next values are not defined before Solaris 10 8.174 - // but Solaris 8 is used for jdk6 update builds. 8.175 + // We only build on Solaris 10 and up, but some of the values below 8.176 + // are not defined on all versions of Solaris 10, so we define them, 8.177 + // if necessary. 8.178 #ifndef AV_SPARC_ASI_BLK_INIT 8.179 #define AV_SPARC_ASI_BLK_INIT 0x0080 /* ASI_BLK_INIT_xxx ASI */ 8.180 #endif 8.181 - if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m; 8.182 + if (av & AV_SPARC_ASI_BLK_INIT) features |= blk_init_instructions_m; 8.183 8.184 #ifndef AV_SPARC_FMAF 8.185 #define AV_SPARC_FMAF 0x0100 /* Fused Multiply-Add */ 8.186 #endif 8.187 - if (av & AV_SPARC_FMAF) features |= fmaf_instructions_m; 8.188 + if (av & AV_SPARC_FMAF) features |= fmaf_instructions_m; 8.189 8.190 #ifndef AV_SPARC_FMAU 8.191 -#define AV_SPARC_FMAU 0x0200 /* Unfused Multiply-Add */ 8.192 +#define AV_SPARC_FMAU 0x0200 /* Unfused Multiply-Add */ 8.193 #endif 8.194 - if (av & AV_SPARC_FMAU) features |= fmau_instructions_m; 8.195 + if (av & AV_SPARC_FMAU) features |= fmau_instructions_m; 8.196 8.197 #ifndef AV_SPARC_VIS3 8.198 -#define AV_SPARC_VIS3 0x0400 /* VIS3 instruction set extensions */ 8.199 +#define AV_SPARC_VIS3 0x0400 /* VIS3 instruction set extensions */ 8.200 #endif 8.201 - if (av & AV_SPARC_VIS3) features |= vis3_instructions_m; 8.202 + if (av & AV_SPARC_VIS3) features |= vis3_instructions_m; 8.203 8.204 #ifndef AV_SPARC_CBCOND 8.205 #define AV_SPARC_CBCOND 0x10000000 /* compare and branch instrs supported */ 8.206 #endif 8.207 - if (av & AV_SPARC_CBCOND) features |= cbcond_instructions_m; 8.208 + if (av & AV_SPARC_CBCOND) features |= cbcond_instructions_m; 8.209 8.210 #ifndef AV_SPARC_AES 8.211 #define AV_SPARC_AES 0x00020000 /* aes instrs supported */ 8.212 #endif 8.213 - if (av & AV_SPARC_AES) features |= aes_instructions_m; 8.214 + if (av & AV_SPARC_AES) features |= aes_instructions_m; 8.215 8.216 #ifndef AV_SPARC_SHA1 8.217 #define AV_SPARC_SHA1 0x00400000 /* sha1 instruction supported */ 8.218 #endif 8.219 - if (av & AV_SPARC_SHA1) features |= sha1_instruction_m; 8.220 + if (av & AV_SPARC_SHA1) features |= sha1_instruction_m; 8.221 8.222 #ifndef AV_SPARC_SHA256 8.223 #define AV_SPARC_SHA256 0x00800000 /* sha256 instruction supported */ 8.224 #endif 8.225 - if (av & AV_SPARC_SHA256) features |= sha256_instruction_m; 8.226 + if (av & AV_SPARC_SHA256) features |= sha256_instruction_m; 8.227 8.228 #ifndef AV_SPARC_SHA512 8.229 #define AV_SPARC_SHA512 0x01000000 /* sha512 instruction supported */ 8.230 #endif 8.231 - if (av & AV_SPARC_SHA512) features |= sha512_instruction_m; 8.232 + if (av & AV_SPARC_SHA512) features |= sha512_instruction_m; 8.233 8.234 + // Determine the machine type. 8.235 + if (Sysinfo(SI_MACHINE).match("sun4v")) { 8.236 + features |= sun4v_m; 8.237 + } 8.238 + 8.239 + // If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes 8.240 + // is available to us as well 8.241 + Sysinfo cpu_info(SI_CPUBRAND); 8.242 + bool use_solaris_12_api = cpu_info.valid(); 8.243 + const char* impl; 8.244 + int impl_m = 0; 8.245 + if (use_solaris_12_api) { 8.246 + impl = cpu_info.value(); 8.247 +#ifndef PRODUCT 8.248 + if (PrintMiscellaneous && Verbose) { 8.249 + tty->print_cr("Parsing CPU implementation from %s", impl); 8.250 + } 8.251 +#endif 8.252 + impl_m = parse_features(impl); 8.253 } else { 8.254 - // getisax(2) failed, use the old legacy code. 8.255 + // Otherwise use kstat to determine the machine type. 8.256 + kstat_ctl_t* kc = kstat_open(); 8.257 + if (kc != NULL) { 8.258 + kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL); 8.259 + if (ksp != NULL) { 8.260 + if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) { 8.261 + kstat_named_t* knm = (kstat_named_t *)ksp->ks_data; 8.262 + for (int i = 0; i < ksp->ks_ndata; i++) { 8.263 + if (strcmp((const char*)&(knm[i].name), "implementation") == 0) { 8.264 + impl = KSTAT_NAMED_STR_PTR(&knm[i]); 8.265 #ifndef PRODUCT 8.266 - if (PrintMiscellaneous && Verbose) 8.267 - tty->print_cr("getisax(2) is not supported."); 8.268 + if (PrintMiscellaneous && Verbose) { 8.269 + tty->print_cr("Parsing CPU implementation from %s", impl); 8.270 + } 8.271 #endif 8.272 - 8.273 - char tmp; 8.274 - size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1); 8.275 - char* buf = (char*) malloc(bufsize); 8.276 - 8.277 - if (buf != NULL) { 8.278 - if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) { 8.279 - // Figure out what kind of sparc we have 8.280 - char *sparc_string = strstr(buf, "sparc"); 8.281 - if (sparc_string != NULL) { features |= v8_instructions_m; 8.282 - if (sparc_string[5] == 'v') { 8.283 - if (sparc_string[6] == '8') { 8.284 - if (sparc_string[7] == '-') { features |= hardware_mul32_m; 8.285 - features |= hardware_div32_m; 8.286 - } else if (sparc_string[7] == 'p') features |= generic_v9_m; 8.287 - else features |= generic_v8_m; 8.288 - } else if (sparc_string[6] == '9') features |= generic_v9_m; 8.289 + impl_m = parse_features(impl); 8.290 + break; 8.291 + } 8.292 } 8.293 } 8.294 - 8.295 - // Check for visualization instructions 8.296 - char *vis = strstr(buf, "vis"); 8.297 - if (vis != NULL) { features |= vis1_instructions_m; 8.298 - if (vis[3] == '2') features |= vis2_instructions_m; 8.299 - } 8.300 } 8.301 - free(buf); 8.302 + kstat_close(kc); 8.303 } 8.304 } 8.305 + assert(impl_m != 0, err_msg("Unknown CPU implementation %s", impl)); 8.306 + features |= impl_m; 8.307 8.308 - // Determine the machine type. 8.309 - do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m); 8.310 + bool is_sun4v = (features & sun4v_m) != 0; 8.311 + if (use_solaris_12_api && is_sun4v) { 8.312 + // If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes 8.313 + Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ); 8.314 + if (l1_dcache_line_size.valid()) { 8.315 + _L1_data_cache_line_size = l1_dcache_line_size.value(); 8.316 + } 8.317 8.318 - { 8.319 - // Using kstat to determine the machine type. 8.320 - kstat_ctl_t* kc = kstat_open(); 8.321 - kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL); 8.322 - const char* implementation = "UNKNOWN"; 8.323 - if (ksp != NULL) { 8.324 - if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) { 8.325 - kstat_named_t* knm = (kstat_named_t *)ksp->ks_data; 8.326 - for (int i = 0; i < ksp->ks_ndata; i++) { 8.327 - if (strcmp((const char*)&(knm[i].name),"implementation") == 0) { 8.328 -#ifndef KSTAT_DATA_STRING 8.329 -#define KSTAT_DATA_STRING 9 8.330 -#endif 8.331 - if (knm[i].data_type == KSTAT_DATA_CHAR) { 8.332 - // VM is running on Solaris 8 which does not have value.str. 8.333 - implementation = &(knm[i].value.c[0]); 8.334 - } else if (knm[i].data_type == KSTAT_DATA_STRING) { 8.335 - // VM is running on Solaris 10. 8.336 -#ifndef KSTAT_NAMED_STR_PTR 8.337 - // Solaris 8 was used to build VM, define the structure it misses. 8.338 - struct str_t { 8.339 - union { 8.340 - char *ptr; /* NULL-term string */ 8.341 - char __pad[8]; /* 64-bit padding */ 8.342 - } addr; 8.343 - uint32_t len; /* # bytes for strlen + '\0' */ 8.344 - }; 8.345 -#define KSTAT_NAMED_STR_PTR(knptr) (( (str_t*)&((knptr)->value) )->addr.ptr) 8.346 -#endif 8.347 - implementation = KSTAT_NAMED_STR_PTR(&knm[i]); 8.348 - } 8.349 -#ifndef PRODUCT 8.350 - if (PrintMiscellaneous && Verbose) { 8.351 - tty->print_cr("cpu_info.implementation: %s", implementation); 8.352 - } 8.353 -#endif 8.354 - // Convert to UPPER case before compare. 8.355 - char* impl = strdup(implementation); 8.356 - 8.357 - for (int i = 0; impl[i] != 0; i++) 8.358 - impl[i] = (char)toupper((uint)impl[i]); 8.359 - if (strstr(impl, "SPARC64") != NULL) { 8.360 - features |= sparc64_family_m; 8.361 - } else if (strstr(impl, "SPARC-M") != NULL) { 8.362 - // M-series SPARC is based on T-series. 8.363 - features |= (M_family_m | T_family_m); 8.364 - } else if (strstr(impl, "SPARC-T") != NULL) { 8.365 - features |= T_family_m; 8.366 - if (strstr(impl, "SPARC-T1") != NULL) { 8.367 - features |= T1_model_m; 8.368 - } 8.369 - } else { 8.370 - if (strstr(impl, "SPARC") == NULL) { 8.371 -#ifndef PRODUCT 8.372 - // kstat on Solaris 8 virtual machines (branded zones) 8.373 - // returns "(unsupported)" implementation. 8.374 - warning("kstat cpu_info implementation = '%s', should contain SPARC", impl); 8.375 -#endif 8.376 - implementation = "SPARC"; 8.377 - } 8.378 - } 8.379 - free((void*)impl); 8.380 - break; 8.381 - } 8.382 - } // for( 8.383 - } 8.384 + Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ); 8.385 + if (l2_dcache_line_size.valid()) { 8.386 + _L2_data_cache_line_size = l2_dcache_line_size.value(); 8.387 } 8.388 - assert(strcmp(implementation, "UNKNOWN") != 0, 8.389 - "unknown cpu info (changed kstat interface?)"); 8.390 - kstat_close(kc); 8.391 + } else { 8.392 + // Otherwise figure out the cache line sizes using PICL 8.393 + bool is_fujitsu = (features & sparc64_family_m) != 0; 8.394 + PICL picl(is_fujitsu, is_sun4v); 8.395 + _L1_data_cache_line_size = picl.L1_data_cache_line_size(); 8.396 + _L2_data_cache_line_size = picl.L2_data_cache_line_size(); 8.397 } 8.398 - 8.399 - // Figure out cache line sizes using PICL 8.400 - PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0); 8.401 - _L2_data_cache_line_size = picl.L2_data_cache_line_size(); 8.402 - 8.403 return features; 8.404 }
9.1 --- a/src/share/vm/classfile/classLoaderData.cpp Mon Jun 26 14:49:58 2017 -0700 9.2 +++ b/src/share/vm/classfile/classLoaderData.cpp Fri Jun 30 23:56:45 2017 -0700 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -78,7 +78,7 @@ 9.11 // The null-class-loader should always be kept alive. 9.12 _keep_alive(is_anonymous || h_class_loader.is_null()), 9.13 _metaspace(NULL), _unloading(false), _klasses(NULL), 9.14 - _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), 9.15 + _claimed(0), _jmethod_ids(NULL), _handles(), _deallocate_list(NULL), 9.16 _next(NULL), _dependencies(dependencies), 9.17 _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { 9.18 // empty 9.19 @@ -96,6 +96,45 @@ 9.20 _list_head = oopFactory::new_objectArray(2, CHECK); 9.21 } 9.22 9.23 +ClassLoaderData::ChunkedHandleList::~ChunkedHandleList() { 9.24 + Chunk* c = _head; 9.25 + while (c != NULL) { 9.26 + Chunk* next = c->_next; 9.27 + delete c; 9.28 + c = next; 9.29 + } 9.30 +} 9.31 + 9.32 +oop* ClassLoaderData::ChunkedHandleList::add(oop o) { 9.33 + if (_head == NULL || _head->_size == Chunk::CAPACITY) { 9.34 + Chunk* next = new Chunk(_head); 9.35 + OrderAccess::release_store_ptr(&_head, next); 9.36 + } 9.37 + oop* handle = &_head->_data[_head->_size]; 9.38 + *handle = o; 9.39 + OrderAccess::release_store(&_head->_size, _head->_size + 1); 9.40 + return handle; 9.41 +} 9.42 + 9.43 +inline void ClassLoaderData::ChunkedHandleList::oops_do_chunk(OopClosure* f, Chunk* c, const juint size) { 9.44 + for (juint i = 0; i < size; i++) { 9.45 + if (c->_data[i] != NULL) { 9.46 + f->do_oop(&c->_data[i]); 9.47 + } 9.48 + } 9.49 +} 9.50 + 9.51 +void ClassLoaderData::ChunkedHandleList::oops_do(OopClosure* f) { 9.52 + Chunk* head = (Chunk*) OrderAccess::load_ptr_acquire(&_head); 9.53 + if (head != NULL) { 9.54 + // Must be careful when reading size of head 9.55 + oops_do_chunk(f, head, OrderAccess::load_acquire(&head->_size)); 9.56 + for (Chunk* c = head->_next; c != NULL; c = c->_next) { 9.57 + oops_do_chunk(f, c, c->_size); 9.58 + } 9.59 + } 9.60 +} 9.61 + 9.62 bool ClassLoaderData::claim() { 9.63 if (_claimed == 1) { 9.64 return false; 9.65 @@ -111,7 +150,7 @@ 9.66 9.67 f->do_oop(&_class_loader); 9.68 _dependencies.oops_do(f); 9.69 - _handles->oops_do(f); 9.70 + _handles.oops_do(f); 9.71 if (klass_closure != NULL) { 9.72 classes_do(klass_closure); 9.73 } 9.74 @@ -342,11 +381,6 @@ 9.75 _metaspace = NULL; 9.76 // release the metaspace 9.77 delete m; 9.78 - // release the handles 9.79 - if (_handles != NULL) { 9.80 - JNIHandleBlock::release_block(_handles); 9.81 - _handles = NULL; 9.82 - } 9.83 } 9.84 9.85 // Clear all the JNI handles for methods 9.86 @@ -406,15 +440,9 @@ 9.87 return _metaspace; 9.88 } 9.89 9.90 -JNIHandleBlock* ClassLoaderData::handles() const { return _handles; } 9.91 -void ClassLoaderData::set_handles(JNIHandleBlock* handles) { _handles = handles; } 9.92 - 9.93 jobject ClassLoaderData::add_handle(Handle h) { 9.94 MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); 9.95 - if (handles() == NULL) { 9.96 - set_handles(JNIHandleBlock::allocate_block()); 9.97 - } 9.98 - return handles()->allocate_handle(h()); 9.99 + return (jobject) _handles.add(h()); 9.100 } 9.101 9.102 // Add this metadata pointer to be freed when it's safe. This is only during 9.103 @@ -479,7 +507,6 @@ 9.104 p2i(class_loader() != NULL ? class_loader()->klass() : NULL), loader_name()); 9.105 if (claimed()) out->print(" claimed "); 9.106 if (is_unloading()) out->print(" unloading "); 9.107 - out->print(" handles " INTPTR_FORMAT, p2i(handles())); 9.108 out->cr(); 9.109 if (metaspace_or_null() != NULL) { 9.110 out->print_cr("metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null()));
10.1 --- a/src/share/vm/classfile/classLoaderData.hpp Mon Jun 26 14:49:58 2017 -0700 10.2 +++ b/src/share/vm/classfile/classLoaderData.hpp Fri Jun 30 23:56:45 2017 -0700 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -51,7 +51,6 @@ 10.11 10.12 class ClassLoaderData; 10.13 class JNIMethodBlock; 10.14 -class JNIHandleBlock; 10.15 class Metadebug; 10.16 10.17 // GC root for walking class loader data created 10.18 @@ -145,6 +144,31 @@ 10.19 void oops_do(OopClosure* f); 10.20 }; 10.21 10.22 + class ChunkedHandleList VALUE_OBJ_CLASS_SPEC { 10.23 + struct Chunk : public CHeapObj<mtClass> { 10.24 + static const size_t CAPACITY = 32; 10.25 + 10.26 + oop _data[CAPACITY]; 10.27 + volatile juint _size; 10.28 + Chunk* _next; 10.29 + 10.30 + Chunk(Chunk* c) : _next(c), _size(0) { } 10.31 + }; 10.32 + 10.33 + Chunk* _head; 10.34 + 10.35 + void oops_do_chunk(OopClosure* f, Chunk* c, const juint size); 10.36 + 10.37 + public: 10.38 + ChunkedHandleList() : _head(NULL) {} 10.39 + ~ChunkedHandleList(); 10.40 + 10.41 + // Only one thread at a time can add, guarded by ClassLoaderData::metaspace_lock(). 10.42 + // However, multiple threads can execute oops_do concurrently with add. 10.43 + oop* add(oop o); 10.44 + void oops_do(OopClosure* f); 10.45 + }; 10.46 + 10.47 friend class ClassLoaderDataGraph; 10.48 friend class ClassLoaderDataGraphKlassIteratorAtomic; 10.49 friend class ClassLoaderDataGraphMetaspaceIterator; 10.50 @@ -169,7 +193,8 @@ 10.51 // Has to be an int because we cas it. 10.52 Klass* _klasses; // The classes defined by the class loader. 10.53 10.54 - JNIHandleBlock* _handles; // Handles to constant pool arrays 10.55 + ChunkedHandleList _handles; // Handles to constant pool arrays, etc, which 10.56 + // have the same life cycle of the corresponding ClassLoader. 10.57 10.58 // These method IDs are created for the class loader and set to NULL when the 10.59 // class loader is unloaded. They are rarely freed, only for redefine classes 10.60 @@ -196,9 +221,6 @@ 10.61 10.62 void set_metaspace(Metaspace* m) { _metaspace = m; } 10.63 10.64 - JNIHandleBlock* handles() const; 10.65 - void set_handles(JNIHandleBlock* handles); 10.66 - 10.67 Mutex* metaspace_lock() const { return _metaspace_lock; } 10.68 10.69 // GC interface.
11.1 --- a/src/share/vm/classfile/javaClasses.cpp Mon Jun 26 14:49:58 2017 -0700 11.2 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Jun 30 23:56:45 2017 -0700 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -2852,6 +2852,15 @@ 11.11 mname->address_field_put(_vmindex_offset, (address) index); 11.12 } 11.13 11.14 +bool java_lang_invoke_MemberName::equals(oop mn1, oop mn2) { 11.15 + if (mn1 == mn2) { 11.16 + return true; 11.17 + } 11.18 + return (vmtarget(mn1) == vmtarget(mn2) && flags(mn1) == flags(mn2) && 11.19 + vmindex(mn1) == vmindex(mn2) && 11.20 + clazz(mn1) == clazz(mn2)); 11.21 +} 11.22 + 11.23 oop java_lang_invoke_LambdaForm::vmentry(oop lform) { 11.24 assert(is_instance(lform), "wrong type"); 11.25 return lform->obj_field(_vmentry_offset);
12.1 --- a/src/share/vm/classfile/javaClasses.hpp Mon Jun 26 14:49:58 2017 -0700 12.2 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Jun 30 23:56:45 2017 -0700 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -1132,6 +1132,8 @@ 12.11 static int flags_offset_in_bytes() { return _flags_offset; } 12.12 static int vmtarget_offset_in_bytes() { return _vmtarget_offset; } 12.13 static int vmindex_offset_in_bytes() { return _vmindex_offset; } 12.14 + 12.15 + static bool equals(oop mt1, oop mt2); 12.16 }; 12.17 12.18
13.1 --- a/src/share/vm/classfile/systemDictionary.cpp Mon Jun 26 14:49:58 2017 -0700 13.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Jun 30 23:56:45 2017 -0700 13.3 @@ -1084,15 +1084,18 @@ 13.4 THREAD); 13.5 13.6 const char* pkg = "java/"; 13.7 + size_t pkglen = strlen(pkg); 13.8 if (!HAS_PENDING_EXCEPTION && 13.9 !class_loader.is_null() && 13.10 parsed_name != NULL && 13.11 - !strncmp((const char*)parsed_name->bytes(), pkg, strlen(pkg))) { 13.12 + parsed_name->utf8_length() >= (int)pkglen && 13.13 + !strncmp((const char*)parsed_name->bytes(), pkg, pkglen)) { 13.14 // It is illegal to define classes in the "java." package from 13.15 // JVM_DefineClass or jni_DefineClass unless you're the bootclassloader 13.16 ResourceMark rm(THREAD); 13.17 char* name = parsed_name->as_C_string(); 13.18 char* index = strrchr(name, '/'); 13.19 + assert(index != NULL, "must be"); 13.20 *index = '\0'; // chop to just the package name 13.21 while ((index = strchr(name, '/')) != NULL) { 13.22 *index = '.'; // replace '/' with '.' in package name
14.1 --- a/src/share/vm/code/nmethod.cpp Mon Jun 26 14:49:58 2017 -0700 14.2 +++ b/src/share/vm/code/nmethod.cpp Fri Jun 30 23:56:45 2017 -0700 14.3 @@ -1151,6 +1151,7 @@ 14.4 // Clear ICStubs of all compiled ICs 14.5 void nmethod::clear_ic_stubs() { 14.6 assert_locked_or_safepoint(CompiledIC_lock); 14.7 + ResourceMark rm; 14.8 RelocIterator iter(this); 14.9 while(iter.next()) { 14.10 if (iter.type() == relocInfo::virtual_call_type) {
15.1 --- a/src/share/vm/oops/instanceKlass.cpp Mon Jun 26 14:49:58 2017 -0700 15.2 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Jun 30 23:56:45 2017 -0700 15.3 @@ -3018,7 +3018,7 @@ 15.4 return NULL; 15.5 } 15.6 15.7 -bool InstanceKlass::add_member_name(Handle mem_name) { 15.8 +oop InstanceKlass::add_member_name(Handle mem_name, bool intern) { 15.9 jweak mem_name_wref = JNIHandles::make_weak_global(mem_name); 15.10 MutexLocker ml(MemberNameTable_lock); 15.11 DEBUG_ONLY(No_Safepoint_Verifier nsv); 15.12 @@ -3028,7 +3028,7 @@ 15.13 // is called! 15.14 Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name()); 15.15 if (method->is_obsolete()) { 15.16 - return false; 15.17 + return NULL; 15.18 } else if (method->is_old()) { 15.19 // Replace method with redefined version 15.20 java_lang_invoke_MemberName::set_vmtarget(mem_name(), method_with_idnum(method->method_idnum())); 15.21 @@ -3037,8 +3037,11 @@ 15.22 if (_member_names == NULL) { 15.23 _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count()); 15.24 } 15.25 - _member_names->add_member_name(mem_name_wref); 15.26 - return true; 15.27 + if (intern) { 15.28 + return _member_names->find_or_add_member_name(mem_name_wref); 15.29 + } else { 15.30 + return _member_names->add_member_name(mem_name_wref); 15.31 + } 15.32 } 15.33 15.34 // -----------------------------------------------------------------------------------------------------
16.1 --- a/src/share/vm/oops/instanceKlass.hpp Mon Jun 26 14:49:58 2017 -0700 16.2 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Jun 30 23:56:45 2017 -0700 16.3 @@ -1105,7 +1105,7 @@ 16.4 // JSR-292 support 16.5 MemberNameTable* member_names() { return _member_names; } 16.6 void set_member_names(MemberNameTable* member_names) { _member_names = member_names; } 16.7 - bool add_member_name(Handle member_name); 16.8 + oop add_member_name(Handle member_name, bool intern); 16.9 16.10 public: 16.11 // JVMTI support
17.1 --- a/src/share/vm/opto/cfgnode.hpp Mon Jun 26 14:49:58 2017 -0700 17.2 +++ b/src/share/vm/opto/cfgnode.hpp Fri Jun 30 23:56:45 2017 -0700 17.3 @@ -119,6 +119,9 @@ 17.4 // input in slot 0. 17.5 class PhiNode : public TypeNode { 17.6 const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes. 17.7 + // The following fields are only used for data PhiNodes to indicate 17.8 + // that the PhiNode represents the value of a known instance field. 17.9 + int _inst_mem_id; // Instance memory id (node index of the memory Phi) 17.10 const int _inst_id; // Instance id of the memory slice. 17.11 const int _inst_index; // Alias index of the instance memory slice. 17.12 // Array elements references have the same alias_idx but different offset. 17.13 @@ -138,11 +141,13 @@ 17.14 }; 17.15 17.16 PhiNode( Node *r, const Type *t, const TypePtr* at = NULL, 17.17 + const int imid = -1, 17.18 const int iid = TypeOopPtr::InstanceTop, 17.19 const int iidx = Compile::AliasIdxTop, 17.20 const int ioffs = Type::OffsetTop ) 17.21 : TypeNode(t,r->req()), 17.22 _adr_type(at), 17.23 + _inst_mem_id(imid), 17.24 _inst_id(iid), 17.25 _inst_index(iidx), 17.26 _inst_offset(ioffs) 17.27 @@ -187,11 +192,14 @@ 17.28 virtual bool pinned() const { return in(0) != 0; } 17.29 virtual const TypePtr *adr_type() const { verify_adr_type(true); return _adr_type; } 17.30 17.31 + void set_inst_mem_id(int inst_mem_id) { _inst_mem_id = inst_mem_id; } 17.32 + const int inst_mem_id() const { return _inst_mem_id; } 17.33 const int inst_id() const { return _inst_id; } 17.34 const int inst_index() const { return _inst_index; } 17.35 const int inst_offset() const { return _inst_offset; } 17.36 - bool is_same_inst_field(const Type* tp, int id, int index, int offset) { 17.37 + bool is_same_inst_field(const Type* tp, int mem_id, int id, int index, int offset) { 17.38 return type()->basic_type() == tp->basic_type() && 17.39 + inst_mem_id() == mem_id && 17.40 inst_id() == id && 17.41 inst_index() == index && 17.42 inst_offset() == offset &&
18.1 --- a/src/share/vm/opto/macro.cpp Mon Jun 26 14:49:58 2017 -0700 18.2 +++ b/src/share/vm/opto/macro.cpp Fri Jun 30 23:56:45 2017 -0700 18.3 @@ -401,7 +401,7 @@ 18.4 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) { 18.5 Node* phi = region->fast_out(k); 18.6 if (phi->is_Phi() && phi != mem && 18.7 - phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) { 18.8 + phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) { 18.9 return phi; 18.10 } 18.11 } 18.12 @@ -420,7 +420,7 @@ 18.13 GrowableArray <Node *> values(length, length, NULL, false); 18.14 18.15 // create a new Phi for the value 18.16 - PhiNode *phi = new (C) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset); 18.17 + PhiNode *phi = new (C) PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset); 18.18 transform_later(phi); 18.19 value_phis->push(phi, mem->_idx); 18.20
19.1 --- a/src/share/vm/opto/memnode.cpp Mon Jun 26 14:49:58 2017 -0700 19.2 +++ b/src/share/vm/opto/memnode.cpp Fri Jun 30 23:56:45 2017 -0700 19.3 @@ -1155,7 +1155,7 @@ 19.4 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { 19.5 Node* phi = region->fast_out(i); 19.6 if (phi->is_Phi() && phi != mem && 19.7 - phi->as_Phi()->is_same_inst_field(this_type, this_iid, this_index, this_offset)) { 19.8 + phi->as_Phi()->is_same_inst_field(this_type, (int)mem->_idx, this_iid, this_index, this_offset)) { 19.9 return phi; 19.10 } 19.11 } 19.12 @@ -1400,7 +1400,7 @@ 19.13 this_iid = base->_idx; 19.14 } 19.15 PhaseIterGVN* igvn = phase->is_IterGVN(); 19.16 - Node* phi = new (C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); 19.17 + Node* phi = new (C) PhiNode(region, this_type, NULL, mem->_idx, this_iid, this_index, this_offset); 19.18 for (uint i = 1; i < region->req(); i++) { 19.19 Node* x; 19.20 Node* the_clone = NULL;
20.1 --- a/src/share/vm/opto/phaseX.cpp Mon Jun 26 14:49:58 2017 -0700 20.2 +++ b/src/share/vm/opto/phaseX.cpp Fri Jun 30 23:56:45 2017 -0700 20.3 @@ -481,6 +481,8 @@ 20.4 uint current_idx = 0; // The current new node ID. Incremented after every assignment. 20.5 for (uint i = 0; i < _useful.size(); i++) { 20.6 Node* n = _useful.at(i); 20.7 + // Sanity check that fails if we ever decide to execute this phase after EA 20.8 + assert(!n->is_Phi() || n->as_Phi()->inst_mem_id() == -1, "should not be linked to data Phi"); 20.9 const Type* type = gvn->type_or_null(n); 20.10 new_type_array.map(current_idx, type); 20.11 20.12 @@ -1378,6 +1380,18 @@ 20.13 i -= num_edges; // we deleted 1 or more copies of this edge 20.14 } 20.15 20.16 + // Search for instance field data PhiNodes in the same region pointing to the old 20.17 + // memory PhiNode and update their instance memory ids to point to the new node. 20.18 + if (old->is_Phi() && old->as_Phi()->type()->has_memory() && old->in(0) != NULL) { 20.19 + Node* region = old->in(0); 20.20 + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { 20.21 + PhiNode* phi = region->fast_out(i)->isa_Phi(); 20.22 + if (phi != NULL && phi->inst_mem_id() == (int)old->_idx) { 20.23 + phi->set_inst_mem_id((int)nn->_idx); 20.24 + } 20.25 + } 20.26 + } 20.27 + 20.28 // Smash all inputs to 'old', isolating him completely 20.29 Node *temp = new (C) Node(1); 20.30 temp->init_req(0,nn); // Add a use to nn to prevent him from dying
21.1 --- a/src/share/vm/opto/type.hpp Mon Jun 26 14:49:58 2017 -0700 21.2 +++ b/src/share/vm/opto/type.hpp Fri Jun 30 23:56:45 2017 -0700 21.3 @@ -882,7 +882,7 @@ 21.4 21.5 // If not InstanceTop or InstanceBot, indicates that this is 21.6 // a particular instance of this type which is distinct. 21.7 - // This is the the node index of the allocation node creating this instance. 21.8 + // This is the node index of the allocation node creating this instance. 21.9 int _instance_id; 21.10 21.11 // Extra type information profiling gave us. We propagate it the
22.1 --- a/src/share/vm/prims/jni.cpp Mon Jun 26 14:49:58 2017 -0700 22.2 +++ b/src/share/vm/prims/jni.cpp Fri Jun 30 23:56:45 2017 -0700 22.3 @@ -5129,6 +5129,7 @@ 22.4 run_unit_test(TestKlass_test()); 22.5 run_unit_test(Test_linked_list()); 22.6 run_unit_test(TestChunkedList_test()); 22.7 + run_unit_test(ObjectMonitor::sanity_checks()); 22.8 #if INCLUDE_VM_STRUCTS 22.9 run_unit_test(VMStructs::test()); 22.10 #endif
23.1 --- a/src/share/vm/prims/jvm.cpp Mon Jun 26 14:49:58 2017 -0700 23.2 +++ b/src/share/vm/prims/jvm.cpp Fri Jun 30 23:56:45 2017 -0700 23.3 @@ -643,7 +643,7 @@ 23.4 // This can safepoint and redefine method, so need both new_obj and method 23.5 // in a handle, for two different reasons. new_obj can move, method can be 23.6 // deleted if nothing is using it on the stack. 23.7 - m->method_holder()->add_member_name(new_obj()); 23.8 + m->method_holder()->add_member_name(new_obj(), false); 23.9 } 23.10 } 23.11
24.1 --- a/src/share/vm/prims/methodHandles.cpp Mon Jun 26 14:49:58 2017 -0700 24.2 +++ b/src/share/vm/prims/methodHandles.cpp Fri Jun 30 23:56:45 2017 -0700 24.3 @@ -173,7 +173,7 @@ 24.4 return NULL; 24.5 } 24.6 24.7 -oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { 24.8 +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, bool intern) { 24.9 assert(info.resolved_appendix().is_null(), "only normal methods here"); 24.10 methodHandle m = info.resolved_method(); 24.11 KlassHandle m_klass = m->method_holder(); 24.12 @@ -270,13 +270,7 @@ 24.13 // If relevant, the vtable or itable value is stored as vmindex. 24.14 // This is done eagerly, since it is readily available without 24.15 // constructing any new objects. 24.16 - // TO DO: maybe intern mname_oop 24.17 - if (m->method_holder()->add_member_name(mname)) { 24.18 - return mname(); 24.19 - } else { 24.20 - // Redefinition caused this to fail. Return NULL (and an exception?) 24.21 - return NULL; 24.22 - } 24.23 + return m->method_holder()->add_member_name(mname, intern); 24.24 } 24.25 24.26 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { 24.27 @@ -917,7 +911,9 @@ 24.28 if (!java_lang_invoke_MemberName::is_instance(result())) 24.29 return -99; // caller bug! 24.30 CallInfo info(m); 24.31 - oop saved = MethodHandles::init_method_MemberName(result, info); 24.32 + // Since this is going through the methods to create MemberNames, don't search 24.33 + // for matching methods already in the table 24.34 + oop saved = MethodHandles::init_method_MemberName(result, info, /*intern*/false); 24.35 if (saved != result()) 24.36 results->obj_at_put(rfill-1, saved); // show saved instance to user 24.37 } else if (++overflow >= overflow_limit) { 24.38 @@ -949,9 +945,34 @@ 24.39 } 24.40 } 24.41 24.42 -void MemberNameTable::add_member_name(jweak mem_name_wref) { 24.43 +oop MemberNameTable::add_member_name(jweak mem_name_wref) { 24.44 assert_locked_or_safepoint(MemberNameTable_lock); 24.45 this->push(mem_name_wref); 24.46 + return JNIHandles::resolve(mem_name_wref); 24.47 +} 24.48 + 24.49 +oop MemberNameTable::find_or_add_member_name(jweak mem_name_wref) { 24.50 + assert_locked_or_safepoint(MemberNameTable_lock); 24.51 + oop new_mem_name = JNIHandles::resolve(mem_name_wref); 24.52 + 24.53 + // Find matching member name in the list. 24.54 + // This is linear because these are short lists. 24.55 + int len = this->length(); 24.56 + int new_index = len; 24.57 + for (int idx = 0; idx < len; idx++) { 24.58 + oop mname = JNIHandles::resolve(this->at(idx)); 24.59 + if (mname == NULL) { 24.60 + new_index = idx; 24.61 + continue; 24.62 + } 24.63 + if (java_lang_invoke_MemberName::equals(new_mem_name, mname)) { 24.64 + JNIHandles::destroy_weak_global(mem_name_wref); 24.65 + return mname; 24.66 + } 24.67 + } 24.68 + // Not found, push the new one, or reuse empty slot 24.69 + this->at_put_grow(new_index, mem_name_wref); 24.70 + return new_mem_name; 24.71 } 24.72 24.73 #if INCLUDE_JVMTI
25.1 --- a/src/share/vm/prims/methodHandles.hpp Mon Jun 26 14:49:58 2017 -0700 25.2 +++ b/src/share/vm/prims/methodHandles.hpp Fri Jun 30 23:56:45 2017 -0700 25.3 @@ -1,5 +1,5 @@ 25.4 /* 25.5 - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. 25.6 + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. 25.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.8 * 25.9 * This code is free software; you can redistribute it and/or modify it 25.10 @@ -60,7 +60,7 @@ 25.11 static Handle new_MemberName(TRAPS); // must be followed by init_MemberName 25.12 static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target 25.13 static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false); 25.14 - static oop init_method_MemberName(Handle mname_h, CallInfo& info); 25.15 + static oop init_method_MemberName(Handle mname_h, CallInfo& info, bool intern = true); 25.16 static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true); 25.17 static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig, 25.18 int mflags, KlassHandle caller, 25.19 @@ -236,7 +236,8 @@ 25.20 public: 25.21 MemberNameTable(int methods_cnt); 25.22 ~MemberNameTable(); 25.23 - void add_member_name(jweak mem_name_ref); 25.24 + oop add_member_name(jweak mem_name_ref); 25.25 + oop find_or_add_member_name(jweak mem_name_ref); 25.26 25.27 #if INCLUDE_JVMTI 25.28 // RedefineClasses() API support:
26.1 --- a/src/share/vm/runtime/objectMonitor.cpp Mon Jun 26 14:49:58 2017 -0700 26.2 +++ b/src/share/vm/runtime/objectMonitor.cpp Fri Jun 30 23:56:45 2017 -0700 26.3 @@ -2529,6 +2529,10 @@ 26.4 SETKNOB(FastHSSEC) ; 26.5 #undef SETKNOB 26.6 26.7 + if (Knob_Verbose) { 26.8 + sanity_checks(); 26.9 + } 26.10 + 26.11 if (os::is_MP()) { 26.12 BackOffMask = (1 << Knob_SpinBackOff) - 1 ; 26.13 if (Knob_ReportSettings) ::printf ("BackOffMask=%X\n", BackOffMask) ; 26.14 @@ -2549,6 +2553,66 @@ 26.15 InitDone = 1 ; 26.16 } 26.17 26.18 +void ObjectMonitor::sanity_checks() { 26.19 + int error_cnt = 0; 26.20 + int warning_cnt = 0; 26.21 + bool verbose = Knob_Verbose != 0 NOT_PRODUCT(|| VerboseInternalVMTests); 26.22 + 26.23 + if (verbose) { 26.24 + tty->print_cr("INFO: sizeof(ObjectMonitor)=" SIZE_FORMAT, 26.25 + sizeof(ObjectMonitor)); 26.26 + } 26.27 + 26.28 + uint cache_line_size = VM_Version::L1_data_cache_line_size(); 26.29 + if (verbose) { 26.30 + tty->print_cr("INFO: L1_data_cache_line_size=%u", cache_line_size); 26.31 + } 26.32 + 26.33 + ObjectMonitor dummy; 26.34 + u_char *addr_begin = (u_char*)&dummy; 26.35 + u_char *addr_header = (u_char*)&dummy._header; 26.36 + u_char *addr_owner = (u_char*)&dummy._owner; 26.37 + 26.38 + uint offset_header = (uint)(addr_header - addr_begin); 26.39 + if (verbose) tty->print_cr("INFO: offset(_header)=%u", offset_header); 26.40 + 26.41 + uint offset_owner = (uint)(addr_owner - addr_begin); 26.42 + if (verbose) tty->print_cr("INFO: offset(_owner)=%u", offset_owner); 26.43 + 26.44 + if ((uint)(addr_header - addr_begin) != 0) { 26.45 + tty->print_cr("ERROR: offset(_header) must be zero (0)."); 26.46 + error_cnt++; 26.47 + } 26.48 + 26.49 + if (cache_line_size != 0) { 26.50 + // We were able to determine the L1 data cache line size so 26.51 + // do some cache line specific sanity checks 26.52 + 26.53 + if ((offset_owner - offset_header) < cache_line_size) { 26.54 + tty->print_cr("WARNING: the _header and _owner fields are closer " 26.55 + "than a cache line which permits false sharing."); 26.56 + warning_cnt++; 26.57 + } 26.58 + 26.59 + if ((sizeof(ObjectMonitor) % cache_line_size) != 0) { 26.60 + tty->print_cr("WARNING: ObjectMonitor size is not a multiple of " 26.61 + "a cache line which permits false sharing."); 26.62 + warning_cnt++; 26.63 + } 26.64 + } 26.65 + 26.66 + ObjectSynchronizer::sanity_checks(verbose, cache_line_size, &error_cnt, 26.67 + &warning_cnt); 26.68 + 26.69 + if (verbose || error_cnt != 0 || warning_cnt != 0) { 26.70 + tty->print_cr("INFO: error_cnt=%d", error_cnt); 26.71 + tty->print_cr("INFO: warning_cnt=%d", warning_cnt); 26.72 + } 26.73 + 26.74 + guarantee(error_cnt == 0, 26.75 + "Fatal error(s) found in ObjectMonitor::sanity_checks()"); 26.76 +} 26.77 + 26.78 #ifndef PRODUCT 26.79 void ObjectMonitor::verify() { 26.80 }
27.1 --- a/src/share/vm/runtime/objectMonitor.hpp Mon Jun 26 14:49:58 2017 -0700 27.2 +++ b/src/share/vm/runtime/objectMonitor.hpp Fri Jun 30 23:56:45 2017 -0700 27.3 @@ -189,6 +189,8 @@ 27.4 bool check(TRAPS); // true if the thread owns the monitor. 27.5 void check_slow(TRAPS); 27.6 void clear(); 27.7 + static void sanity_checks(); // public for -XX:+ExecuteInternalVMTests 27.8 + // in PRODUCT for -XX:SyncKnobs=Verbose=1 27.9 #ifndef PRODUCT 27.10 void verify(); 27.11 void print(); 27.12 @@ -234,8 +236,6 @@ 27.13 27.14 // WARNING: this must be the very first word of ObjectMonitor 27.15 // This means this class can't use any virtual member functions. 27.16 - // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the 27.17 - // implicit 0 offset in emitted code. 27.18 27.19 volatile markOop _header; // displaced object header word - mark 27.20 void* volatile _object; // backward object pointer - strong root
28.1 --- a/src/share/vm/runtime/sweeper.cpp Mon Jun 26 14:49:58 2017 -0700 28.2 +++ b/src/share/vm/runtime/sweeper.cpp Fri Jun 30 23:56:45 2017 -0700 28.3 @@ -319,6 +319,7 @@ 28.4 } 28.5 28.6 void NMethodSweeper::sweep_code_cache() { 28.7 + ResourceMark rm; 28.8 Ticks sweep_start_counter = Ticks::now(); 28.9 28.10 _flushed_count = 0; 28.11 @@ -626,6 +627,7 @@ 28.12 // state of the code cache if it's requested. 28.13 void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { 28.14 if (PrintMethodFlushing) { 28.15 + ResourceMark rm; 28.16 stringStream s; 28.17 // Dump code cache state into a buffer before locking the tty, 28.18 // because log_state() will use locks causing lock conflicts. 28.19 @@ -643,6 +645,7 @@ 28.20 } 28.21 28.22 if (LogCompilation && (xtty != NULL)) { 28.23 + ResourceMark rm; 28.24 stringStream s; 28.25 // Dump code cache state into a buffer before locking the tty, 28.26 // because log_state() will use locks causing lock conflicts.
29.1 --- a/src/share/vm/runtime/synchronizer.cpp Mon Jun 26 14:49:58 2017 -0700 29.2 +++ b/src/share/vm/runtime/synchronizer.cpp Fri Jun 30 23:56:45 2017 -0700 29.3 @@ -437,19 +437,22 @@ 29.4 // Hash Code handling 29.5 // 29.6 // Performance concern: 29.7 -// OrderAccess::storestore() calls release() which STs 0 into the global volatile 29.8 -// OrderAccess::Dummy variable. This store is unnecessary for correctness. 29.9 -// Many threads STing into a common location causes considerable cache migration 29.10 -// or "sloshing" on large SMP system. As such, I avoid using OrderAccess::storestore() 29.11 -// until it's repaired. In some cases OrderAccess::fence() -- which incurs local 29.12 -// latency on the executing processor -- is a better choice as it scales on SMP 29.13 -// systems. See http://blogs.sun.com/dave/entry/biased_locking_in_hotspot for a 29.14 -// discussion of coherency costs. Note that all our current reference platforms 29.15 -// provide strong ST-ST order, so the issue is moot on IA32, x64, and SPARC. 29.16 +// OrderAccess::storestore() calls release() which at one time stored 0 29.17 +// into the global volatile OrderAccess::dummy variable. This store was 29.18 +// unnecessary for correctness. Many threads storing into a common location 29.19 +// causes considerable cache migration or "sloshing" on large SMP systems. 29.20 +// As such, I avoided using OrderAccess::storestore(). In some cases 29.21 +// OrderAccess::fence() -- which incurs local latency on the executing 29.22 +// processor -- is a better choice as it scales on SMP systems. 29.23 +// 29.24 +// See http://blogs.oracle.com/dave/entry/biased_locking_in_hotspot for 29.25 +// a discussion of coherency costs. Note that all our current reference 29.26 +// platforms provide strong ST-ST order, so the issue is moot on IA32, 29.27 +// x64, and SPARC. 29.28 // 29.29 // As a general policy we use "volatile" to control compiler-based reordering 29.30 -// and explicit fences (barriers) to control for architectural reordering performed 29.31 -// by the CPU(s) or platform. 29.32 +// and explicit fences (barriers) to control for architectural reordering 29.33 +// performed by the CPU(s) or platform. 29.34 29.35 struct SharedGlobals { 29.36 // These are highly shared mostly-read variables. 29.37 @@ -1636,7 +1639,55 @@ 29.38 } 29.39 29.40 //------------------------------------------------------------------------------ 29.41 -// Non-product code 29.42 +// Debugging code 29.43 + 29.44 +void ObjectSynchronizer::sanity_checks(const bool verbose, 29.45 + const uint cache_line_size, 29.46 + int *error_cnt_ptr, 29.47 + int *warning_cnt_ptr) { 29.48 + u_char *addr_begin = (u_char*)&GVars; 29.49 + u_char *addr_stwRandom = (u_char*)&GVars.stwRandom; 29.50 + u_char *addr_hcSequence = (u_char*)&GVars.hcSequence; 29.51 + 29.52 + if (verbose) { 29.53 + tty->print_cr("INFO: sizeof(SharedGlobals)=" SIZE_FORMAT, 29.54 + sizeof(SharedGlobals)); 29.55 + } 29.56 + 29.57 + uint offset_stwRandom = (uint)(addr_stwRandom - addr_begin); 29.58 + if (verbose) tty->print_cr("INFO: offset(stwRandom)=%u", offset_stwRandom); 29.59 + 29.60 + uint offset_hcSequence = (uint)(addr_hcSequence - addr_begin); 29.61 + if (verbose) { 29.62 + tty->print_cr("INFO: offset(_hcSequence)=%u", offset_hcSequence); 29.63 + } 29.64 + 29.65 + if (cache_line_size != 0) { 29.66 + // We were able to determine the L1 data cache line size so 29.67 + // do some cache line specific sanity checks 29.68 + 29.69 + if (offset_stwRandom < cache_line_size) { 29.70 + tty->print_cr("WARNING: the SharedGlobals.stwRandom field is closer " 29.71 + "to the struct beginning than a cache line which permits " 29.72 + "false sharing."); 29.73 + (*warning_cnt_ptr)++; 29.74 + } 29.75 + 29.76 + if ((offset_hcSequence - offset_stwRandom) < cache_line_size) { 29.77 + tty->print_cr("WARNING: the SharedGlobals.stwRandom and " 29.78 + "SharedGlobals.hcSequence fields are closer than a cache " 29.79 + "line which permits false sharing."); 29.80 + (*warning_cnt_ptr)++; 29.81 + } 29.82 + 29.83 + if ((sizeof(SharedGlobals) - offset_hcSequence) < cache_line_size) { 29.84 + tty->print_cr("WARNING: the SharedGlobals.hcSequence field is closer " 29.85 + "to the struct end than a cache line which permits false " 29.86 + "sharing."); 29.87 + (*warning_cnt_ptr)++; 29.88 + } 29.89 + } 29.90 +} 29.91 29.92 #ifndef PRODUCT 29.93
30.1 --- a/src/share/vm/runtime/synchronizer.hpp Mon Jun 26 14:49:58 2017 -0700 30.2 +++ b/src/share/vm/runtime/synchronizer.hpp Fri Jun 30 23:56:45 2017 -0700 30.3 @@ -121,6 +121,9 @@ 30.4 static void oops_do(OopClosure* f); 30.5 30.6 // debugging 30.7 + static void sanity_checks(const bool verbose, 30.8 + const unsigned int cache_line_size, 30.9 + int *error_cnt_ptr, int *warning_cnt_ptr); 30.10 static void verify() PRODUCT_RETURN; 30.11 static int verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0; 30.12
31.1 --- a/src/share/vm/runtime/vm_version.cpp Mon Jun 26 14:49:58 2017 -0700 31.2 +++ b/src/share/vm/runtime/vm_version.cpp Fri Jun 30 23:56:45 2017 -0700 31.3 @@ -50,6 +50,7 @@ 31.4 bool Abstract_VM_Version::_supports_atomic_getadd4 = false; 31.5 bool Abstract_VM_Version::_supports_atomic_getadd8 = false; 31.6 unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U; 31.7 +unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0; 31.8 int Abstract_VM_Version::_reserve_for_allocation_prefetch = 0; 31.9 31.10 #ifndef HOTSPOT_RELEASE_VERSION
32.1 --- a/src/share/vm/runtime/vm_version.hpp Mon Jun 26 14:49:58 2017 -0700 32.2 +++ b/src/share/vm/runtime/vm_version.hpp Fri Jun 30 23:56:45 2017 -0700 32.3 @@ -1,5 +1,5 @@ 32.4 /* 32.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 32.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 * 32.9 * This code is free software; you can redistribute it and/or modify it 32.10 @@ -42,6 +42,7 @@ 32.11 static bool _supports_atomic_getadd4; 32.12 static bool _supports_atomic_getadd8; 32.13 static unsigned int _logical_processors_per_package; 32.14 + static unsigned int _L1_data_cache_line_size; 32.15 static int _vm_major_version; 32.16 static int _vm_minor_version; 32.17 static int _vm_build_number; 32.18 @@ -114,6 +115,10 @@ 32.19 return _logical_processors_per_package; 32.20 } 32.21 32.22 + static unsigned int L1_data_cache_line_size() { 32.23 + return _L1_data_cache_line_size; 32.24 + } 32.25 + 32.26 // Need a space at the end of TLAB for prefetch instructions 32.27 // which may fault when accessing memory outside of heap. 32.28 static int reserve_for_allocation_prefetch() {