Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(933)

Unified Diff: src/platform-cygwin.cc

Issue 6794050: Revert "[Arguments] Merge (7442,7496] from bleeding_edge." (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform.h ('k') | src/platform-macos.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform-cygwin.cc
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index d591b9dc27162e5432dc29d6a59f260769aaf7d5..4b450c18a6c0f009a71f5a75dff4a0782d2f7897 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -42,6 +42,7 @@
#include "v8.h"
#include "platform.h"
+#include "top.h"
#include "v8threads.h"
#include "vm-state-inl.h"
#include "win32-headers.h"
@@ -58,9 +59,6 @@ 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
@@ -69,7 +67,6 @@ void OS::Setup() {
// 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();
}
@@ -122,9 +119,6 @@ static void* highest_ever_allocated = reinterpret_cast<void*>(0);
static void UpdateAllocatedSpaceLimits(void* address, int size) {
- ASSERT(limit_mutex != NULL);
- ScopedLock lock(limit_mutex);
-
lowest_ever_allocated = Min(lowest_ever_allocated, address);
highest_ever_allocated =
Max(highest_ever_allocated,
@@ -260,7 +254,6 @@ void OS::LogSharedLibraryAddresses() {
const int kLibNameLen = FILENAME_MAX + 1;
char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen));
- i::Isolate* isolate = ISOLATE;
// This loop will terminate once the scanning hits an EOF.
while (true) {
uintptr_t start, end;
@@ -294,7 +287,7 @@ void OS::LogSharedLibraryAddresses() {
snprintf(lib_name, kLibNameLen,
"%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end);
}
- LOG(isolate, SharedLibraryEvent(lib_name, start, end));
+ LOG(SharedLibraryEvent(lib_name, start, end));
} else {
// Entry not describing executable data. Skip to end of line to setup
// reading the next entry.
@@ -321,44 +314,47 @@ int OS::StackWalk(Vector<OS::StackFrame> frames) {
}
-// The VirtualMemory implementation is taken from platform-win32.cc.
-// The mmap-based virtual memory implementation as it is used on most posix
-// platforms does not work well because Cygwin does not support MAP_FIXED.
-// This causes VirtualMemory::Commit to not always commit the memory region
-// specified.
-
-bool VirtualMemory::IsReserved() {
- return address_ != NULL;
-}
+// Constants used for mmap.
+static const int kMmapFd = -1;
+static const int kMmapFdOffset = 0;
VirtualMemory::VirtualMemory(size_t size) {
- address_ = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
+ address_ = mmap(NULL, size, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
+ kMmapFd, kMmapFdOffset);
size_ = size;
}
VirtualMemory::~VirtualMemory() {
if (IsReserved()) {
- if (0 == VirtualFree(address(), 0, MEM_RELEASE)) address_ = NULL;
+ if (0 == munmap(address(), size())) address_ = MAP_FAILED;
}
}
+bool VirtualMemory::IsReserved() {
+ return address_ != MAP_FAILED;
+}
+
+
bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
- int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
- if (NULL == VirtualAlloc(address, size, MEM_COMMIT, prot)) {
+ int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+
+ if (mprotect(address, size, prot) != 0) {
return false;
}
- UpdateAllocatedSpaceLimits(address, static_cast<int>(size));
+ UpdateAllocatedSpaceLimits(address, size);
return true;
}
bool VirtualMemory::Uncommit(void* address, size_t size) {
- ASSERT(IsReserved());
- return VirtualFree(address, size, MEM_DECOMMIT) != false;
+ return mmap(address, size, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
+ kMmapFd, kMmapFdOffset) != MAP_FAILED;
}
@@ -431,7 +427,6 @@ static void* ThreadEntry(void* arg) {
// one) so we initialize it here too.
thread->thread_handle_data()->thread_ = pthread_self();
ASSERT(thread->IsValid());
- Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return NULL;
}
@@ -444,14 +439,7 @@ void Thread::set_name(const char* name) {
void Thread::Start() {
- pthread_attr_t* attr_ptr = NULL;
- pthread_attr_t attr;
- if (stack_size_ > 0) {
- pthread_attr_init(&attr);
- pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
- attr_ptr = &attr;
- }
- pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
+ pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
ASSERT(IsValid());
}
@@ -635,176 +623,128 @@ Semaphore* OS::CreateSemaphore(int count) {
class Sampler::PlatformData : public Malloced {
public:
- // Get a handle to the calling thread. This is the thread that we are
- // going to profile. We need to make a copy of the handle because we are
- // going to use it in the sampler thread. Using GetThreadHandle() will
- // not work in this case. We're using OpenThread because DuplicateHandle
- // for some reason doesn't work in Chrome's sandbox.
- PlatformData() : profiled_thread_(OpenThread(THREAD_GET_CONTEXT |
- THREAD_SUSPEND_RESUME |
- THREAD_QUERY_INFORMATION,
- false,
- GetCurrentThreadId())) {}
-
- ~PlatformData() {
- if (profiled_thread_ != NULL) {
- CloseHandle(profiled_thread_);
- profiled_thread_ = NULL;
- }
+ explicit PlatformData(Sampler* sampler) {
+ sampler_ = sampler;
+ sampler_thread_ = INVALID_HANDLE_VALUE;
+ profiled_thread_ = INVALID_HANDLE_VALUE;
}
- HANDLE profiled_thread() { return profiled_thread_; }
-
- private:
+ Sampler* sampler_;
+ HANDLE sampler_thread_;
HANDLE profiled_thread_;
-};
-
-
-class SamplerThread : public Thread {
- public:
- explicit SamplerThread(int interval)
- : Thread(NULL, "SamplerThread"),
- interval_(interval) {}
-
- static void AddActiveSampler(Sampler* sampler) {
- ScopedLock lock(mutex_);
- SamplerRegistry::AddActiveSampler(sampler);
- if (instance_ == NULL) {
- instance_ = new SamplerThread(sampler->interval());
- instance_->Start();
- } else {
- ASSERT(instance_->interval_ == sampler->interval());
- }
- }
-
- static void RemoveActiveSampler(Sampler* sampler) {
- ScopedLock lock(mutex_);
- SamplerRegistry::RemoveActiveSampler(sampler);
- if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
- RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
- instance_->Join();
- delete instance_;
- instance_ = NULL;
- }
- }
+ RuntimeProfilerRateLimiter rate_limiter_;
- // Implement Thread::Run().
- virtual void Run() {
- SamplerRegistry::State state;
- while ((state = SamplerRegistry::GetState()) !=
- SamplerRegistry::HAS_NO_SAMPLERS) {
- bool cpu_profiling_enabled =
- (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
- bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
- // When CPU profiling is enabled both JavaScript and C++ code is
- // profiled. We must not suspend.
- if (!cpu_profiling_enabled) {
- if (rate_limiter_.SuspendIfNecessary()) continue;
- }
- if (cpu_profiling_enabled) {
- if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) {
- return;
- }
- }
- if (runtime_profiler_enabled) {
- if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) {
- return;
- }
- }
- OS::Sleep(interval_);
+ // Sampler thread handler.
+ void Runner() {
+ while (sampler_->IsActive()) {
+ if (rate_limiter_.SuspendIfNecessary()) continue;
+ Sample();
+ Sleep(sampler_->interval_);
}
}
- static void DoCpuProfile(Sampler* sampler, void* raw_sampler_thread) {
- if (!sampler->isolate()->IsInitialized()) return;
- if (!sampler->IsProfiling()) return;
- SamplerThread* sampler_thread =
- reinterpret_cast<SamplerThread*>(raw_sampler_thread);
- sampler_thread->SampleContext(sampler);
- }
-
- static void DoRuntimeProfile(Sampler* sampler, void* ignored) {
- if (!sampler->isolate()->IsInitialized()) return;
- sampler->isolate()->runtime_profiler()->NotifyTick();
- }
-
- void SampleContext(Sampler* sampler) {
- HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
- if (profiled_thread == NULL) return;
-
- // Context used for sampling the register state of the profiled thread.
- CONTEXT context;
- memset(&context, 0, sizeof(context));
+ void Sample() {
+ if (sampler_->IsProfiling()) {
+ // Context used for sampling the register state of the profiled thread.
+ CONTEXT context;
+ memset(&context, 0, sizeof(context));
- TickSample sample_obj;
- TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
- if (sample == NULL) sample = &sample_obj;
+ TickSample sample_obj;
+ TickSample* sample = CpuProfiler::TickSampleEvent();
+ if (sample == NULL) sample = &sample_obj;
- static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
- if (SuspendThread(profiled_thread) == kSuspendFailed) return;
- sample->state = sampler->isolate()->current_vm_state();
+ static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
+ if (SuspendThread(profiled_thread_) == kSuspendFailed) return;
+ sample->state = Top::current_vm_state();
- context.ContextFlags = CONTEXT_FULL;
- if (GetThreadContext(profiled_thread, &context) != 0) {
+ context.ContextFlags = CONTEXT_FULL;
+ if (GetThreadContext(profiled_thread_, &context) != 0) {
#if V8_HOST_ARCH_X64
- sample->pc = reinterpret_cast<Address>(context.Rip);
- sample->sp = reinterpret_cast<Address>(context.Rsp);
- sample->fp = reinterpret_cast<Address>(context.Rbp);
+ sample->pc = reinterpret_cast<Address>(context.Rip);
+ sample->sp = reinterpret_cast<Address>(context.Rsp);
+ sample->fp = reinterpret_cast<Address>(context.Rbp);
#else
- sample->pc = reinterpret_cast<Address>(context.Eip);
- sample->sp = reinterpret_cast<Address>(context.Esp);
- sample->fp = reinterpret_cast<Address>(context.Ebp);
+ sample->pc = reinterpret_cast<Address>(context.Eip);
+ sample->sp = reinterpret_cast<Address>(context.Esp);
+ sample->fp = reinterpret_cast<Address>(context.Ebp);
#endif
- sampler->SampleStack(sample);
- sampler->Tick(sample);
+ sampler_->SampleStack(sample);
+ sampler_->Tick(sample);
+ }
+ ResumeThread(profiled_thread_);
}
- ResumeThread(profiled_thread);
+ if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
}
-
- const int interval_;
- RuntimeProfilerRateLimiter rate_limiter_;
-
- // Protects the process wide state below.
- static Mutex* mutex_;
- static SamplerThread* instance_;
-
- DISALLOW_COPY_AND_ASSIGN(SamplerThread);
};
-Mutex* SamplerThread::mutex_ = OS::CreateMutex();
-SamplerThread* SamplerThread::instance_ = NULL;
+// Entry point for sampler thread.
+static DWORD __stdcall SamplerEntry(void* arg) {
+ Sampler::PlatformData* data =
+ reinterpret_cast<Sampler::PlatformData*>(arg);
+ data->Runner();
+ return 0;
+}
-Sampler::Sampler(Isolate* isolate, int interval)
- : isolate_(isolate),
- interval_(interval),
+// Initialize a profile sampler.
+Sampler::Sampler(int interval)
+ : interval_(interval),
profiling_(false),
active_(false),
samples_taken_(0) {
- data_ = new PlatformData;
+ data_ = new PlatformData(this);
}
Sampler::~Sampler() {
- ASSERT(!IsActive());
delete data_;
}
+// Start profiling.
void Sampler::Start() {
+ // Do not start multiple threads for the same sampler.
ASSERT(!IsActive());
+
+ // Get a handle to the calling thread. This is the thread that we are
+ // going to profile. We need to make a copy of the handle because we are
+ // going to use it in the sampler thread. Using GetThreadHandle() will
+ // not work in this case. We're using OpenThread because DuplicateHandle
+ // for some reason doesn't work in Chrome's sandbox.
+ data_->profiled_thread_ = OpenThread(THREAD_GET_CONTEXT |
+ THREAD_SUSPEND_RESUME |
+ THREAD_QUERY_INFORMATION,
+ false,
+ GetCurrentThreadId());
+ BOOL ok = data_->profiled_thread_ != NULL;
+ if (!ok) return;
+
+ // Start sampler thread.
+ DWORD tid;
SetActive(true);
- SamplerThread::AddActiveSampler(this);
+ data_->sampler_thread_ = CreateThread(NULL, 0, SamplerEntry, data_, 0, &tid);
+ // Set thread to high priority to increase sampling accuracy.
+ SetThreadPriority(data_->sampler_thread_, THREAD_PRIORITY_TIME_CRITICAL);
}
+// Stop profiling.
void Sampler::Stop() {
- ASSERT(IsActive());
- SamplerThread::RemoveActiveSampler(this);
+ // Seting active to false triggers termination of the sampler
+ // thread.
SetActive(false);
+
+ // Wait for sampler thread to terminate.
+ Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
+ WaitForSingleObject(data_->sampler_thread_, INFINITE);
+
+ // Release the thread handles
+ CloseHandle(data_->sampler_thread_);
+ CloseHandle(data_->profiled_thread_);
}
+
#endif // ENABLE_LOGGING_AND_PROFILING
} } // namespace v8::internal
« no previous file with comments | « src/platform.h ('k') | src/platform-macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698