[platform] JDK architecture detection (IDEA-285872 prerequisite)

GitOrigin-RevId: 5484fe400a785d2739802fb584b3bfda88114072
This commit is contained in:
Roman Shevchenko
2022-01-12 21:44:59 +00:00
committed by intellij-monorepo-bot
parent 035e93c893
commit 979a7aa59b
7 changed files with 37 additions and 60 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.memory.agent;
import com.intellij.debugger.engine.DebugProcessImpl;
@@ -13,11 +13,11 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.memory.agent.extractor.ProxyExtractor;
import com.intellij.debugger.memory.agent.parsers.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Bitness;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.system.CpuArch;
import com.sun.jdi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -394,7 +394,7 @@ public class IdeaNativeAgentProxyMirror {
JdkVersionDetector.JdkVersionInfo info = JdkVersionDetector.getInstance().detectJdkVersionInfo(javaHomePath);
if (info == null) return null;
String agentPath = getMemoryAgentPath(info.bitness);
String agentPath = getMemoryAgentPath(info.arch);
if (agentPath == null) return null;
setAgentPathPropertyValue(evaluationContext, systemClassType, agentPath);
@@ -422,11 +422,8 @@ public class IdeaNativeAgentProxyMirror {
);
}
@Nullable private static String getMemoryAgentPath(@NotNull Bitness bitness)
throws ExecutionException, InterruptedException, TimeoutException {
return MemoryAgentUtil.getAgentFilePathAsString(
Registry.is("debugger.memory.agent.debug"), MemoryAgentUtil.detectAgentKindByBitness(bitness)
);
private static @Nullable String getMemoryAgentPath(CpuArch arch) throws ExecutionException, InterruptedException, TimeoutException {
return MemoryAgentUtil.getAgentFilePathAsString(Registry.is("debugger.memory.agent.debug"), MemoryAgentUtil.detectAgentKindByArch(arch));
}
// Evaluates System.getProperty(propertyName)
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.memory.agent;
import com.intellij.debugger.engine.evaluation.EvaluateException;
@@ -9,7 +9,6 @@ import com.intellij.debugger.memory.ui.SizedReferenceInfo;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Bitness;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
@@ -45,12 +44,11 @@ public final class MemoryAgentUtil {
);
}
@NotNull
static AgentExtractor.AgentLibraryType detectAgentKindByBitness(@NotNull Bitness bitness) {
static AgentExtractor.@NotNull AgentLibraryType detectAgentKindByArch(CpuArch arch) {
LOG.assertTrue(isPlatformSupported());
if (SystemInfo.isLinux) return AgentExtractor.AgentLibraryType.LINUX;
if (SystemInfo.isMac) return AgentExtractor.AgentLibraryType.MACOS;
return bitness.equals(Bitness.x32) ? AgentExtractor.AgentLibraryType.WINDOWS32 : AgentExtractor.AgentLibraryType.WINDOWS64;
return arch.width == 32 ? AgentExtractor.AgentLibraryType.WINDOWS32 : AgentExtractor.AgentLibraryType.WINDOWS64;
}
@NotNull
@@ -1,9 +1,9 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.jps.model.java;
import com.intellij.openapi.util.Bitness;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.lang.JavaVersion;
import com.intellij.util.system.CpuArch;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.service.JpsServiceManager;
@@ -19,8 +19,7 @@ public abstract class JdkVersionDetector {
public abstract @Nullable JdkVersionInfo detectJdkVersionInfo(@NotNull String homePath, @NotNull ExecutorService actionRunner);
/** Known OpenJDK builds */
@SuppressWarnings("SpellCheckingInspection")
public enum Variant {
AdoptOpenJdk_HS("adopt", "AdoptOpenJDK (HotSpot)"),
AdoptOpenJdk_J9("adopt-j9", "AdoptOpenJDK (OpenJ9)"),
@@ -47,13 +46,13 @@ public abstract class JdkVersionDetector {
public static final class JdkVersionInfo {
public final JavaVersion version;
public final Bitness bitness;
public final Variant variant;
public final CpuArch arch;
public JdkVersionInfo(@NotNull JavaVersion version, @NotNull Bitness bitness, @Nullable Variant variant) {
public JdkVersionInfo(@NotNull JavaVersion version, @Nullable Variant variant, @NotNull CpuArch arch) {
this.version = version;
this.bitness = bitness;
this.variant = variant != null ? variant : Variant.Unknown;
this.arch = arch;
}
public @NotNull String suggestedName() {
@@ -68,7 +67,7 @@ public abstract class JdkVersionDetector {
@Override
public String toString() {
return version + " " + bitness;
return version + " " + arch;
}
}
@@ -1,12 +1,12 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.jps.model.java.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Bitness;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.io.BaseOutputReader;
import com.intellij.util.lang.JavaVersion;
import com.intellij.util.system.CpuArch;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.JdkVersionDetector;
@@ -58,17 +58,16 @@ public class JdkVersionDetectorImpl extends JdkVersionDetector {
if (versionString != null) {
JavaVersion version = JavaVersion.parse(versionString);
String arch = unquoteProperty(p, "OS_ARCH");
boolean x64 = "x86_64".equals(arch) || "amd64".equals(arch);
Bitness bitness = x64 ? Bitness.x64 : Bitness.x32;
Variant variant = detectVariant(p);
if (variant == null && version.feature < 9) {
// pre-modular release files rarely contain enough information
JdkVersionInfo fromJar = detectFromJar(homePath);
if (fromJar != null) variant = fromJar.variant;
}
return new JdkVersionInfo(version, bitness, variant);
CpuArch arch = CpuArch.fromString(unquoteProperty(p, "OS_ARCH"));
return new JdkVersionInfo(version, variant, arch);
}
}
catch (IOException | IllegalArgumentException e) {
@@ -91,7 +90,7 @@ public class JdkVersionDetectorImpl extends JdkVersionDetector {
boolean x64 = SystemInfo.isMac || Files.isDirectory(rtFile.resolveSibling("amd64"));
String vendorString = manifest.getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
Variant variant = vendorString != null ? detectVendor(vendorString) : null;
return new JdkVersionInfo(version, x64 ? Bitness.x64 : Bitness.x32, variant);
return new JdkVersionInfo(version, variant, x64 ? CpuArch.X86_64 : CpuArch.UNKNOWN);
}
}
}
@@ -125,8 +124,7 @@ public class JdkVersionDetectorImpl extends JdkVersionDetector {
JavaVersion base = JavaVersion.parse(lines.get(0));
JavaVersion rt = JavaVersion.tryParse(lines.size() > 2 ? lines.get(1) : null);
JavaVersion version = rt != null && rt.feature == base.feature && rt.minor == base.minor ? rt : base;
boolean x64 = lines.stream().anyMatch(s -> s.contains("64-Bit") || s.contains("x86_64") || s.contains("amd64"));
return new JdkVersionInfo(version, x64 ? Bitness.x64 : Bitness.x32, null);
return new JdkVersionInfo(version, null, CpuArch.UNKNOWN);
}
}
catch (IOException | IllegalArgumentException e) {
@@ -1,7 +1,6 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.jps.model
import com.intellij.openapi.util.Bitness
import com.intellij.openapi.util.SystemInfo
import com.intellij.util.SystemProperties
import com.intellij.util.lang.JavaVersion
@@ -15,7 +14,7 @@ class JdkVersionDetectorTest {
val jdkHome = SystemProperties.getJavaHome()
val jdkVersion = JdkVersionDetector.getInstance().detectJdkVersionInfo(jdkHome)
assertThat(jdkVersion?.version?.trim()).isEqualTo(JavaVersion.current().trim())
assertThat(jdkVersion?.bitness).isEqualTo(if (CpuArch.is32Bit()) Bitness.x32 else Bitness.x64)
assertThat(jdkVersion?.arch).isEqualTo(CpuArch.CURRENT)
if (SystemInfo.isMac && jdkHome.endsWith("/Contents/Home")) {
val altHome = jdkHome.substring(0, jdkHome.length - "/Contents/Home".length)
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.util;
import com.intellij.execution.ExecutionException;
@@ -8,9 +8,9 @@ import com.intellij.execution.util.ExecUtil;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.projectRoots.JdkUtil;
import com.intellij.openapi.util.Bitness;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.lang.JavaVersion;
import com.intellij.util.system.CpuArch;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,10 +51,6 @@ public final class JdkBundle {
return myVersionInfo.version;
}
public @NotNull Bitness getBitness() {
return myVersionInfo.bitness;
}
public boolean isBoot() {
return myBoot;
}
@@ -142,7 +138,7 @@ public final class JdkBundle {
JdkVersionInfo versionInfo;
if (boot) {
versionInfo = new JdkVersionInfo(JavaVersion.current(), SystemInfo.is64Bit ? Bitness.x64 : Bitness.x32, null);
versionInfo = new JdkVersionInfo(JavaVersion.current(), null, CpuArch.CURRENT);
}
else {
versionInfo = JdkVersionDetector.getInstance().detectJdkVersionInfo(actualHome.getPath());
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.util.system;
import com.intellij.jna.JnaLoader;
@@ -8,6 +8,7 @@ import com.sun.jna.platform.mac.SystemB;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.ptr.IntByReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public enum CpuArch {
@@ -33,24 +34,13 @@ public enum CpuArch {
*
* <p><b>Note</b>: may not correspond to the actual hardware if a JVM is "virtualized" (e.g. WoW64 or Rosetta 2).</p>
*/
public static final CpuArch CURRENT;
static {
String arch = System.getProperty("os.arch");
if ("x86_64".equals(arch) || "amd64".equals(arch)) {
CURRENT = X86_64;
}
else if ("i386".equals(arch) || "x86".equals(arch)) {
CURRENT = X86;
}
else if ("aarch64".equals(arch) || "arm64".equals(arch)) {
CURRENT = ARM64;
}
else if (arch == null || arch.trim().isEmpty()) {
CURRENT = UNKNOWN;
}
else {
CURRENT = OTHER;
}
public static final CpuArch CURRENT = fromString(System.getProperty("os.arch"));
public static @NotNull CpuArch fromString(@Nullable String arch) {
if ("x86_64".equals(arch) || "amd64".equals(arch)) return X86_64;
if ("i386".equals(arch) || "x86".equals(arch)) return X86;
if ("aarch64".equals(arch) || "arm64".equals(arch)) return ARM64;
return arch == null || arch.trim().isEmpty() ? UNKNOWN : OTHER;
}
public static boolean isIntel32() { return CURRENT == X86; }