Skip to content

Commit 5d2e616

Browse files
committed
perf: improved VM::CPU_BRAND
1 parent 5a73f7e commit 5d2e616

1 file changed

Lines changed: 45 additions & 71 deletions

File tree

src/vmaware.hpp

Lines changed: 45 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,8 +3862,8 @@ struct VM {
38623862
}
38633863

38643864
#if (WINDOWS)
3865-
const std::string& brand = cpu::get_brand();
3866-
if (brand.find("Virtual CPU") != std::string::npos) {
3865+
const char* brand = cpu::get_brand();
3866+
if (brand && strstr(brand, "Virtual CPU")) {
38673867
return true;
38683868
}
38693869
#endif
@@ -4468,7 +4468,7 @@ struct VM {
44684468
#if (x86)
44694469
i32 regs[4];
44704470
cpu::cpuid(regs, 1);
4471-
return (regs[2] & (1 << 20)) != 0; // ECX Bit 20: SSE4.2
4471+
return (regs[2] & (1 << 20)) != 0;
44724472
#else
44734473
return false;
44744474
#endif
@@ -4498,7 +4498,7 @@ struct VM {
44984498
return crc;
44994499
}
45004500

4501-
// Native/SSE4.2 hardware assisted or software CRC32C of a single byte
4501+
// native/SSE4.2 hardware assisted or software CRC32C of a single byte
45024502
#if (x86 && (GCC || CLANG))
45034503
__attribute__((__target__("sse4.2")))
45044504
#endif
@@ -4721,7 +4721,7 @@ struct VM {
47214721
};
47224722

47234723
static constexpr rule merge_rules[] = {
4724-
// Double merges
4724+
// double merges
47254725
{ brand_enum::VPC, brand_enum::HYPERV, brand_enum::INVALID, brand_enum::HYPERV_VPC },
47264726

47274727
{ brand_enum::AZURE_HYPERV, brand_enum::HYPERV, brand_enum::INVALID, brand_enum::AZURE_HYPERV },
@@ -4746,7 +4746,7 @@ struct VM {
47464746
{ brand_enum::HYPERV_VPC, brand_enum::QEMU_KVM_HYPERV, brand_enum::INVALID, brand_enum::QEMU_KVM_HYPERV },
47474747
{ brand_enum::HYPERV, brand_enum::QEMU_KVM_HYPERV, brand_enum::INVALID, brand_enum::QEMU_KVM_HYPERV },
47484748

4749-
// Triple merge
4749+
// triple merge
47504750
{ brand_enum::QEMU, brand_enum::KVM, brand_enum::KVM_HYPERV, brand_enum::QEMU_KVM_HYPERV },
47514751

47524752
// VMware merges
@@ -4966,79 +4966,53 @@ struct VM {
49664966
* @category x86
49674967
* @implements VM::CPU_BRAND
49684968
*/
4969-
[[nodiscard]] static bool cpu_brand() {
4969+
[[nodiscard]] static bool cpu_brand() {
49704970
#if (!x86)
4971-
return false;
4971+
return false;
49724972
#else
4973-
const std::string& brand = cpu::get_brand();
4974-
4975-
// easy shortcut for QEMU
4976-
if (brand.rfind("QEMU Virtual CPU version", 0) == 0) {
4977-
return core::add(brand_enum::QEMU);
4978-
}
4979-
4980-
struct cstrview {
4981-
const char* data;
4982-
std::size_t size;
4983-
constexpr cstrview(const char* d, std::size_t s) noexcept
4984-
: data(d), size(s) {
4985-
}
4986-
};
4973+
const char* brand = cpu::get_brand();
49874974

4988-
static constexpr std::array<cstrview, 10> checks{ {
4989-
{ "qemu", 4 },
4990-
{ "kvm", 3 },
4991-
{ "vbox", 4 },
4992-
{ "virtualbox", 10},
4993-
{ "monitor", 7 },
4994-
{ "bhyve", 5 },
4995-
{ "hypervisor", 10},
4996-
{ "hvisor", 6 },
4997-
{ "parallels", 9 },
4998-
{ "vmware", 6 }
4999-
} };
5000-
5001-
for (auto& v : checks) {
5002-
if (brand.size() < v.size) {
5003-
continue; // too short to match
5004-
}
4975+
if (!brand) {
4976+
return false;
4977+
}
50054978

5006-
if (brand.find(v.data) != std::string::npos) {
5007-
debug("CPU_BRAND: match = ", v.data);
4979+
if (strncmp(brand, "QEMU Virtual CPU version", 24) == 0) {
4980+
return core::add(brand_enum::QEMU);
4981+
}
50084982

5009-
// For these, we only care that it's virtualized:
5010-
if (v.size == 7 // "monitor"
5011-
|| ((v.size == 6) && (v.data[0] == 'h')) // "hvisor"
5012-
|| ((v.size == 10) && (v.data[0] == 'h')) // "hypervisor"
5013-
) {
5014-
return true;
5015-
}
4983+
struct check_t {
4984+
const char* text;
4985+
brand_enum brand;
4986+
};
4987+
4988+
static constexpr check_t checks[] = {
4989+
{ "qemu", brand_enum::QEMU },
4990+
{ "kvm", brand_enum::KVM },
4991+
{ "vbox", brand_enum::VBOX },
4992+
{ "virtualbox", brand_enum::VBOX },
4993+
{ "bhyve", brand_enum::BHYVE },
4994+
{ "parallels", brand_enum::PARALLELS },
4995+
{ "vmware", brand_enum::VMWARE },
4996+
};
4997+
4998+
for (const auto& c : checks) {
4999+
if (strstr(brand, c.text)) {
5000+
debug("CPU_BRAND: match = ", c.text);
5001+
return core::add(c.brand);
5002+
}
5003+
}
50165004

5017-
// Otherwise map to our enums:
5018-
switch (v.size) {
5019-
case 4: // "qemu" or "vbox"
5020-
return core::add(v.data[0] == 'q'
5021-
? brand_enum::QEMU
5022-
: brand_enum::VBOX);
5023-
case 3: // "kvm"
5024-
return core::add(brand_enum::KVM);
5025-
case 5: // "bhyve"
5026-
return core::add(brand_enum::BHYVE);
5027-
case 9: // "parallels"
5028-
return core::add(brand_enum::PARALLELS);
5029-
case 10: // "virtualbox"
5030-
return core::add(brand_enum::VBOX);
5031-
case 6: // "vmware"
5032-
return core::add(brand_enum::VMWARE);
5033-
default:
5034-
return false;
5035-
}
5036-
}
5037-
}
5005+
if (strstr(brand, "monitor") ||
5006+
strstr(brand, "hypervisor") ||
5007+
strstr(brand, "hvisor"))
5008+
{
5009+
debug("CPU_BRAND: generic virtualization match");
5010+
return true;
5011+
}
50385012

5039-
return false;
5013+
return false;
50405014
#endif
5041-
}
5015+
}
50425016

50435017

50445018
/**

0 commit comments

Comments
 (0)