Commit 256de323 authored by olivf@chromium.org's avatar olivf@chromium.org

Ensure only whitelisted stubs have sse2 versions in the snapshot.

BUG=
R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/26680002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17123 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fc952077
......@@ -50,6 +50,7 @@ bool CpuFeatures::initialized_ = false;
#endif
unsigned CpuFeatures::supported_ = 0;
unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
unsigned CpuFeatures::cross_compile_ = 0;
unsigned CpuFeatures::cache_line_size_ = 64;
......
......@@ -64,23 +64,41 @@ class CpuFeatures : public AllStatic {
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
ASSERT(initialized_);
return (supported_ & (1u << f)) != 0;
return Check(f, supported_);
}
static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
ASSERT(initialized_);
return (found_by_runtime_probing_only_ &
(static_cast<uint64_t>(1) << f)) != 0;
return Check(f, found_by_runtime_probing_only_);
}
static bool IsSafeForSnapshot(CpuFeature f) {
return (IsSupported(f) &&
return Check(f, cross_compile_) ||
(IsSupported(f) &&
(!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
}
static unsigned cache_line_size() { return cache_line_size_; }
static bool VerifyCrossCompiling() {
return cross_compile_ == 0;
}
static bool VerifyCrossCompiling(CpuFeature f) {
unsigned mask = flag2set(f);
return cross_compile_ == 0 ||
(cross_compile_ & mask) == mask;
}
private:
static bool Check(CpuFeature f, unsigned set) {
return (set & flag2set(f)) != 0;
}
static unsigned flag2set(CpuFeature f) {
return 1u << f;
}
#ifdef DEBUG
static bool initialized_;
#endif
......@@ -88,6 +106,8 @@ class CpuFeatures : public AllStatic {
static unsigned found_by_runtime_probing_only_;
static unsigned cache_line_size_;
static unsigned cross_compile_;
friend class ExternalReference;
friend class PlatformFeatureScope;
DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
......
......@@ -210,19 +210,14 @@ CpuFeatureScope::~CpuFeatureScope() {
// Implementation of PlatformFeatureScope
PlatformFeatureScope::PlatformFeatureScope(CpuFeature f)
: old_supported_(CpuFeatures::supported_),
old_found_by_runtime_probing_only_(
CpuFeatures::found_by_runtime_probing_only_) {
: old_cross_compile_(CpuFeatures::cross_compile_) {
uint64_t mask = static_cast<uint64_t>(1) << f;
CpuFeatures::supported_ |= mask;
CpuFeatures::found_by_runtime_probing_only_ &= ~mask;
CpuFeatures::cross_compile_ |= mask;
}
PlatformFeatureScope::~PlatformFeatureScope() {
CpuFeatures::supported_ = old_supported_;
CpuFeatures::found_by_runtime_probing_only_ =
old_found_by_runtime_probing_only_;
CpuFeatures::cross_compile_ = old_cross_compile_;
}
......
......@@ -142,8 +142,7 @@ class PlatformFeatureScope BASE_EMBEDDED {
~PlatformFeatureScope();
private:
uint64_t old_supported_;
uint64_t old_found_by_runtime_probing_only_;
uint64_t old_cross_compile_;
};
......
......@@ -129,6 +129,11 @@ Handle<Code> PlatformCodeStub::GenerateCode(Isolate* isolate) {
}
void CodeStub::VerifyPlatformFeatures(Isolate* isolate) {
ASSERT(CpuFeatures::VerifyCrossCompiling());
}
Handle<Code> CodeStub::GetCode(Isolate* isolate) {
Factory* factory = isolate->factory();
Heap* heap = isolate->heap();
......@@ -141,6 +146,10 @@ Handle<Code> CodeStub::GetCode(Isolate* isolate) {
return Handle<Code>(code);
}
#ifdef DEBUG
VerifyPlatformFeatures(isolate);
#endif
{
HandleScope scope(isolate);
......@@ -297,8 +306,6 @@ void BinaryOpStub::GenerateAheadOfTime(Isolate* isolate) {
// expensive at runtime. When solved we should be able to add most binops to
// the snapshot instead of hand-picking them.
// Generated list of commonly used stubs
Generate(Token::ADD, GENERIC, STRING, STRING, NO_OVERWRITE, isolate);
Generate(Token::ADD, GENERIC, STRING, STRING, OVERWRITE_RIGHT, isolate);
Generate(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE, isolate);
Generate(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
Generate(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE, isolate);
......@@ -326,12 +333,6 @@ void BinaryOpStub::GenerateAheadOfTime(Isolate* isolate) {
Generate(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT, isolate);
Generate(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT, isolate);
Generate(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT, isolate);
Generate(Token::ADD, STRING, GENERIC, STRING, NO_OVERWRITE, isolate);
Generate(Token::ADD, STRING, GENERIC, STRING, OVERWRITE_LEFT, isolate);
Generate(Token::ADD, STRING, GENERIC, STRING, OVERWRITE_RIGHT, isolate);
Generate(Token::ADD, STRING, STRING, STRING, NO_OVERWRITE, isolate);
Generate(Token::ADD, STRING, STRING, STRING, OVERWRITE_LEFT, isolate);
Generate(Token::ADD, STRING, STRING, STRING, OVERWRITE_RIGHT, isolate);
Generate(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE, isolate);
Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT, isolate);
Generate(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT, isolate);
......
......@@ -209,6 +209,7 @@ class CodeStub BASE_EMBEDDED {
// Generates the assembler code for the stub.
virtual Handle<Code> GenerateCode(Isolate* isolate) = 0;
virtual void VerifyPlatformFeatures(Isolate* isolate);
// Returns whether the code generated for this stub needs to be allocated as
// a fixed (non-moveable) code object.
......@@ -1043,6 +1044,10 @@ class BinaryOpStub: public HydrogenCodeStub {
return MONOMORPHIC;
}
virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
}
virtual Code::ExtraICState GetExtraICState() {
bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI &&
CpuFeatures::IsSafeForSnapshot(SSE2);
......@@ -1348,6 +1353,11 @@ class CEntryStub : public PlatformCodeStub {
virtual bool IsPregenerated(Isolate* isolate) V8_OVERRIDE;
static void GenerateAheadOfTime(Isolate* isolate);
protected:
virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
};
private:
void GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception,
......@@ -1766,6 +1776,11 @@ class DoubleToIStub : public PlatformCodeStub {
virtual bool SometimesSetsUpAFrame() { return false; }
protected:
virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
}
private:
static const int kBitsPerRegisterNumber = 6;
STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
......
......@@ -53,6 +53,7 @@ bool CpuFeatures::initialized_ = false;
#endif
uint64_t CpuFeatures::supported_ = 0;
uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
uint64_t CpuFeatures::cross_compile_ = 0;
ExternalReference ExternalReference::cpu_features() {
......
......@@ -535,31 +535,52 @@ class CpuFeatures : public AllStatic {
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
ASSERT(initialized_);
if (Check(f, cross_compile_)) return true;
if (f == SSE2 && !FLAG_enable_sse2) return false;
if (f == SSE3 && !FLAG_enable_sse3) return false;
if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
if (f == CMOV && !FLAG_enable_cmov) return false;
return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
return Check(f, supported_);
}
static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
ASSERT(initialized_);
return (found_by_runtime_probing_only_ &
(static_cast<uint64_t>(1) << f)) != 0;
return Check(f, found_by_runtime_probing_only_);
}
static bool IsSafeForSnapshot(CpuFeature f) {
return (IsSupported(f) &&
return Check(f, cross_compile_) ||
(IsSupported(f) &&
(!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
}
static bool VerifyCrossCompiling() {
return cross_compile_ == 0;
}
static bool VerifyCrossCompiling(CpuFeature f) {
uint64_t mask = flag2set(f);
return cross_compile_ == 0 ||
(cross_compile_ & mask) == mask;
}
private:
static bool Check(CpuFeature f, uint64_t set) {
return (set & flag2set(f)) != 0;
}
static uint64_t flag2set(CpuFeature f) {
return static_cast<uint64_t>(1) << f;
}
#ifdef DEBUG
static bool initialized_;
#endif
static uint64_t supported_;
static uint64_t found_by_runtime_probing_only_;
static uint64_t cross_compile_;
friend class ExternalReference;
friend class PlatformFeatureScope;
DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
......
......@@ -48,6 +48,7 @@ bool CpuFeatures::initialized_ = false;
#endif
unsigned CpuFeatures::supported_ = 0;
unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
unsigned CpuFeatures::cross_compile_ = 0;
ExternalReference ExternalReference::cpu_features() {
......
......@@ -411,27 +411,47 @@ class CpuFeatures : public AllStatic {
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
ASSERT(initialized_);
return (supported_ & (1u << f)) != 0;
return Check(f, supported_);
}
static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
ASSERT(initialized_);
return (found_by_runtime_probing_only_ &
(static_cast<uint64_t>(1) << f)) != 0;
return Check(f, found_by_runtime_probing_only_);
}
static bool IsSafeForSnapshot(CpuFeature f) {
return (IsSupported(f) &&
return Check(f, cross_compile_) ||
(IsSupported(f) &&
(!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
}
static bool VerifyCrossCompiling() {
return cross_compile_ == 0;
}
static bool VerifyCrossCompiling(CpuFeature f) {
unsigned mask = flag2set(f);
return cross_compile_ == 0 ||
(cross_compile_ & mask) == mask;
}
private:
static bool Check(CpuFeature f, unsigned set) {
return (set & flag2set(f)) != 0;
}
static unsigned flag2set(CpuFeature f) {
return 1u << f;
}
#ifdef DEBUG
static bool initialized_;
#endif
static unsigned supported_;
static unsigned found_by_runtime_probing_only_;
static unsigned cross_compile_;
friend class ExternalReference;
friend class PlatformFeatureScope;
DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
......
......@@ -44,7 +44,7 @@ bool CpuFeatures::initialized_ = false;
#endif
uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures;
uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
uint64_t CpuFeatures::cross_compile_ = 0;
ExternalReference ExternalReference::cpu_features() {
ASSERT(CpuFeatures::initialized_);
......
......@@ -471,26 +471,45 @@ class CpuFeatures : public AllStatic {
// Check whether a feature is supported by the target CPU.
static bool IsSupported(CpuFeature f) {
if (Check(f, cross_compile_)) return true;
ASSERT(initialized_);
if (f == SSE3 && !FLAG_enable_sse3) return false;
if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
if (f == CMOV && !FLAG_enable_cmov) return false;
if (f == SAHF && !FLAG_enable_sahf) return false;
return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
return Check(f, supported_);
}
static bool IsFoundByRuntimeProbingOnly(CpuFeature f) {
ASSERT(initialized_);
return (found_by_runtime_probing_only_ &
(static_cast<uint64_t>(1) << f)) != 0;
return Check(f, found_by_runtime_probing_only_);
}
static bool IsSafeForSnapshot(CpuFeature f) {
return (IsSupported(f) &&
return Check(f, cross_compile_) ||
(IsSupported(f) &&
(!Serializer::enabled() || !IsFoundByRuntimeProbingOnly(f)));
}
static bool VerifyCrossCompiling() {
return cross_compile_ == 0;
}
static bool VerifyCrossCompiling(CpuFeature f) {
uint64_t mask = flag2set(f);
return cross_compile_ == 0 ||
(cross_compile_ & mask) == mask;
}
private:
static bool Check(CpuFeature f, uint64_t set) {
return (set & flag2set(f)) != 0;
}
static uint64_t flag2set(CpuFeature f) {
return static_cast<uint64_t>(1) << f;
}
// Safe defaults include CMOV for X64. It is always available, if
// anyone checks, but they shouldn't need to check.
// The required user mode extensions in X64 are (from AMD64 ABI Table A.1):
......@@ -503,6 +522,8 @@ class CpuFeatures : public AllStatic {
static uint64_t supported_;
static uint64_t found_by_runtime_probing_only_;
static uint64_t cross_compile_;
friend class ExternalReference;
friend class PlatformFeatureScope;
DISALLOW_COPY_AND_ASSIGN(CpuFeatures);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment