Revision: 11239
Author:   [email protected]
Date:     Thu Apr  5 07:10:39 2012
Log: Minimize uses of lazy initialization by adding explicit initialization functions.

BUG=118686

Review URL: https://chromiumcodereview.appspot.com/9976003
Patch from Philippe Liard <[email protected]>.
http://code.google.com/p/v8/source/detail?r=11239

Modified:
 /branches/bleeding_edge/src/assembler.cc
 /branches/bleeding_edge/src/assembler.h
 /branches/bleeding_edge/src/frames.cc
 /branches/bleeding_edge/src/frames.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/lazy-instance.h
 /branches/bleeding_edge/src/log.cc
 /branches/bleeding_edge/src/log.h
 /branches/bleeding_edge/src/platform-cygwin.cc
 /branches/bleeding_edge/src/platform-freebsd.cc
 /branches/bleeding_edge/src/platform-linux.cc
 /branches/bleeding_edge/src/platform-macos.cc
 /branches/bleeding_edge/src/platform-openbsd.cc
 /branches/bleeding_edge/src/platform-posix.cc
 /branches/bleeding_edge/src/platform-posix.h
 /branches/bleeding_edge/src/platform-solaris.cc
 /branches/bleeding_edge/src/platform-win32.cc
 /branches/bleeding_edge/src/runtime-profiler.cc
 /branches/bleeding_edge/src/runtime-profiler.h
 /branches/bleeding_edge/src/v8.cc
 /branches/bleeding_edge/src/x64/disasm-x64.cc

=======================================
--- /branches/bleeding_edge/src/assembler.cc    Mon Mar 12 06:56:56 2012
+++ /branches/bleeding_edge/src/assembler.cc    Thu Apr  5 07:10:39 2012
@@ -99,21 +99,7 @@
   double the_hole_nan;
 };

-struct InitializeDoubleConstants {
-  static void Construct(DoubleConstant* double_constants) {
-    double_constants->min_int = kMinInt;
-    double_constants->one_half = 0.5;
-    double_constants->minus_zero = -0.0;
-    double_constants->uint8_max_value = 255;
-    double_constants->zero = 0.0;
-    double_constants->canonical_non_hole_nan = OS::nan_value();
-    double_constants->the_hole_nan = BitCast<double>(kHoleNanInt64);
-    double_constants->negative_infinity = -V8_INFINITY;
-  }
-};
-
-static LazyInstance<DoubleConstant, InitializeDoubleConstants>::type
-    double_constants = LAZY_INSTANCE_INITIALIZER;
+static DoubleConstant double_constants;

const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";

@@ -726,6 +712,18 @@
// -----------------------------------------------------------------------------
 // Implementation of ExternalReference

+void ExternalReference::SetUp() {
+  double_constants.min_int = kMinInt;
+  double_constants.one_half = 0.5;
+  double_constants.minus_zero = -0.0;
+  double_constants.uint8_max_value = 255;
+  double_constants.zero = 0.0;
+  double_constants.canonical_non_hole_nan = OS::nan_value();
+  double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64);
+  double_constants.negative_infinity = -V8_INFINITY;
+}
+
+
ExternalReference::ExternalReference(Builtins::CFunctionId id, Isolate* isolate)
   : address_(Redirect(isolate, Builtins::c_function_address(id))) {}

@@ -958,50 +956,47 @@


 ExternalReference ExternalReference::address_of_min_int() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->min_int));
+ return ExternalReference(reinterpret_cast<void*>(&double_constants.min_int));
 }


 ExternalReference ExternalReference::address_of_one_half() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->one_half));
+ return ExternalReference(reinterpret_cast<void*>(&double_constants.one_half));
 }


 ExternalReference ExternalReference::address_of_minus_zero() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->minus_zero));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.minus_zero));
 }


 ExternalReference ExternalReference::address_of_zero() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->zero));
+ return ExternalReference(reinterpret_cast<void*>(&double_constants.zero));
 }


 ExternalReference ExternalReference::address_of_uint8_max_value() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->uint8_max_value));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.uint8_max_value));
 }


 ExternalReference ExternalReference::address_of_negative_infinity() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->negative_infinity));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.negative_infinity));
 }


 ExternalReference ExternalReference::address_of_canonical_non_hole_nan() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->canonical_non_hole_nan));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.canonical_non_hole_nan));
 }


 ExternalReference ExternalReference::address_of_the_hole_nan() {
-  return ExternalReference(reinterpret_cast<void*>(
-      &double_constants.Pointer()->the_hole_nan));
+  return ExternalReference(
+      reinterpret_cast<void*>(&double_constants.the_hole_nan));
 }


=======================================
--- /branches/bleeding_edge/src/assembler.h     Mon Mar 12 06:56:56 2012
+++ /branches/bleeding_edge/src/assembler.h     Thu Apr  5 07:10:39 2012
@@ -535,6 +535,8 @@
     DIRECT_GETTER_CALL
   };

+  static void SetUp();
+
   typedef void* ExternalReferenceRedirector(void* original, Type type);

   ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
=======================================
--- /branches/bleeding_edge/src/frames.cc       Mon Mar 19 05:08:20 2012
+++ /branches/bleeding_edge/src/frames.cc       Thu Apr  5 07:10:39 2012
@@ -1369,24 +1369,23 @@


 struct JSCallerSavedCodeData {
-  JSCallerSavedCodeData() {
-    int i = 0;
-    for (int r = 0; r < kNumRegs; r++)
-      if ((kJSCallerSaved & (1 << r)) != 0)
-        reg_code[i++] = r;
-
-    ASSERT(i == kNumJSCallerSaved);
-  }
   int reg_code[kNumJSCallerSaved];
 };

-
-static LazyInstance<JSCallerSavedCodeData>::type caller_saved_code_data =
-    LAZY_INSTANCE_INITIALIZER;
+JSCallerSavedCodeData caller_saved_code_data;
+
+void SetUpJSCallerSavedCodeData() {
+  int i = 0;
+  for (int r = 0; r < kNumRegs; r++)
+    if ((kJSCallerSaved & (1 << r)) != 0)
+      caller_saved_code_data.reg_code[i++] = r;
+
+  ASSERT(i == kNumJSCallerSaved);
+}

 int JSCallerSavedCode(int n) {
   ASSERT(0 <= n && n < kNumJSCallerSaved);
-  return caller_saved_code_data.Get().reg_code[n];
+  return caller_saved_code_data.reg_code[n];
 }


=======================================
--- /branches/bleeding_edge/src/frames.h        Mon Feb 27 07:15:53 2012
+++ /branches/bleeding_edge/src/frames.h        Thu Apr  5 07:10:39 2012
@@ -40,6 +40,8 @@
 // Get the number of registers in a given register list.
 int NumRegs(RegList list);

+void SetUpJSCallerSavedCodeData();
+
 // Return the code of the n-th saved register available to JavaScript.
 int JSCallerSavedCode(int n);

=======================================
--- /branches/bleeding_edge/src/heap.cc Tue Apr  3 00:32:19 2012
+++ /branches/bleeding_edge/src/heap.cc Thu Apr  5 07:10:39 2012
@@ -42,6 +42,7 @@
 #include "natives.h"
 #include "objects-visiting.h"
 #include "objects-visiting-inl.h"
+#include "once.h"
 #include "runtime-profiler.h"
 #include "scopeinfo.h"
 #include "snapshot.h"
@@ -60,8 +61,6 @@
 namespace v8 {
 namespace internal {

-static LazyMutex gc_initializer_mutex = LAZY_MUTEX_INITIALIZER;
-

 Heap::Heap()
     : isolate_(NULL),
@@ -5849,6 +5848,15 @@
 };

 #endif
+
+
+V8_DECLARE_ONCE(initialize_gc_once);
+
+static void InitializeGCOnce() {
+  InitializeScavengingVisitorsTables();
+  NewSpaceScavenger::Initialize();
+  MarkCompactCollector::Initialize();
+}

 bool Heap::SetUp(bool create_heap_objects) {
 #ifdef DEBUG
@@ -5868,15 +5876,7 @@
     if (!ConfigureHeapDefault()) return false;
   }

-  gc_initializer_mutex.Pointer()->Lock();
-  static bool initialized_gc = false;
-  if (!initialized_gc) {
-      initialized_gc = true;
-      InitializeScavengingVisitorsTables();
-      NewSpaceScavenger::Initialize();
-      MarkCompactCollector::Initialize();
-  }
-  gc_initializer_mutex.Pointer()->Unlock();
+  CallOnce(&initialize_gc_once, &InitializeGCOnce);

   MarkMapPointersAsEncoded(false);

=======================================
--- /branches/bleeding_edge/src/lazy-instance.h Fri Mar 30 13:48:32 2012
+++ /branches/bleeding_edge/src/lazy-instance.h Thu Apr  5 07:10:39 2012
@@ -65,8 +65,12 @@
 //   static LazyInstance<MyClass, MyCreateTrait>::type my_instance =
 //      LAZY_INSTANCE_INITIALIZER;
 //
-// WARNING: This implementation of LazyInstance is NOT thread-safe by default.
-// See ThreadSafeInitOnceTrait declared below for that.
+// WARNINGS:
+// - This implementation of LazyInstance is NOT THREAD-SAFE by default. See
+//   ThreadSafeInitOnceTrait declared below for that.
+// - Lazy initialization comes with a cost. Make sure that you don't use it on
+//   critical path. Consider adding your initialization code to a function
+//   which is explicitly called once.
 //
 // Notes for advanced users:
 // LazyInstance can actually be used in two different ways:
=======================================
--- /branches/bleeding_edge/src/log.cc  Mon Mar 12 06:56:56 2012
+++ /branches/bleeding_edge/src/log.cc  Thu Apr  5 07:10:39 2012
@@ -1730,13 +1730,20 @@
 }

 // Protects the state below.
-static LazyMutex active_samplers_mutex = LAZY_MUTEX_INITIALIZER;
+static Mutex* active_samplers_mutex = NULL;

 List<Sampler*>* SamplerRegistry::active_samplers_ = NULL;


+void SamplerRegistry::SetUp() {
+  if (!active_samplers_mutex) {
+    active_samplers_mutex = OS::CreateMutex();
+  }
+}
+
+
bool SamplerRegistry::IterateActiveSamplers(VisitSampler func, void* param) {
-  ScopedLock lock(active_samplers_mutex.Pointer());
+  ScopedLock lock(active_samplers_mutex);
   for (int i = 0;
        ActiveSamplersExist() && i < active_samplers_->length();
        ++i) {
@@ -1763,7 +1770,7 @@

 void SamplerRegistry::AddActiveSampler(Sampler* sampler) {
   ASSERT(sampler->IsActive());
-  ScopedLock lock(active_samplers_mutex.Pointer());
+  ScopedLock lock(active_samplers_mutex);
   if (active_samplers_ == NULL) {
     active_samplers_ = new List<Sampler*>;
   } else {
@@ -1775,7 +1782,7 @@

 void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) {
   ASSERT(sampler->IsActive());
-  ScopedLock lock(active_samplers_mutex.Pointer());
+  ScopedLock lock(active_samplers_mutex);
   ASSERT(active_samplers_ != NULL);
   bool removed = active_samplers_->RemoveElement(sampler);
   ASSERT(removed);
=======================================
--- /branches/bleeding_edge/src/log.h   Mon Mar 12 06:56:56 2012
+++ /branches/bleeding_edge/src/log.h   Thu Apr  5 07:10:39 2012
@@ -437,6 +437,8 @@
     HAS_CPU_PROFILING_SAMPLERS
   };

+  static void SetUp();
+
   typedef void (*VisitSampler)(Sampler*, void*);

   static State GetState();
=======================================
--- /branches/bleeding_edge/src/platform-cygwin.cc      Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-cygwin.cc      Thu Apr  5 07:10:39 2012
@@ -62,22 +62,8 @@
 static Mutex* limit_mutex = NULL;


-void OS::SetUp() {
-  // Seed the random number generator.
- // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly can cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that
-  // call this setup code within the same millisecond.
-  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
-  srandom(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-}
-
-
 void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
-  // CPU.
-  MathSetup();
+  POSIXPostSetUp();
 }

 uint64_t OS::CpuFeaturesImpliedByPlatform() {
@@ -633,9 +619,15 @@
   explicit SamplerThread(int interval)
       : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       instance_ = new SamplerThread(sampler->interval());
@@ -646,7 +638,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -732,7 +724,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SamplerThread* instance_;

  private:
@@ -740,10 +732,23 @@
 };


-LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SamplerThread::mutex_ = NULL;
 SamplerThread* SamplerThread::instance_ = NULL;


+void OS::SetUp() {
+  // Seed the random number generator.
+ // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly can cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SamplerThread::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/platform-freebsd.cc     Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-freebsd.cc     Thu Apr  5 07:10:39 2012
@@ -80,22 +80,8 @@
 static Mutex* limit_mutex = NULL;


-void OS::SetUp() {
-  // Seed the random number generator.
- // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly can cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that
-  // call this setup code within the same millisecond.
-  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
-  srandom(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-}
-
-
 void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
-  // CPU.
-  MathSetup();
+  POSIXPostSetUp();
 }


@@ -729,9 +715,15 @@
   explicit SignalSender(int interval)
       : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Install a signal handler.
@@ -751,7 +743,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -844,7 +836,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -853,12 +845,25 @@
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };

-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 SignalSender* SignalSender::instance_ = NULL;
 struct sigaction SignalSender::old_signal_handler_;
 bool SignalSender::signal_handler_installed_ = false;


+void OS::SetUp() {
+  // Seed the random number generator.
+ // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly can cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SignalSender::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/platform-linux.cc       Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-linux.cc       Thu Apr  5 07:10:39 2012
@@ -79,37 +79,8 @@
 static Mutex* limit_mutex = NULL;


-void OS::SetUp() {
-  // Seed the random number generator. We preserve microsecond resolution.
-  uint64_t seed = Ticks() ^ (getpid() << 16);
-  srandom(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-
-#ifdef __arm__
-  // When running on ARM hardware check that the EABI used by V8 and
-  // by the C code is the same.
-  bool hard_float = OS::ArmUsingHardFloat();
-  if (hard_float) {
-#if !USE_EABI_HARDFLOAT
-    PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without "
-           "-DUSE_EABI_HARDFLOAT\n");
-    exit(1);
-#endif
-  } else {
-#if USE_EABI_HARDFLOAT
-    PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with "
-           "-DUSE_EABI_HARDFLOAT\n");
-    exit(1);
-#endif
-  }
-#endif
-}
-
-
 void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
-  // CPU.
-  MathSetup();
+  POSIXPostSetUp();
 }


@@ -1083,6 +1054,12 @@
       : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
         vm_tgid_(getpid()),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void InstallSignalHandler() {
     struct sigaction sa;
@@ -1101,7 +1078,7 @@
   }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Start a thread that will send SIGPROF signal to VM threads,
@@ -1114,7 +1091,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -1217,7 +1194,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -1227,12 +1204,40 @@
 };


-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 SignalSender* SignalSender::instance_ = NULL;
 struct sigaction SignalSender::old_signal_handler_;
 bool SignalSender::signal_handler_installed_ = false;


+void OS::SetUp() {
+  // Seed the random number generator. We preserve microsecond resolution.
+  uint64_t seed = Ticks() ^ (getpid() << 16);
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+
+#ifdef __arm__
+  // When running on ARM hardware check that the EABI used by V8 and
+  // by the C code is the same.
+  bool hard_float = OS::ArmUsingHardFloat();
+  if (hard_float) {
+#if !USE_EABI_HARDFLOAT
+    PrintF("ERROR: Binary compiled with -mfloat-abi=hard but without "
+           "-DUSE_EABI_HARDFLOAT\n");
+    exit(1);
+#endif
+  } else {
+#if USE_EABI_HARDFLOAT
+    PrintF("ERROR: Binary not compiled with -mfloat-abi=hard but with "
+           "-DUSE_EABI_HARDFLOAT\n");
+    exit(1);
+#endif
+  }
+#endif
+  SignalSender::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/platform-macos.cc       Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-macos.cc       Thu Apr  5 07:10:39 2012
@@ -94,18 +94,8 @@
 static Mutex* limit_mutex = NULL;


-void OS::SetUp() {
-  // Seed the random number generator. We preserve microsecond resolution.
-  uint64_t seed = Ticks() ^ (getpid() << 16);
-  srandom(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-}
-
-
 void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
-  // CPU.
-  MathSetup();
+  POSIXPostSetUp();
 }


@@ -752,9 +742,15 @@
   explicit SamplerThread(int interval)
       : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       instance_ = new SamplerThread(sampler->interval());
@@ -765,7 +761,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -862,7 +858,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SamplerThread* instance_;

  private:
@@ -872,10 +868,19 @@
 #undef REGISTER_FIELD


-LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SamplerThread::mutex_ = NULL;
 SamplerThread* SamplerThread::instance_ = NULL;


+void OS::SetUp() {
+  // Seed the random number generator. We preserve microsecond resolution.
+  uint64_t seed = Ticks() ^ (getpid() << 16);
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SamplerThread::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/platform-openbsd.cc     Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-openbsd.cc     Thu Apr  5 07:10:39 2012
@@ -98,20 +98,10 @@
   }
   return NULL;
 }
-
-
-void OS::SetUp() {
-  // Seed the random number generator. We preserve microsecond resolution.
-  uint64_t seed = Ticks() ^ (getpid() << 16);
-  srandom(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-}


 void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
-  // CPU.
-  MathSetup();
+  POSIXPostSetUp();
 }


@@ -802,6 +792,12 @@
       : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
         vm_tgid_(getpid()),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void InstallSignalHandler() {
     struct sigaction sa;
@@ -820,7 +816,7 @@
   }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Start a thread that will send SIGPROF signal to VM threads,
@@ -833,7 +829,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -927,7 +923,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -937,12 +933,21 @@
 };


-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 SignalSender* SignalSender::instance_ = NULL;
 struct sigaction SignalSender::old_signal_handler_;
 bool SignalSender::signal_handler_installed_ = false;


+void OS::SetUp() {
+  // Seed the random number generator. We preserve microsecond resolution.
+  uint64_t seed = Ticks() ^ (getpid() << 16);
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SignalSender::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/platform-posix.cc       Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-posix.cc       Thu Apr  5 07:10:39 2012
@@ -147,15 +147,6 @@
 #undef MATH_FUNCTION


-void MathSetup() {
-  init_fast_sin_function();
-  init_fast_cos_function();
-  init_fast_tan_function();
-  init_fast_log_function();
-  init_fast_sqrt_function();
-}
-
-
 double OS::nan_value() {
   // NAN from math.h is defined in C99 and not in POSIX.
   return NAN;
@@ -313,20 +304,11 @@

 #if defined(V8_TARGET_ARCH_IA32)
 static OS::MemCopyFunction memcopy_function = NULL;
-static LazyMutex memcopy_function_mutex = LAZY_MUTEX_INITIALIZER;
 // Defined in codegen-ia32.cc.
 OS::MemCopyFunction CreateMemCopyFunction();

 // Copy memory area to disjoint memory area.
 void OS::MemCopy(void* dest, const void* src, size_t size) {
-  if (memcopy_function == NULL) {
-    ScopedLock lock(memcopy_function_mutex.Pointer());
-    if (memcopy_function == NULL) {
-      OS::MemCopyFunction temp = CreateMemCopyFunction();
-      MemoryBarrier();
-      memcopy_function = temp;
-    }
-  }
   // Note: here we rely on dependent reads being ordered. This is true
   // on all architectures we currently support.
   (*memcopy_function)(dest, src, size);
@@ -335,6 +317,18 @@
 #endif
 }
 #endif  // V8_TARGET_ARCH_IA32
+
+
+void POSIXPostSetUp() {
+#if defined(V8_TARGET_ARCH_IA32)
+  memcopy_function = CreateMemCopyFunction();
+#endif
+  init_fast_sin_function();
+  init_fast_cos_function();
+  init_fast_tan_function();
+  init_fast_log_function();
+  init_fast_sqrt_function();
+}

// ----------------------------------------------------------------------------
 // POSIX string support.
=======================================
--- /branches/bleeding_edge/src/platform-posix.h        Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-posix.h        Thu Apr  5 07:10:39 2012
@@ -31,9 +31,8 @@
 namespace v8 {
 namespace internal {

-// Used by platform implementation files during OS::PostSetUp() to initialize
-// the math functions.
-void MathSetup();
+// Used by platform implementation files during OS::PostSetUp().
+void POSIXPostSetUp();

 } }  // namespace v8::internal

=======================================
--- /branches/bleeding_edge/src/platform-solaris.cc     Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/platform-solaris.cc     Thu Apr  5 07:10:39 2012
@@ -91,22 +91,10 @@


 static Mutex* limit_mutex = NULL;
-void OS::SetUp() {
-  // Seed the random number generator.
- // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly will cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that
-  // call this setup code within the same millisecond.
-  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
-  srandom(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-}


 void OS::PostSetUp() {
- // Math functions depend on CPU features therefore they are initialized after
-  // CPU.
-  MathSetup();
+  POSIXPostSetUp();
 }


@@ -723,6 +711,12 @@
   explicit SignalSender(int interval)
       : Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void InstallSignalHandler() {
     struct sigaction sa;
@@ -741,7 +735,7 @@
   }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       // Start a thread that will send SIGPROF signal to VM threads,
@@ -754,7 +748,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -848,7 +842,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SignalSender* instance_;
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
@@ -857,12 +851,25 @@
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };

-LazyMutex SignalSender::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SignalSender::mutex_ = NULL;
 SignalSender* SignalSender::instance_ = NULL;
 struct sigaction SignalSender::old_signal_handler_;
 bool SignalSender::signal_handler_installed_ = false;


+void OS::SetUp() {
+  // Seed the random number generator.
+ // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly will cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srandom(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SignalSender::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/platform-win32.cc       Fri Mar 30 13:48:32 2012
+++ /branches/bleeding_edge/src/platform-win32.cc       Thu Apr  5 07:10:39 2012
@@ -141,20 +141,11 @@

 #if defined(V8_TARGET_ARCH_IA32)
 static OS::MemCopyFunction memcopy_function = NULL;
-static LazyMutex memcopy_function_mutex = LAZY_MUTEX_INITIALIZER;
 // Defined in codegen-ia32.cc.
 OS::MemCopyFunction CreateMemCopyFunction();

 // Copy memory area to disjoint memory area.
 void OS::MemCopy(void* dest, const void* src, size_t size) {
-  if (memcopy_function == NULL) {
-    ScopedLock lock(memcopy_function_mutex.Pointer());
-    if (memcopy_function == NULL) {
-      OS::MemCopyFunction temp = CreateMemCopyFunction();
-      MemoryBarrier();
-      memcopy_function = temp;
-    }
-  }
   // Note: here we rely on dependent reads being ordered. This is true
   // on all architectures we currently support.
   (*memcopy_function)(dest, src, size);
@@ -561,24 +552,15 @@
   // saving is in effect at the given time.
   return InDST() ? dst_tz_name_ : std_tz_name_;
 }
-
-
-void OS::SetUp() {
-  // Seed the random number generator.
- // Convert the current time to a 64-bit integer first, before converting it - // to an unsigned. Going directly can cause an overflow and the seed to be - // set to all ones. The seed will be identical for different instances that
-  // call this setup code within the same millisecond.
-  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
-  srand(static_cast<unsigned int>(seed));
-  limit_mutex = CreateMutex();
-}


 void OS::PostSetUp() {
// Math functions depend on CPU features therefore they are initialized after
   // CPU.
   MathSetup();
+#if defined(V8_TARGET_ARCH_IA32)
+  memcopy_function = CreateMemCopyFunction();
+#endif
 }


@@ -1966,9 +1948,15 @@
   explicit SamplerThread(int interval)
       : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)),
         interval_(interval) {}
+
+  static void SetUp() {
+    if (!mutex_) {
+      mutex_ = OS::CreateMutex();
+    }
+  }

   static void AddActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::AddActiveSampler(sampler);
     if (instance_ == NULL) {
       instance_ = new SamplerThread(sampler->interval());
@@ -1979,7 +1967,7 @@
   }

   static void RemoveActiveSampler(Sampler* sampler) {
-    ScopedLock lock(mutex_.Pointer());
+    ScopedLock lock(mutex_);
     SamplerRegistry::RemoveActiveSampler(sampler);
     if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
       RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_);
@@ -2065,7 +2053,7 @@
   RuntimeProfilerRateLimiter rate_limiter_;

   // Protects the process wide state below.
-  static LazyMutex mutex_;
+  static Mutex* mutex_;
   static SamplerThread* instance_;

  private:
@@ -2073,10 +2061,23 @@
 };


-LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER;
+Mutex* SamplerThread::mutex_ = NULL;
 SamplerThread* SamplerThread::instance_ = NULL;


+void OS::SetUp() {
+  // Seed the random number generator.
+ // Convert the current time to a 64-bit integer first, before converting it + // to an unsigned. Going directly can cause an overflow and the seed to be + // set to all ones. The seed will be identical for different instances that
+  // call this setup code within the same millisecond.
+  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
+  srand(static_cast<unsigned int>(seed));
+  limit_mutex = CreateMutex();
+  SamplerThread::SetUp();
+}
+
+
 Sampler::Sampler(Isolate* isolate, int interval)
     : isolate_(isolate),
       interval_(interval),
=======================================
--- /branches/bleeding_edge/src/runtime-profiler.cc     Tue Mar 27 05:26:58 2012
+++ /branches/bleeding_edge/src/runtime-profiler.cc     Thu Apr  5 07:10:39 2012
@@ -101,7 +101,7 @@
 }


-void RuntimeProfiler::GlobalSetup() {
+void RuntimeProfiler::GlobalSetUp() {
   ASSERT(!has_been_globally_set_up_);
   enabled_ = V8::UseCrankshaft() && FLAG_opt;
 #ifdef DEBUG
=======================================
--- /branches/bleeding_edge/src/runtime-profiler.h      Tue Mar 27 05:26:58 2012
+++ /branches/bleeding_edge/src/runtime-profiler.h      Thu Apr  5 07:10:39 2012
@@ -43,7 +43,7 @@
  public:
   explicit RuntimeProfiler(Isolate* isolate);

-  static void GlobalSetup();
+  static void GlobalSetUp();

   static inline bool IsEnabled() {
     ASSERT(has_been_globally_set_up_);
=======================================
--- /branches/bleeding_edge/src/v8.cc   Fri Mar 30 07:30:46 2012
+++ /branches/bleeding_edge/src/v8.cc   Thu Apr  5 07:10:39 2012
@@ -27,11 +27,13 @@

 #include "v8.h"

+#include "assembler.h"
 #include "isolate.h"
 #include "elements.h"
 #include "bootstrapper.h"
 #include "debug.h"
 #include "deoptimizer.h"
+#include "frames.h"
 #include "heap-profiler.h"
 #include "hydrogen.h"
 #include "lithium-allocator.h"
@@ -262,7 +264,7 @@

   OS::PostSetUp();

-  RuntimeProfiler::GlobalSetup();
+  RuntimeProfiler::GlobalSetUp();

   ElementsAccessor::InitializeOncePerProcess();

@@ -273,6 +275,9 @@
   }

   LOperand::SetUpCaches();
+  SetUpJSCallerSavedCodeData();
+  SamplerRegistry::SetUp();
+  ExternalReference::SetUp();
 }

 void V8::InitializeOncePerProcess() {
=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc       Mon Mar 12 06:56:56 2012
+++ /branches/bleeding_edge/src/x64/disasm-x64.cc       Thu Apr  5 07:10:39 2012
@@ -315,7 +315,8 @@
         rex_(0),
         operand_size_(0),
         group_1_prefix_(0),
-        byte_size_operand_(false) {
+        byte_size_operand_(false),
+        instruction_table_(instruction_table.Pointer()) {
     tmp_buffer_[0] = '\0';
   }

@@ -344,6 +345,7 @@
byte group_1_prefix_; // 0xF2, 0xF3, or (if no group 1 prefix is present) 0.
   // Byte size operand override.
   bool byte_size_operand_;
+  const InstructionTable* const instruction_table_;

   void setRex(byte rex) {
     ASSERT_EQ(0x40, rex & 0xF0);
@@ -1340,7 +1342,7 @@
     data++;
   }

-  const InstructionDesc& idesc = instruction_table.Get().Get(current);
+  const InstructionDesc& idesc = instruction_table_->Get(current);
   byte_size_operand_ = idesc.byte_size_operation;
   switch (idesc.type) {
     case ZERO_OPERANDS_INSTR:

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to