ART: Change InstructionSetFeatures to return unique_ptr
This makes clear the ownership of the object.
Test: m test-art-host
Change-Id: I55fa734f04bc3046d370f4dcf98ce6b17c59e234
diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc
index c3a5829..c81a93c 100644
--- a/runtime/arch/arm/instruction_set_features_arm.cc
+++ b/runtime/arch/arm/instruction_set_features_arm.cc
@@ -33,7 +33,7 @@
namespace art {
-const ArmInstructionSetFeatures* ArmInstructionSetFeatures::FromVariant(
+ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg) {
// Assume all ARM processors are SMP.
// TODO: set the SMP support based on variant.
@@ -69,7 +69,7 @@
if (FindVariantInArray(unsupported_arm_variants, arraysize(unsupported_arm_variants),
variant)) {
*error_msg = StringPrintf("Attempt to use unsupported ARM variant: %s", variant.c_str());
- return nullptr;
+ return ArmFeaturesUniquePtr();
}
// Warn if the variant is unknown.
// TODO: some of the variants below may have feature support, but that support is currently
@@ -97,17 +97,17 @@
<< ") using conservative defaults";
}
}
- return new ArmInstructionSetFeatures(smp, has_div, has_lpae);
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
}
-const ArmInstructionSetFeatures* ArmInstructionSetFeatures::FromBitmap(uint32_t bitmap) {
+ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromBitmap(uint32_t bitmap) {
bool smp = (bitmap & kSmpBitfield) != 0;
bool has_div = (bitmap & kDivBitfield) != 0;
bool has_atomic_ldrd_strd = (bitmap & kAtomicLdrdStrdBitfield) != 0;
- return new ArmInstructionSetFeatures(smp, has_div, has_atomic_ldrd_strd);
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_atomic_ldrd_strd));
}
-const ArmInstructionSetFeatures* ArmInstructionSetFeatures::FromCppDefines() {
+ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromCppDefines() {
const bool smp = true;
#if defined(__ARM_ARCH_EXT_IDIV__)
const bool has_div = true;
@@ -119,10 +119,10 @@
#else
const bool has_lpae = false;
#endif
- return new ArmInstructionSetFeatures(smp, has_div, has_lpae);
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
}
-const ArmInstructionSetFeatures* ArmInstructionSetFeatures::FromCpuInfo() {
+ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromCpuInfo() {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
bool smp = false;
@@ -157,10 +157,10 @@
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return new ArmInstructionSetFeatures(smp, has_div, has_lpae);
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
}
-const ArmInstructionSetFeatures* ArmInstructionSetFeatures::FromHwcap() {
+ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromHwcap() {
bool smp = sysconf(_SC_NPROCESSORS_CONF) > 1;
bool has_div = false;
@@ -180,7 +180,7 @@
}
#endif
- return new ArmInstructionSetFeatures(smp, has_div, has_lpae);
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
}
// A signal handler called by a fault for an illegal instruction. We record the fact in r0
@@ -198,7 +198,7 @@
#endif
}
-const ArmInstructionSetFeatures* ArmInstructionSetFeatures::FromAssembly() {
+ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromAssembly() {
const bool smp = true;
// See if have a sdiv instruction. Register a signal handler and try to execute an sdiv
@@ -226,7 +226,7 @@
#else
const bool has_lpae = false;
#endif
- return new ArmInstructionSetFeatures(smp, has_div, has_lpae);
+ return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(smp, has_div, has_lpae));
}
bool ArmInstructionSetFeatures::Equals(const InstructionSetFeatures* other) const {
@@ -265,7 +265,8 @@
return result;
}
-const InstructionSetFeatures* ArmInstructionSetFeatures::AddFeaturesFromSplitString(
+std::unique_ptr<const InstructionSetFeatures>
+ArmInstructionSetFeatures::AddFeaturesFromSplitString(
const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
bool has_atomic_ldrd_strd = has_atomic_ldrd_strd_;
bool has_div = has_div_;
@@ -284,7 +285,8 @@
return nullptr;
}
}
- return new ArmInstructionSetFeatures(smp, has_div, has_atomic_ldrd_strd);
+ return std::unique_ptr<const InstructionSetFeatures>(
+ new ArmInstructionSetFeatures(smp, has_div, has_atomic_ldrd_strd));
}
} // namespace art
diff --git a/runtime/arch/arm/instruction_set_features_arm.h b/runtime/arch/arm/instruction_set_features_arm.h
index 221bf1f..204d1d7 100644
--- a/runtime/arch/arm/instruction_set_features_arm.h
+++ b/runtime/arch/arm/instruction_set_features_arm.h
@@ -21,29 +21,31 @@
namespace art {
+class ArmInstructionSetFeatures;
+using ArmFeaturesUniquePtr = std::unique_ptr<const ArmInstructionSetFeatures>;
+
// Instruction set features relevant to the ARM architecture.
class ArmInstructionSetFeatures FINAL : public InstructionSetFeatures {
public:
// Process a CPU variant string like "krait" or "cortex-a15" and create InstructionSetFeatures.
- static const ArmInstructionSetFeatures* FromVariant(const std::string& variant,
- std::string* error_msg);
+ static ArmFeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg);
// Parse a bitmap and create an InstructionSetFeatures.
- static const ArmInstructionSetFeatures* FromBitmap(uint32_t bitmap);
+ static ArmFeaturesUniquePtr FromBitmap(uint32_t bitmap);
// Turn C pre-processor #defines into the equivalent instruction set features.
- static const ArmInstructionSetFeatures* FromCppDefines();
+ static ArmFeaturesUniquePtr FromCppDefines();
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const ArmInstructionSetFeatures* FromCpuInfo();
+ static ArmFeaturesUniquePtr FromCpuInfo();
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const ArmInstructionSetFeatures* FromHwcap();
+ static ArmFeaturesUniquePtr FromHwcap();
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const ArmInstructionSetFeatures* FromAssembly();
+ static ArmFeaturesUniquePtr FromAssembly();
bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
@@ -71,7 +73,7 @@
protected:
// Parse a vector of the form "div", "lpae" adding these to a new ArmInstructionSetFeatures.
- const InstructionSetFeatures*
+ std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc
index cad13b2..4e7dea3 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.cc
+++ b/runtime/arch/arm64/instruction_set_features_arm64.cc
@@ -19,12 +19,13 @@
#include <fstream>
#include <sstream>
+#include "base/stl_util.h"
#include "base/stringprintf.h"
#include "utils.h" // For Trim.
namespace art {
-const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromVariant(
+Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg) {
const bool smp = true; // Conservative default.
@@ -52,22 +53,23 @@
// The variants that need a fix for 843419 are the same that need a fix for 835769.
bool needs_a53_843419_fix = needs_a53_835769_fix;
- return new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix, needs_a53_843419_fix);
+ return Arm64FeaturesUniquePtr(
+ new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix, needs_a53_843419_fix));
}
-const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
+Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
bool smp = (bitmap & kSmpBitfield) != 0;
bool is_a53 = (bitmap & kA53Bitfield) != 0;
- return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
}
-const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCppDefines() {
+Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromCppDefines() {
const bool smp = true;
const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
- return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
}
-const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCpuInfo() {
+Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromCpuInfo() {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
bool smp = false;
@@ -89,16 +91,16 @@
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
}
-const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromHwcap() {
+Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromHwcap() {
bool smp = sysconf(_SC_NPROCESSORS_CONF) > 1;
const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
- return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
+ return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
}
-const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromAssembly() {
+Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromAssembly() {
UNIMPLEMENTED(WARNING);
return FromCppDefines();
}
@@ -130,7 +132,8 @@
return result;
}
-const InstructionSetFeatures* Arm64InstructionSetFeatures::AddFeaturesFromSplitString(
+std::unique_ptr<const InstructionSetFeatures>
+Arm64InstructionSetFeatures::AddFeaturesFromSplitString(
const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
bool is_a53 = fix_cortex_a53_835769_;
for (auto i = features.begin(); i != features.end(); i++) {
@@ -144,7 +147,8 @@
return nullptr;
}
}
- return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
+ return std::unique_ptr<const InstructionSetFeatures>(
+ new Arm64InstructionSetFeatures(smp, is_a53, is_a53));
}
} // namespace art
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.h b/runtime/arch/arm64/instruction_set_features_arm64.h
index abd7e83..e51aa1c 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.h
+++ b/runtime/arch/arm64/instruction_set_features_arm64.h
@@ -21,29 +21,31 @@
namespace art {
+class Arm64InstructionSetFeatures;
+using Arm64FeaturesUniquePtr = std::unique_ptr<const Arm64InstructionSetFeatures>;
+
// Instruction set features relevant to the ARM64 architecture.
class Arm64InstructionSetFeatures FINAL : public InstructionSetFeatures {
public:
// Process a CPU variant string like "krait" or "cortex-a15" and create InstructionSetFeatures.
- static const Arm64InstructionSetFeatures* FromVariant(const std::string& variant,
- std::string* error_msg);
+ static Arm64FeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg);
// Parse a bitmap and create an InstructionSetFeatures.
- static const Arm64InstructionSetFeatures* FromBitmap(uint32_t bitmap);
+ static Arm64FeaturesUniquePtr FromBitmap(uint32_t bitmap);
// Turn C pre-processor #defines into the equivalent instruction set features.
- static const Arm64InstructionSetFeatures* FromCppDefines();
+ static Arm64FeaturesUniquePtr FromCppDefines();
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const Arm64InstructionSetFeatures* FromCpuInfo();
+ static Arm64FeaturesUniquePtr FromCpuInfo();
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const Arm64InstructionSetFeatures* FromHwcap();
+ static Arm64FeaturesUniquePtr FromHwcap();
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const Arm64InstructionSetFeatures* FromAssembly();
+ static Arm64FeaturesUniquePtr FromAssembly();
bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
@@ -70,7 +72,7 @@
protected:
// Parse a vector of the form "a53" adding these to a new ArmInstructionSetFeatures.
- const InstructionSetFeatures*
+ std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc
index 898f83a..b32391f 100644
--- a/runtime/arch/instruction_set_features.cc
+++ b/runtime/arch/instruction_set_features.cc
@@ -29,29 +29,28 @@
namespace art {
-const InstructionSetFeatures* InstructionSetFeatures::FromVariant(InstructionSet isa,
- const std::string& variant,
- std::string* error_msg) {
- const InstructionSetFeatures* result;
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromVariant(
+ InstructionSet isa, const std::string& variant, std::string* error_msg) {
+ std::unique_ptr<const InstructionSetFeatures> result;
switch (isa) {
case kArm:
case kThumb2:
- result = ArmInstructionSetFeatures::FromVariant(variant, error_msg);
+ result.reset(ArmInstructionSetFeatures::FromVariant(variant, error_msg).release());
break;
case kArm64:
- result = Arm64InstructionSetFeatures::FromVariant(variant, error_msg);
+ result.reset(Arm64InstructionSetFeatures::FromVariant(variant, error_msg).release());
break;
case kMips:
- result = MipsInstructionSetFeatures::FromVariant(variant, error_msg);
+ result.reset(MipsInstructionSetFeatures::FromVariant(variant, error_msg).release());
break;
case kMips64:
result = Mips64InstructionSetFeatures::FromVariant(variant, error_msg);
break;
case kX86:
- result = X86InstructionSetFeatures::FromVariant(variant, error_msg);
+ result.reset(X86InstructionSetFeatures::FromVariant(variant, error_msg).release());
break;
case kX86_64:
- result = X86_64InstructionSetFeatures::FromVariant(variant, error_msg);
+ result.reset(X86_64InstructionSetFeatures::FromVariant(variant, error_msg).release());
break;
default:
UNIMPLEMENTED(FATAL) << isa;
@@ -61,28 +60,28 @@
return result;
}
-const InstructionSetFeatures* InstructionSetFeatures::FromBitmap(InstructionSet isa,
- uint32_t bitmap) {
- const InstructionSetFeatures* result;
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromBitmap(InstructionSet isa,
+ uint32_t bitmap) {
+ std::unique_ptr<const InstructionSetFeatures> result;
switch (isa) {
case kArm:
case kThumb2:
- result = ArmInstructionSetFeatures::FromBitmap(bitmap);
+ result.reset(ArmInstructionSetFeatures::FromBitmap(bitmap).release());
break;
case kArm64:
- result = Arm64InstructionSetFeatures::FromBitmap(bitmap);
+ result.reset(Arm64InstructionSetFeatures::FromBitmap(bitmap).release());
break;
case kMips:
- result = MipsInstructionSetFeatures::FromBitmap(bitmap);
+ result.reset(MipsInstructionSetFeatures::FromBitmap(bitmap).release());
break;
case kMips64:
result = Mips64InstructionSetFeatures::FromBitmap(bitmap);
break;
case kX86:
- result = X86InstructionSetFeatures::FromBitmap(bitmap);
+ result.reset(X86InstructionSetFeatures::FromBitmap(bitmap).release());
break;
case kX86_64:
- result = X86_64InstructionSetFeatures::FromBitmap(bitmap);
+ result.reset(X86_64InstructionSetFeatures::FromBitmap(bitmap).release());
break;
default:
UNIMPLEMENTED(FATAL) << isa;
@@ -92,27 +91,27 @@
return result;
}
-const InstructionSetFeatures* InstructionSetFeatures::FromCppDefines() {
- const InstructionSetFeatures* result;
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCppDefines() {
+ std::unique_ptr<const InstructionSetFeatures> result;
switch (kRuntimeISA) {
case kArm:
case kThumb2:
- result = ArmInstructionSetFeatures::FromCppDefines();
+ result.reset(ArmInstructionSetFeatures::FromCppDefines().release());
break;
case kArm64:
- result = Arm64InstructionSetFeatures::FromCppDefines();
+ result.reset(Arm64InstructionSetFeatures::FromCppDefines().release());
break;
case kMips:
- result = MipsInstructionSetFeatures::FromCppDefines();
+ result.reset(MipsInstructionSetFeatures::FromCppDefines().release());
break;
case kMips64:
result = Mips64InstructionSetFeatures::FromCppDefines();
break;
case kX86:
- result = X86InstructionSetFeatures::FromCppDefines();
+ result.reset(X86InstructionSetFeatures::FromCppDefines().release());
break;
case kX86_64:
- result = X86_64InstructionSetFeatures::FromCppDefines();
+ result.reset(X86_64InstructionSetFeatures::FromCppDefines().release());
break;
default:
UNIMPLEMENTED(FATAL) << kRuntimeISA;
@@ -122,27 +121,27 @@
}
-const InstructionSetFeatures* InstructionSetFeatures::FromCpuInfo() {
- const InstructionSetFeatures* result;
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCpuInfo() {
+ std::unique_ptr<const InstructionSetFeatures> result;
switch (kRuntimeISA) {
case kArm:
case kThumb2:
- result = ArmInstructionSetFeatures::FromCpuInfo();
+ result.reset(ArmInstructionSetFeatures::FromCpuInfo().release());
break;
case kArm64:
- result = Arm64InstructionSetFeatures::FromCpuInfo();
+ result.reset(Arm64InstructionSetFeatures::FromCpuInfo().release());
break;
case kMips:
- result = MipsInstructionSetFeatures::FromCpuInfo();
+ result.reset(MipsInstructionSetFeatures::FromCpuInfo().release());
break;
case kMips64:
result = Mips64InstructionSetFeatures::FromCpuInfo();
break;
case kX86:
- result = X86InstructionSetFeatures::FromCpuInfo();
+ result.reset(X86InstructionSetFeatures::FromCpuInfo().release());
break;
case kX86_64:
- result = X86_64InstructionSetFeatures::FromCpuInfo();
+ result.reset(X86_64InstructionSetFeatures::FromCpuInfo().release());
break;
default:
UNIMPLEMENTED(FATAL) << kRuntimeISA;
@@ -151,27 +150,27 @@
return result;
}
-const InstructionSetFeatures* InstructionSetFeatures::FromHwcap() {
- const InstructionSetFeatures* result;
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromHwcap() {
+ std::unique_ptr<const InstructionSetFeatures> result;
switch (kRuntimeISA) {
case kArm:
case kThumb2:
- result = ArmInstructionSetFeatures::FromHwcap();
+ result.reset(ArmInstructionSetFeatures::FromHwcap().release());
break;
case kArm64:
- result = Arm64InstructionSetFeatures::FromHwcap();
+ result.reset(Arm64InstructionSetFeatures::FromHwcap().release());
break;
case kMips:
- result = MipsInstructionSetFeatures::FromHwcap();
+ result.reset(MipsInstructionSetFeatures::FromHwcap().release());
break;
case kMips64:
result = Mips64InstructionSetFeatures::FromHwcap();
break;
case kX86:
- result = X86InstructionSetFeatures::FromHwcap();
+ result.reset(X86InstructionSetFeatures::FromHwcap().release());
break;
case kX86_64:
- result = X86_64InstructionSetFeatures::FromHwcap();
+ result.reset(X86_64InstructionSetFeatures::FromHwcap().release());
break;
default:
UNIMPLEMENTED(FATAL) << kRuntimeISA;
@@ -180,27 +179,27 @@
return result;
}
-const InstructionSetFeatures* InstructionSetFeatures::FromAssembly() {
- const InstructionSetFeatures* result;
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromAssembly() {
+ std::unique_ptr<const InstructionSetFeatures> result;
switch (kRuntimeISA) {
case kArm:
case kThumb2:
- result = ArmInstructionSetFeatures::FromAssembly();
+ result.reset(ArmInstructionSetFeatures::FromAssembly().release());
break;
case kArm64:
- result = Arm64InstructionSetFeatures::FromAssembly();
+ result.reset(Arm64InstructionSetFeatures::FromAssembly().release());
break;
case kMips:
- result = MipsInstructionSetFeatures::FromAssembly();
+ result.reset(MipsInstructionSetFeatures::FromAssembly().release());
break;
case kMips64:
result = Mips64InstructionSetFeatures::FromAssembly();
break;
case kX86:
- result = X86InstructionSetFeatures::FromAssembly();
+ result.reset(X86InstructionSetFeatures::FromAssembly().release());
break;
case kX86_64:
- result = X86_64InstructionSetFeatures::FromAssembly();
+ result.reset(X86_64InstructionSetFeatures::FromAssembly().release());
break;
default:
UNIMPLEMENTED(FATAL) << kRuntimeISA;
@@ -209,11 +208,11 @@
return result;
}
-const InstructionSetFeatures* InstructionSetFeatures::AddFeaturesFromString(
+std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::AddFeaturesFromString(
const std::string& feature_list, std::string* error_msg) const {
if (feature_list.empty()) {
*error_msg = "No instruction set features specified";
- return nullptr;
+ return std::unique_ptr<const InstructionSetFeatures>();
}
std::vector<std::string> features;
Split(feature_list, ',', &features);
@@ -223,7 +222,7 @@
for (auto it = features.begin(); it != features.end();) {
if (use_default) {
*error_msg = "Unexpected instruction set features after 'default'";
- return nullptr;
+ return std::unique_ptr<const InstructionSetFeatures>();
}
std::string feature = Trim(*it);
bool erase = false;
@@ -233,7 +232,7 @@
erase = true;
} else {
*error_msg = "Unexpected instruction set features before 'default'";
- return nullptr;
+ return std::unique_ptr<const InstructionSetFeatures>();
}
} else if (feature == "smp") {
smp = true;
diff --git a/runtime/arch/instruction_set_features.h b/runtime/arch/instruction_set_features.h
index d10ae21..d84bc02 100644
--- a/runtime/arch/instruction_set_features.h
+++ b/runtime/arch/instruction_set_features.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_
#define ART_RUNTIME_ARCH_INSTRUCTION_SET_FEATURES_H_
+#include <memory>
#include <ostream>
#include <vector>
@@ -36,31 +37,32 @@
class InstructionSetFeatures {
public:
// Process a CPU variant string for the given ISA and create an InstructionSetFeatures.
- static const InstructionSetFeatures* FromVariant(InstructionSet isa,
- const std::string& variant,
- std::string* error_msg);
+ static std::unique_ptr<const InstructionSetFeatures> FromVariant(InstructionSet isa,
+ const std::string& variant,
+ std::string* error_msg);
// Parse a bitmap for the given isa and create an InstructionSetFeatures.
- static const InstructionSetFeatures* FromBitmap(InstructionSet isa, uint32_t bitmap);
+ static std::unique_ptr<const InstructionSetFeatures> FromBitmap(InstructionSet isa,
+ uint32_t bitmap);
// Turn C pre-processor #defines into the equivalent instruction set features for kRuntimeISA.
- static const InstructionSetFeatures* FromCppDefines();
+ static std::unique_ptr<const InstructionSetFeatures> FromCppDefines();
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const InstructionSetFeatures* FromCpuInfo();
+ static std::unique_ptr<const InstructionSetFeatures> FromCpuInfo();
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const InstructionSetFeatures* FromHwcap();
+ static std::unique_ptr<const InstructionSetFeatures> FromHwcap();
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const InstructionSetFeatures* FromAssembly();
+ static std::unique_ptr<const InstructionSetFeatures> FromAssembly();
// Parse a string of the form "div,-atomic_ldrd_strd" adding and removing these features to
// create a new InstructionSetFeatures.
- const InstructionSetFeatures* AddFeaturesFromString(const std::string& feature_list,
- std::string* error_msg) const WARN_UNUSED;
+ std::unique_ptr<const InstructionSetFeatures> AddFeaturesFromString(
+ const std::string& feature_list, std::string* error_msg) const WARN_UNUSED;
// Are these features the same as the other given features?
virtual bool Equals(const InstructionSetFeatures* other) const = 0;
@@ -107,7 +109,7 @@
const std::string& variant);
// Add architecture specific features in sub-classes.
- virtual const InstructionSetFeatures*
+ virtual std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(bool smp, const std::vector<std::string>& features,
std::string* error_msg) const = 0;
diff --git a/runtime/arch/mips/instruction_set_features_mips.cc b/runtime/arch/mips/instruction_set_features_mips.cc
index b3a9866..a95b6f6 100644
--- a/runtime/arch/mips/instruction_set_features_mips.cc
+++ b/runtime/arch/mips/instruction_set_features_mips.cc
@@ -19,6 +19,7 @@
#include <fstream>
#include <sstream>
+#include "base/stl_util.h"
#include "base/stringprintf.h"
#include "utils.h" // For Trim.
@@ -63,7 +64,7 @@
}
}
-const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromVariant(
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) {
bool smp = true; // Conservative default.
@@ -97,18 +98,19 @@
LOG(WARNING) << "Unexpected CPU variant for Mips32 using defaults: " << variant;
}
- return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6);
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
}
-const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromBitmap(uint32_t bitmap) {
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromBitmap(
+ uint32_t bitmap) {
bool smp = (bitmap & kSmpBitfield) != 0;
bool fpu_32bit = (bitmap & kFpu32Bitfield) != 0;
bool mips_isa_gte2 = (bitmap & kIsaRevGte2Bitfield) != 0;
bool r6 = (bitmap & kR6) != 0;
- return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6);
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
}
-const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCppDefines() {
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromCppDefines() {
// Assume conservative defaults.
const bool smp = true;
@@ -117,10 +119,10 @@
bool r6;
GetFlagsFromCppDefined(&mips_isa_gte2, &r6, &fpu_32bit);
- return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6);
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
}
-const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromCpuInfo() {
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromCpuInfo() {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
// Assume conservative defaults.
@@ -147,15 +149,15 @@
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6);
+ return MipsFeaturesUniquePtr(new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
}
-const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromHwcap() {
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromHwcap() {
UNIMPLEMENTED(WARNING);
return FromCppDefines();
}
-const MipsInstructionSetFeatures* MipsInstructionSetFeatures::FromAssembly() {
+MipsFeaturesUniquePtr MipsInstructionSetFeatures::FromAssembly() {
UNIMPLEMENTED(WARNING);
return FromCppDefines();
}
@@ -201,7 +203,8 @@
return result;
}
-const InstructionSetFeatures* MipsInstructionSetFeatures::AddFeaturesFromSplitString(
+std::unique_ptr<const InstructionSetFeatures>
+MipsInstructionSetFeatures::AddFeaturesFromSplitString(
const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
bool fpu_32bit = fpu_32bit_;
bool mips_isa_gte2 = mips_isa_gte2_;
@@ -225,7 +228,8 @@
return nullptr;
}
}
- return new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6);
+ return std::unique_ptr<const InstructionSetFeatures>(
+ new MipsInstructionSetFeatures(smp, fpu_32bit, mips_isa_gte2, r6));
}
} // namespace art
diff --git a/runtime/arch/mips/instruction_set_features_mips.h b/runtime/arch/mips/instruction_set_features_mips.h
index 2d54988..c2a28dc 100644
--- a/runtime/arch/mips/instruction_set_features_mips.h
+++ b/runtime/arch/mips/instruction_set_features_mips.h
@@ -23,29 +23,31 @@
namespace art {
+class MipsInstructionSetFeatures;
+using MipsFeaturesUniquePtr = std::unique_ptr<const MipsInstructionSetFeatures>;
+
// Instruction set features relevant to the MIPS architecture.
class MipsInstructionSetFeatures FINAL : public InstructionSetFeatures {
public:
// Process a CPU variant string like "r4000" and create InstructionSetFeatures.
- static const MipsInstructionSetFeatures* FromVariant(const std::string& variant,
- std::string* error_msg);
+ static MipsFeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg);
// Parse a bitmap and create an InstructionSetFeatures.
- static const MipsInstructionSetFeatures* FromBitmap(uint32_t bitmap);
+ static MipsFeaturesUniquePtr FromBitmap(uint32_t bitmap);
// Turn C pre-processor #defines into the equivalent instruction set features.
- static const MipsInstructionSetFeatures* FromCppDefines();
+ static MipsFeaturesUniquePtr FromCppDefines();
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const MipsInstructionSetFeatures* FromCpuInfo();
+ static MipsFeaturesUniquePtr FromCpuInfo();
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const MipsInstructionSetFeatures* FromHwcap();
+ static MipsFeaturesUniquePtr FromHwcap();
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const MipsInstructionSetFeatures* FromAssembly();
+ static MipsFeaturesUniquePtr FromAssembly();
bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
@@ -77,7 +79,7 @@
protected:
// Parse a vector of the form "fpu32", "mips2" adding these to a new MipsInstructionSetFeatures.
- virtual const InstructionSetFeatures*
+ std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
diff --git a/runtime/arch/mips64/instruction_set_features_mips64.cc b/runtime/arch/mips64/instruction_set_features_mips64.cc
index 5c0c914..490a8d2 100644
--- a/runtime/arch/mips64/instruction_set_features_mips64.cc
+++ b/runtime/arch/mips64/instruction_set_features_mips64.cc
@@ -24,27 +24,27 @@
namespace art {
-const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromVariant(
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) {
if (variant != "default" && variant != "mips64r6") {
LOG(WARNING) << "Unexpected CPU variant for Mips64 using defaults: " << variant;
}
bool smp = true; // Conservative default.
- return new Mips64InstructionSetFeatures(smp);
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
}
-const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
bool smp = (bitmap & kSmpBitfield) != 0;
- return new Mips64InstructionSetFeatures(smp);
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
}
-const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromCppDefines() {
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromCppDefines() {
const bool smp = true;
- return new Mips64InstructionSetFeatures(smp);
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
}
-const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromCpuInfo() {
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromCpuInfo() {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
bool smp = false;
@@ -65,15 +65,15 @@
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- return new Mips64InstructionSetFeatures(smp);
+ return Mips64FeaturesUniquePtr(new Mips64InstructionSetFeatures(smp));
}
-const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromHwcap() {
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromHwcap() {
UNIMPLEMENTED(WARNING);
return FromCppDefines();
}
-const Mips64InstructionSetFeatures* Mips64InstructionSetFeatures::FromAssembly() {
+Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromAssembly() {
UNIMPLEMENTED(WARNING);
return FromCppDefines();
}
@@ -99,7 +99,8 @@
return result;
}
-const InstructionSetFeatures* Mips64InstructionSetFeatures::AddFeaturesFromSplitString(
+std::unique_ptr<const InstructionSetFeatures>
+Mips64InstructionSetFeatures::AddFeaturesFromSplitString(
const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
auto i = features.begin();
if (i != features.end()) {
@@ -108,7 +109,7 @@
*error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str());
return nullptr;
}
- return new Mips64InstructionSetFeatures(smp);
+ return std::unique_ptr<const InstructionSetFeatures>(new Mips64InstructionSetFeatures(smp));
}
} // namespace art
diff --git a/runtime/arch/mips64/instruction_set_features_mips64.h b/runtime/arch/mips64/instruction_set_features_mips64.h
index d5d6012..2e66235 100644
--- a/runtime/arch/mips64/instruction_set_features_mips64.h
+++ b/runtime/arch/mips64/instruction_set_features_mips64.h
@@ -21,29 +21,32 @@
namespace art {
+class Mips64InstructionSetFeatures;
+using Mips64FeaturesUniquePtr = std::unique_ptr<const Mips64InstructionSetFeatures>;
+
// Instruction set features relevant to the MIPS64 architecture.
class Mips64InstructionSetFeatures FINAL : public InstructionSetFeatures {
public:
// Process a CPU variant string like "r4000" and create InstructionSetFeatures.
- static const Mips64InstructionSetFeatures* FromVariant(const std::string& variant,
- std::string* error_msg);
+ static Mips64FeaturesUniquePtr FromVariant(const std::string& variant,
+ std::string* error_msg);
// Parse a bitmap and create an InstructionSetFeatures.
- static const Mips64InstructionSetFeatures* FromBitmap(uint32_t bitmap);
+ static Mips64FeaturesUniquePtr FromBitmap(uint32_t bitmap);
// Turn C pre-processor #defines into the equivalent instruction set features.
- static const Mips64InstructionSetFeatures* FromCppDefines();
+ static Mips64FeaturesUniquePtr FromCppDefines();
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const Mips64InstructionSetFeatures* FromCpuInfo();
+ static Mips64FeaturesUniquePtr FromCpuInfo();
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const Mips64InstructionSetFeatures* FromHwcap();
+ static Mips64FeaturesUniquePtr FromHwcap();
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const Mips64InstructionSetFeatures* FromAssembly();
+ static Mips64FeaturesUniquePtr FromAssembly();
bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
@@ -59,8 +62,9 @@
protected:
// Parse a vector of the form "fpu32", "mips2" adding these to a new Mips64InstructionSetFeatures.
- virtual const InstructionSetFeatures*
- AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
+ std::unique_ptr<const InstructionSetFeatures>
+ AddFeaturesFromSplitString(const bool smp,
+ const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE;
private:
diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc
index 0093e82..90b55a9 100644
--- a/runtime/arch/x86/instruction_set_features_x86.cc
+++ b/runtime/arch/x86/instruction_set_features_x86.cc
@@ -49,7 +49,34 @@
"silvermont",
};
-const X86InstructionSetFeatures* X86InstructionSetFeatures::FromVariant(
+X86FeaturesUniquePtr X86InstructionSetFeatures::Create(bool x86_64,
+ bool smp,
+ bool has_SSSE3,
+ bool has_SSE4_1,
+ bool has_SSE4_2,
+ bool has_AVX,
+ bool has_AVX2,
+ bool has_POPCNT) {
+ if (x86_64) {
+ return X86FeaturesUniquePtr(new X86_64InstructionSetFeatures(smp,
+ has_SSSE3,
+ has_SSE4_1,
+ has_SSE4_2,
+ has_AVX,
+ has_AVX2,
+ has_POPCNT));
+ } else {
+ return X86FeaturesUniquePtr(new X86InstructionSetFeatures(smp,
+ has_SSSE3,
+ has_SSE4_1,
+ has_SSE4_2,
+ has_AVX,
+ has_AVX2,
+ has_POPCNT));
+ }
+}
+
+X86FeaturesUniquePtr X86InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED,
bool x86_64) {
bool smp = true; // Conservative default.
@@ -75,17 +102,10 @@
LOG(WARNING) << "Unexpected CPU variant for X86 using defaults: " << variant;
}
- if (x86_64) {
- return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- } else {
- return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- }
+ return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
-const X86InstructionSetFeatures* X86InstructionSetFeatures::FromBitmap(uint32_t bitmap,
- bool x86_64) {
+X86FeaturesUniquePtr X86InstructionSetFeatures::FromBitmap(uint32_t bitmap, bool x86_64) {
bool smp = (bitmap & kSmpBitfield) != 0;
bool has_SSSE3 = (bitmap & kSsse3Bitfield) != 0;
bool has_SSE4_1 = (bitmap & kSse4_1Bitfield) != 0;
@@ -93,16 +113,10 @@
bool has_AVX = (bitmap & kAvxBitfield) != 0;
bool has_AVX2 = (bitmap & kAvxBitfield) != 0;
bool has_POPCNT = (bitmap & kPopCntBitfield) != 0;
- if (x86_64) {
- return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2,
- has_AVX, has_AVX2, has_POPCNT);
- } else {
- return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2,
- has_AVX, has_AVX2, has_POPCNT);
- }
+ return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
-const X86InstructionSetFeatures* X86InstructionSetFeatures::FromCppDefines(bool x86_64) {
+X86FeaturesUniquePtr X86InstructionSetFeatures::FromCppDefines(bool x86_64) {
const bool smp = true;
#ifndef __SSSE3__
@@ -141,16 +155,10 @@
const bool has_POPCNT = true;
#endif
- if (x86_64) {
- return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- } else {
- return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- }
+ return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
-const X86InstructionSetFeatures* X86InstructionSetFeatures::FromCpuInfo(bool x86_64) {
+X86FeaturesUniquePtr X86InstructionSetFeatures::FromCpuInfo(bool x86_64) {
// Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
// the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
bool smp = false;
@@ -198,21 +206,15 @@
} else {
LOG(ERROR) << "Failed to open /proc/cpuinfo";
}
- if (x86_64) {
- return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- } else {
- return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- }
+ return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
-const X86InstructionSetFeatures* X86InstructionSetFeatures::FromHwcap(bool x86_64) {
+X86FeaturesUniquePtr X86InstructionSetFeatures::FromHwcap(bool x86_64) {
UNIMPLEMENTED(WARNING);
return FromCppDefines(x86_64);
}
-const X86InstructionSetFeatures* X86InstructionSetFeatures::FromAssembly(bool x86_64) {
+X86FeaturesUniquePtr X86InstructionSetFeatures::FromAssembly(bool x86_64) {
UNIMPLEMENTED(WARNING);
return FromCppDefines(x86_64);
}
@@ -281,7 +283,7 @@
return result;
}
-const InstructionSetFeatures* X86InstructionSetFeatures::AddFeaturesFromSplitString(
+std::unique_ptr<const InstructionSetFeatures> X86InstructionSetFeatures::AddFeaturesFromSplitString(
const bool smp, const std::vector<std::string>& features, bool x86_64,
std::string* error_msg) const {
bool has_SSSE3 = has_SSSE3_;
@@ -321,13 +323,7 @@
return nullptr;
}
}
- if (x86_64) {
- return new X86_64InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- } else {
- return new X86InstructionSetFeatures(smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX,
- has_AVX2, has_POPCNT);
- }
+ return Create(x86_64, smp, has_SSSE3, has_SSE4_1, has_SSE4_2, has_AVX, has_AVX2, has_POPCNT);
}
} // namespace art
diff --git a/runtime/arch/x86/instruction_set_features_x86.h b/runtime/arch/x86/instruction_set_features_x86.h
index 2aa8ae6..672892e 100644
--- a/runtime/arch/x86/instruction_set_features_x86.h
+++ b/runtime/arch/x86/instruction_set_features_x86.h
@@ -21,30 +21,34 @@
namespace art {
+class X86InstructionSetFeatures;
+using X86FeaturesUniquePtr = std::unique_ptr<const X86InstructionSetFeatures>;
+
// Instruction set features relevant to the X86 architecture.
class X86InstructionSetFeatures : public InstructionSetFeatures {
public:
// Process a CPU variant string like "atom" or "nehalem" and create InstructionSetFeatures.
- static const X86InstructionSetFeatures* FromVariant(const std::string& variant,
- std::string* error_msg,
- bool x86_64 = false);
+ static X86FeaturesUniquePtr FromVariant(const std::string& variant,
+ std::string* error_msg,
+ bool x86_64 = false);
// Parse a bitmap and create an InstructionSetFeatures.
- static const X86InstructionSetFeatures* FromBitmap(uint32_t bitmap, bool x86_64 = false);
+ static X86FeaturesUniquePtr FromBitmap(uint32_t bitmap,
+ bool x86_64 = false);
// Turn C pre-processor #defines into the equivalent instruction set features.
- static const X86InstructionSetFeatures* FromCppDefines(bool x86_64 = false);
+ static X86FeaturesUniquePtr FromCppDefines(bool x86_64 = false);
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const X86InstructionSetFeatures* FromCpuInfo(bool x86_64 = false);
+ static X86FeaturesUniquePtr FromCpuInfo(bool x86_64 = false);
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const X86InstructionSetFeatures* FromHwcap(bool x86_64 = false);
+ static X86FeaturesUniquePtr FromHwcap(bool x86_64 = false);
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const X86InstructionSetFeatures* FromAssembly(bool x86_64 = false);
+ static X86FeaturesUniquePtr FromAssembly(bool x86_64 = false);
bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
@@ -64,13 +68,13 @@
protected:
// Parse a string of the form "ssse3" adding these to a new InstructionSetFeatures.
- virtual const InstructionSetFeatures*
+ virtual std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE {
return AddFeaturesFromSplitString(smp, features, false, error_msg);
}
- const InstructionSetFeatures*
+ std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
bool x86_64, std::string* error_msg) const;
@@ -85,6 +89,15 @@
has_POPCNT_(has_POPCNT) {
}
+ static X86FeaturesUniquePtr Create(bool x86_64,
+ bool smp,
+ bool has_SSSE3,
+ bool has_SSE4_1,
+ bool has_SSE4_2,
+ bool has_AVX,
+ bool has_AVX2,
+ bool has_POPCNT);
+
private:
// Bitmap positions for encoding features as a bitmap.
enum {
diff --git a/runtime/arch/x86_64/instruction_set_features_x86_64.h b/runtime/arch/x86_64/instruction_set_features_x86_64.h
index 0840f89..bc0f708 100644
--- a/runtime/arch/x86_64/instruction_set_features_x86_64.h
+++ b/runtime/arch/x86_64/instruction_set_features_x86_64.h
@@ -21,41 +21,42 @@
namespace art {
+class X86_64InstructionSetFeatures;
+using X86_64FeaturesUniquePtr = std::unique_ptr<const X86_64InstructionSetFeatures>;
+
// Instruction set features relevant to the X86_64 architecture.
class X86_64InstructionSetFeatures FINAL : public X86InstructionSetFeatures {
public:
// Process a CPU variant string like "atom" or "nehalem" and create InstructionSetFeatures.
- static const X86_64InstructionSetFeatures* FromVariant(const std::string& variant,
- std::string* error_msg) {
- return X86InstructionSetFeatures::FromVariant(variant, error_msg, true)
- ->AsX86_64InstructionSetFeatures();
+ static X86_64FeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg) {
+ return Convert(X86InstructionSetFeatures::FromVariant(variant, error_msg, true));
}
// Parse a bitmap and create an InstructionSetFeatures.
- static const X86_64InstructionSetFeatures* FromBitmap(uint32_t bitmap) {
- return X86InstructionSetFeatures::FromBitmap(bitmap, true)->AsX86_64InstructionSetFeatures();
+ static X86_64FeaturesUniquePtr FromBitmap(uint32_t bitmap) {
+ return Convert(X86InstructionSetFeatures::FromBitmap(bitmap, true));
}
// Turn C pre-processor #defines into the equivalent instruction set features.
- static const X86_64InstructionSetFeatures* FromCppDefines() {
- return X86InstructionSetFeatures::FromCppDefines(true)->AsX86_64InstructionSetFeatures();
+ static X86_64FeaturesUniquePtr FromCppDefines() {
+ return Convert(X86InstructionSetFeatures::FromCppDefines(true));
}
// Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures.
- static const X86_64InstructionSetFeatures* FromCpuInfo() {
- return X86InstructionSetFeatures::FromCpuInfo(true)->AsX86_64InstructionSetFeatures();
+ static X86_64FeaturesUniquePtr FromCpuInfo() {
+ return Convert(X86InstructionSetFeatures::FromCpuInfo(true));
}
// Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce
// InstructionSetFeatures.
- static const X86_64InstructionSetFeatures* FromHwcap() {
- return X86InstructionSetFeatures::FromHwcap(true)->AsX86_64InstructionSetFeatures();
+ static X86_64FeaturesUniquePtr FromHwcap() {
+ return Convert(X86InstructionSetFeatures::FromHwcap(true));
}
// Use assembly tests of the current runtime (ie kRuntimeISA) to determine the
// InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo.
- static const X86_64InstructionSetFeatures* FromAssembly() {
- return X86InstructionSetFeatures::FromAssembly(true)->AsX86_64InstructionSetFeatures();
+ static X86_64FeaturesUniquePtr FromAssembly() {
+ return Convert(X86InstructionSetFeatures::FromAssembly(true));
}
InstructionSet GetInstructionSet() const OVERRIDE {
@@ -66,7 +67,7 @@
protected:
// Parse a string of the form "ssse3" adding these to a new InstructionSetFeatures.
- const InstructionSetFeatures*
+ std::unique_ptr<const InstructionSetFeatures>
AddFeaturesFromSplitString(const bool smp, const std::vector<std::string>& features,
std::string* error_msg) const OVERRIDE {
return X86InstructionSetFeatures::AddFeaturesFromSplitString(smp, features, true, error_msg);
@@ -79,6 +80,10 @@
has_AVX2, has_POPCNT) {
}
+ static X86_64FeaturesUniquePtr Convert(X86FeaturesUniquePtr&& in) {
+ return X86_64FeaturesUniquePtr(in.release()->AsX86_64InstructionSetFeatures());
+ }
+
friend class X86InstructionSetFeatures;
DISALLOW_COPY_AND_ASSIGN(X86_64InstructionSetFeatures);