1 /* 2 * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "jvm.h" 27 #include "asm/macroAssembler.inline.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "runtime/java.hpp" 30 #include "runtime/os.inline.hpp" 31 #include "runtime/stubCodeGenerator.hpp" 32 #include "vm_version_arm.hpp" 33 #include <sys/auxv.h> 34 #include <asm/hwcap.h> 35 36 #ifndef HWCAP_AES 37 #define HWCAP_AES 1 << 3 38 #endif 39 40 bool VM_Version::_is_initialized = false; 41 bool VM_Version::_has_simd = false; 42 43 extern "C" { 44 typedef bool (*check_simd_t)(); 45 } 46 47 48 #ifdef COMPILER2 49 50 #define __ _masm-> 51 52 class VM_Version_StubGenerator: public StubCodeGenerator { 53 public: 54 55 VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} 56 57 address generate_check_simd() { 58 StubCodeMark mark(this, "VM_Version", "check_simd"); 59 address start = __ pc(); 60 61 __ vcnt(Stemp, Stemp); 62 __ mov(R0, 1); 63 __ ret(LR); 64 65 return start; 66 }; 67 }; 68 69 #undef __ 70 71 #endif 72 73 74 75 extern "C" address check_simd_fault_instr; 76 77 78 void VM_Version::initialize() { 79 ResourceMark rm; 80 81 // Making this stub must be FIRST use of assembler 82 const int stub_size = 128; 83 BufferBlob* stub_blob = BufferBlob::create("get_cpu_info", stub_size); 84 if (stub_blob == NULL) { 85 vm_exit_during_initialization("Unable to allocate get_cpu_info stub"); 86 } 87 88 if (UseFMA) { 89 warning("FMA instructions are not available on this CPU"); 90 FLAG_SET_DEFAULT(UseFMA, false); 91 } 92 93 if (UseSHA) { 94 warning("SHA instructions are not available on this CPU"); 95 FLAG_SET_DEFAULT(UseSHA, false); 96 } 97 98 if (UseSHA1Intrinsics) { 99 warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU."); 100 FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); 101 } 102 103 if (UseSHA256Intrinsics) { 104 warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU."); 105 FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); 106 } 107 108 if (UseSHA512Intrinsics) { 109 warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU."); 110 FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); 111 } 112 113 if (UseCRC32Intrinsics) { 114 if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) 115 warning("CRC32 intrinsics are not available on this CPU"); 116 FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); 117 } 118 119 if (UseCRC32CIntrinsics) { 120 if (!FLAG_IS_DEFAULT(UseCRC32CIntrinsics)) 121 warning("CRC32C intrinsics are not available on this CPU"); 122 FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false); 123 } 124 125 if (UseAdler32Intrinsics) { 126 warning("Adler32 intrinsics are not available on this CPU"); 127 FLAG_SET_DEFAULT(UseAdler32Intrinsics, false); 128 } 129 130 if (UseVectorizedMismatchIntrinsic) { 131 warning("vectorizedMismatch intrinsic is not available on this CPU."); 132 FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); 133 } 134 135 CodeBuffer c(stub_blob); 136 137 #ifdef COMPILER2 138 VM_Version_StubGenerator g(&c); 139 140 address check_simd_pc = g.generate_check_simd(); 141 if (check_simd_pc != NULL) { 142 check_simd_t check_simd = CAST_TO_FN_PTR(check_simd_t, check_simd_pc); 143 check_simd_fault_instr = (address)check_simd; 144 _has_simd = check_simd(); 145 } else { 146 assert(! _has_simd, "default _has_simd value must be 'false'"); 147 } 148 #endif 149 150 unsigned long auxv = getauxval(AT_HWCAP); 151 152 char buf[512]; 153 jio_snprintf(buf, sizeof(buf), "AArch64%s", 154 ((auxv & HWCAP_AES) ? ", aes" : "")); 155 156 _features_string = os::strdup(buf); 157 158 #ifdef COMPILER2 159 if (auxv & HWCAP_AES) { 160 if (FLAG_IS_DEFAULT(UseAES)) { 161 FLAG_SET_DEFAULT(UseAES, true); 162 } 163 if (!UseAES) { 164 if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { 165 warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled."); 166 } 167 FLAG_SET_DEFAULT(UseAESIntrinsics, false); 168 } else { 169 if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { 170 FLAG_SET_DEFAULT(UseAESIntrinsics, true); 171 } 172 } 173 } else 174 #endif 175 if (UseAES || UseAESIntrinsics) { 176 if (UseAES && !FLAG_IS_DEFAULT(UseAES)) { 177 warning("AES instructions are not available on this CPU"); 178 FLAG_SET_DEFAULT(UseAES, false); 179 } 180 if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) { 181 warning("AES intrinsics are not available on this CPU"); 182 FLAG_SET_DEFAULT(UseAESIntrinsics, false); 183 } 184 } 185 186 if (UseAESCTRIntrinsics) { 187 warning("AES/CTR intrinsics are not available on this CPU"); 188 FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); 189 } 190 191 _supports_cx8 = true; 192 _supports_atomic_getset4 = true; 193 _supports_atomic_getadd4 = true; 194 _supports_atomic_getset8 = true; 195 _supports_atomic_getadd8 = true; 196 197 // TODO-AARCH64 revise C2 flags 198 199 if (has_simd()) { 200 if (FLAG_IS_DEFAULT(UsePopCountInstruction)) { 201 FLAG_SET_DEFAULT(UsePopCountInstruction, true); 202 } 203 } 204 205 if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) { 206 FLAG_SET_DEFAULT(AllocatePrefetchDistance, 128); 207 } 208 209 #ifdef COMPILER2 210 FLAG_SET_DEFAULT(UseFPUForSpilling, true); 211 212 if (FLAG_IS_DEFAULT(MaxVectorSize)) { 213 // FLAG_SET_DEFAULT(MaxVectorSize, has_simd() ? 16 : 8); 214 // SIMD/NEON can use 16, but default is 8 because currently 215 // larger than 8 will disable instruction scheduling 216 FLAG_SET_DEFAULT(MaxVectorSize, 8); 217 } 218 219 if (MaxVectorSize > 16) { 220 FLAG_SET_DEFAULT(MaxVectorSize, 8); 221 } 222 #endif 223 224 if (FLAG_IS_DEFAULT(Tier4CompileThreshold)) { 225 Tier4CompileThreshold = 10000; 226 } 227 if (FLAG_IS_DEFAULT(Tier3InvocationThreshold)) { 228 Tier3InvocationThreshold = 1000; 229 } 230 if (FLAG_IS_DEFAULT(Tier3CompileThreshold)) { 231 Tier3CompileThreshold = 5000; 232 } 233 if (FLAG_IS_DEFAULT(Tier3MinInvocationThreshold)) { 234 Tier3MinInvocationThreshold = 500; 235 } 236 237 FLAG_SET_DEFAULT(TypeProfileLevel, 0); // unsupported 238 239 // This machine does not allow unaligned memory accesses 240 if (UseUnalignedAccesses) { 241 if (!FLAG_IS_DEFAULT(UseUnalignedAccesses)) 242 warning("Unaligned memory access is not available on this CPU"); 243 FLAG_SET_DEFAULT(UseUnalignedAccesses, false); 244 } 245 246 _is_initialized = true; 247 } 248 249 bool VM_Version::use_biased_locking() { 250 // TODO-AARCH64 measure performance and revise 251 252 // The cost of CAS on uniprocessor ARM v6 and later is low compared to the 253 // overhead related to slightly longer Biased Locking execution path. 254 // Testing shows no improvement when running with Biased Locking enabled 255 // on an ARMv6 and higher uniprocessor systems. The situation is different on 256 // ARMv5 and MP systems. 257 // 258 // Therefore the Biased Locking is enabled on ARMv5 and ARM MP only. 259 // 260 return os::is_MP(); 261 }