Minimize uses of lazy initialization by adding explicit initialization functions.
BUG=118686 Review URL: https://chromiumcodereview.appspot.com/9976003 Patch from Philippe Liard <pliard@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11239 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ed5d288ac1
commit
db86043160
@ -99,21 +99,7 @@ struct DoubleConstant BASE_EMBEDDED {
|
||||
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 @@ void RelocInfo::Verify() {
|
||||
// -----------------------------------------------------------------------------
|
||||
// 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::scheduled_exception_address(
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -535,6 +535,8 @@ class ExternalReference BASE_EMBEDDED {
|
||||
DIRECT_GETTER_CALL
|
||||
};
|
||||
|
||||
static void SetUp();
|
||||
|
||||
typedef void* ExternalReferenceRedirector(void* original, Type type);
|
||||
|
||||
ExternalReference(Builtins::CFunctionId id, Isolate* isolate);
|
||||
|
@ -1369,24 +1369,23 @@ int NumRegs(RegList reglist) {
|
||||
|
||||
|
||||
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];
|
||||
};
|
||||
|
||||
JSCallerSavedCodeData caller_saved_code_data;
|
||||
|
||||
static LazyInstance<JSCallerSavedCodeData>::type caller_saved_code_data =
|
||||
LAZY_INSTANCE_INITIALIZER;
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,8 @@ typedef uint32_t RegList;
|
||||
// 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);
|
||||
|
||||
|
22
src/heap.cc
22
src/heap.cc
@ -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),
|
||||
@ -5850,6 +5849,15 @@ class HeapDebugUtils {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
V8_DECLARE_ONCE(initialize_gc_once);
|
||||
|
||||
static void InitializeGCOnce() {
|
||||
InitializeScavengingVisitorsTables();
|
||||
NewSpaceScavenger::Initialize();
|
||||
MarkCompactCollector::Initialize();
|
||||
}
|
||||
|
||||
bool Heap::SetUp(bool create_heap_objects) {
|
||||
#ifdef DEBUG
|
||||
allocation_timeout_ = FLAG_gc_interval;
|
||||
@ -5868,15 +5876,7 @@ bool Heap::SetUp(bool create_heap_objects) {
|
||||
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);
|
||||
|
||||
|
@ -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:
|
||||
|
15
src/log.cc
15
src/log.cc
@ -1730,13 +1730,20 @@ void Logger::EnableSlidingStateWindow() {
|
||||
}
|
||||
|
||||
// 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 @@ SamplerRegistry::State SamplerRegistry::GetState() {
|
||||
|
||||
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::AddActiveSampler(Sampler* sampler) {
|
||||
|
||||
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);
|
||||
|
@ -437,6 +437,8 @@ class SamplerRegistry : public AllStatic {
|
||||
HAS_CPU_PROFILING_SAMPLERS
|
||||
};
|
||||
|
||||
static void SetUp();
|
||||
|
||||
typedef void (*VisitSampler)(Sampler*, void*);
|
||||
|
||||
static State GetState();
|
||||
|
@ -62,22 +62,8 @@ double ceiling(double x) {
|
||||
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() {
|
||||
@ -634,8 +620,14 @@ class SamplerThread : public Thread {
|
||||
: 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 @@ class SamplerThread : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SamplerThread : public Thread {
|
||||
RuntimeProfilerRateLimiter rate_limiter_;
|
||||
|
||||
// Protects the process wide state below.
|
||||
static LazyMutex mutex_;
|
||||
static Mutex* mutex_;
|
||||
static SamplerThread* instance_;
|
||||
|
||||
private:
|
||||
@ -740,10 +732,23 @@ class SamplerThread : public Thread {
|
||||
};
|
||||
|
||||
|
||||
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),
|
||||
|
@ -80,22 +80,8 @@ double ceiling(double x) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -730,8 +716,14 @@ class SignalSender : public Thread {
|
||||
: 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 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
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 @@ class SignalSender : public Thread {
|
||||
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),
|
||||
|
@ -79,37 +79,8 @@ double ceiling(double x) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -1084,6 +1055,12 @@ class SignalSender : public Thread {
|
||||
vm_tgid_(getpid()),
|
||||
interval_(interval) {}
|
||||
|
||||
static void SetUp() {
|
||||
if (!mutex_) {
|
||||
mutex_ = OS::CreateMutex();
|
||||
}
|
||||
}
|
||||
|
||||
static void InstallSignalHandler() {
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = ProfilerSignalHandler;
|
||||
@ -1101,7 +1078,7 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
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 @@ class SignalSender : public Thread {
|
||||
};
|
||||
|
||||
|
||||
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),
|
||||
|
@ -94,18 +94,8 @@ double ceiling(double x) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -753,8 +743,14 @@ class SamplerThread : public Thread {
|
||||
: 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 @@ class SamplerThread : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SamplerThread : public Thread {
|
||||
RuntimeProfilerRateLimiter rate_limiter_;
|
||||
|
||||
// Protects the process wide state below.
|
||||
static LazyMutex mutex_;
|
||||
static Mutex* mutex_;
|
||||
static SamplerThread* instance_;
|
||||
|
||||
private:
|
||||
@ -872,10 +868,19 @@ class SamplerThread : public Thread {
|
||||
#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),
|
||||
|
@ -100,18 +100,8 @@ static void* GetRandomMmapAddr() {
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -803,6 +793,12 @@ class SignalSender : public Thread {
|
||||
vm_tgid_(getpid()),
|
||||
interval_(interval) {}
|
||||
|
||||
static void SetUp() {
|
||||
if (!mutex_) {
|
||||
mutex_ = OS::CreateMutex();
|
||||
}
|
||||
}
|
||||
|
||||
static void InstallSignalHandler() {
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = ProfilerSignalHandler;
|
||||
@ -820,7 +816,7 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
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 @@ class SignalSender : public Thread {
|
||||
};
|
||||
|
||||
|
||||
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),
|
||||
|
@ -147,15 +147,6 @@ UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
|
||||
#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 @@ int OS::VSNPrintF(Vector<char> str,
|
||||
|
||||
#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);
|
||||
@ -336,6 +318,18 @@ void OS::MemCopy(void* dest, const void* src, size_t size) {
|
||||
}
|
||||
#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.
|
||||
//
|
||||
|
@ -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
|
||||
|
||||
|
@ -91,22 +91,10 @@ double ceiling(double x) {
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -724,6 +712,12 @@ class SignalSender : public Thread {
|
||||
: Thread(Thread::Options("SignalSender", kSignalSenderStackSize)),
|
||||
interval_(interval) {}
|
||||
|
||||
static void SetUp() {
|
||||
if (!mutex_) {
|
||||
mutex_ = OS::CreateMutex();
|
||||
}
|
||||
}
|
||||
|
||||
static void InstallSignalHandler() {
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = ProfilerSignalHandler;
|
||||
@ -741,7 +735,7 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SignalSender : public Thread {
|
||||
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 @@ class SignalSender : public Thread {
|
||||
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),
|
||||
|
@ -141,20 +141,11 @@ static Mutex* limit_mutex = NULL;
|
||||
|
||||
#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);
|
||||
@ -563,22 +554,13 @@ char* Time::LocalTimezone() {
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -1967,8 +1949,14 @@ class SamplerThread : public Thread {
|
||||
: 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 @@ class SamplerThread : public Thread {
|
||||
}
|
||||
|
||||
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 @@ class SamplerThread : public Thread {
|
||||
RuntimeProfilerRateLimiter rate_limiter_;
|
||||
|
||||
// Protects the process wide state below.
|
||||
static LazyMutex mutex_;
|
||||
static Mutex* mutex_;
|
||||
static SamplerThread* instance_;
|
||||
|
||||
private:
|
||||
@ -2073,10 +2061,23 @@ class SamplerThread : public Thread {
|
||||
};
|
||||
|
||||
|
||||
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),
|
||||
|
@ -101,7 +101,7 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
|
||||
}
|
||||
|
||||
|
||||
void RuntimeProfiler::GlobalSetup() {
|
||||
void RuntimeProfiler::GlobalSetUp() {
|
||||
ASSERT(!has_been_globally_set_up_);
|
||||
enabled_ = V8::UseCrankshaft() && FLAG_opt;
|
||||
#ifdef DEBUG
|
||||
|
@ -43,7 +43,7 @@ class RuntimeProfiler {
|
||||
public:
|
||||
explicit RuntimeProfiler(Isolate* isolate);
|
||||
|
||||
static void GlobalSetup();
|
||||
static void GlobalSetUp();
|
||||
|
||||
static inline bool IsEnabled() {
|
||||
ASSERT(has_been_globally_set_up_);
|
||||
|
@ -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 @@ void V8::InitializeOncePerProcessImpl() {
|
||||
|
||||
OS::PostSetUp();
|
||||
|
||||
RuntimeProfiler::GlobalSetup();
|
||||
RuntimeProfiler::GlobalSetUp();
|
||||
|
||||
ElementsAccessor::InitializeOncePerProcess();
|
||||
|
||||
@ -273,6 +275,9 @@ void V8::InitializeOncePerProcessImpl() {
|
||||
}
|
||||
|
||||
LOperand::SetUpCaches();
|
||||
SetUpJSCallerSavedCodeData();
|
||||
SamplerRegistry::SetUp();
|
||||
ExternalReference::SetUp();
|
||||
}
|
||||
|
||||
void V8::InitializeOncePerProcess() {
|
||||
|
@ -315,7 +315,8 @@ class DisassemblerX64 {
|
||||
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 @@ class DisassemblerX64 {
|
||||
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 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user