Ensure only whitelisted stubs have sse2 versions in the snapshot.
authorolivf@chromium.org <olivf@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 10 Oct 2013 08:45:40 +0000 (08:45 +0000)
committerolivf@chromium.org <olivf@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 10 Oct 2013 08:45:40 +0000 (08:45 +0000)
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

12 files changed:
src/arm/assembler-arm.cc
src/arm/assembler-arm.h
src/assembler.cc
src/assembler.h
src/code-stubs.cc
src/code-stubs.h
src/ia32/assembler-ia32.cc
src/ia32/assembler-ia32.h
src/mips/assembler-mips.cc
src/mips/assembler-mips.h
src/x64/assembler-x64.cc
src/x64/assembler-x64.h

index bd8b0613eb9bea99a87c3f549b12069cbd8c858a..05b25ae2d7a525194832df5c2832f1f40b9a79ea 100644 (file)
@@ -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;
 
 
index 47dda2aa7224cd6622e997a1621fac6996a4cf2b..8caa64df34c2ce442b4919122c45b531dd06c864 100644 (file)
@@ -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);
index 6581aa1305a459fdc8c90b31d0a9faabf9f78169..cd2bedd4287ea40655c12f56a5442e51c198d826 100644 (file)
@@ -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_;
 }
 
 
index 12200740a0becb3ff604b6622be73f73226badfc..3bba98bb7dded9408319160478a39be062846a16 100644 (file)
@@ -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_;
 };
 
 
index 75b880712c9fc66236a6e897cc6bd50df40fac86..0911d9a9aba61405e4a661f022106d336661aa1a 100644 (file)
@@ -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);
index 9b25319a9b82716db689057d95c94d9de2e63ec5..d2101ae293b6cee60ef3ca597bc483ab9b4d18ba 100644 (file)
@@ -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);
index c2e843197f674b6cccff95f2cd99f3c309c162a7..a4412d0b3fd46eebb10bd6ffc4ed277fe6fa30b4 100644 (file)
@@ -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() {
index 7c3999b85f112ab9a80c4967c9ecddcb9a4a4b3f..07851f865cc1da08504f9b9631045ae1480aac97 100644 (file)
@@ -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);
index 345b642454b1b5c09669743eca17a9b5876cac8e..0972a8295cbe40ab049649d9035c783f3cf42e8d 100644 (file)
@@ -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() {
index 3a0ea4020375505c6435831d248451cbd3b1d9ee..2468c3c340c7b8a9ec5dfe331b0b3ae0d2f6a941 100644 (file)
@@ -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);
index b6a28fca9efff62ef414a5857d55e86fd61f29db..aedfa07166cec625a2776fa3722dba54e79d2f40 100644 (file)
@@ -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_);
index f4cc4a39c5954993e2101afe3beb550a16605804..fd1e1e75d55db829fb6f1723543c8fab7611ada6 100644 (file)
@@ -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);