More PNaCL fixes (without GYP/Makefile tweaks)

This is basically https://codereview.chromium.org/513923005/ with a
few changes:

   * Makefile.nacl and v8.gyp are untouched.

   * MAP_NORESERVE-handling is more defensive.

   * Added ugly busy-wait emulation of sem_timedwait.

R=bmeurer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23513 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8938126d
...@@ -9,9 +9,7 @@ ...@@ -9,9 +9,7 @@
#include <semaphore.h> #include <semaphore.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/prctl.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -46,6 +44,15 @@ ...@@ -46,6 +44,15 @@
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#if V8_OS_NACL
#if !defined(MAP_NORESERVE)
// PNaCL doesn't have this, so we always grab all of the memory, which is bad.
#define MAP_NORESERVE 0
#endif
#else
#include <sys/prctl.h>
#include <sys/syscall.h>
#endif
namespace v8 { namespace v8 {
namespace base { namespace base {
...@@ -95,20 +102,30 @@ bool OS::ArmUsingHardFloat() { ...@@ -95,20 +102,30 @@ bool OS::ArmUsingHardFloat() {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) { const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
#if V8_OS_NACL
// Missing support for tm_zone field.
return "";
#else
if (std::isnan(time)) return ""; if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond)); time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
if (NULL == t) return ""; if (NULL == t) return "";
return t->tm_zone; return t->tm_zone;
#endif
} }
double OS::LocalTimeOffset(TimezoneCache* cache) { double OS::LocalTimeOffset(TimezoneCache* cache) {
#if V8_OS_NACL
// Missing support for tm_zone field.
return 0;
#else
time_t tv = time(NULL); time_t tv = time(NULL);
struct tm* t = localtime(&tv); struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it. // tm_gmtoff includes any daylight savings offset, so subtract it.
return static_cast<double>(t->tm_gmtoff * msPerSecond - return static_cast<double>(t->tm_gmtoff * msPerSecond -
(t->tm_isdst > 0 ? 3600 * msPerSecond : 0)); (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
#endif
} }
...@@ -260,18 +277,15 @@ void OS::SignalCodeMovingGC() { ...@@ -260,18 +277,15 @@ void OS::SignalCodeMovingGC() {
OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile());
OS::Abort(); OS::Abort();
} }
void* addr = mmap(OS::GetRandomMmapAddr(), void* addr = mmap(OS::GetRandomMmapAddr(), size,
size, #if V8_OS_NACL
#if defined(__native_client__)
// The Native Client port of V8 uses an interpreter, // The Native Client port of V8 uses an interpreter,
// so code pages don't need PROT_EXEC. // so code pages don't need PROT_EXEC.
PROT_READ, PROT_READ,
#else #else
PROT_READ | PROT_EXEC, PROT_READ | PROT_EXEC,
#endif #endif
MAP_PRIVATE, MAP_PRIVATE, fileno(f), 0);
fileno(f),
0);
DCHECK(addr != MAP_FAILED); DCHECK(addr != MAP_FAILED);
OS::Free(addr, size); OS::Free(addr, size);
fclose(f); fclose(f);
...@@ -387,7 +401,7 @@ void* VirtualMemory::ReserveRegion(size_t size) { ...@@ -387,7 +401,7 @@ void* VirtualMemory::ReserveRegion(size_t size) {
bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
#if defined(__native_client__) #if V8_OS_NACL
// The Native Client port of V8 uses an interpreter, // The Native Client port of V8 uses an interpreter,
// so code pages don't need PROT_EXEC. // so code pages don't need PROT_EXEC.
int prot = PROT_READ | PROT_WRITE; int prot = PROT_READ | PROT_WRITE;
......
...@@ -19,14 +19,8 @@ ...@@ -19,14 +19,8 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/stat.h> #include <sys/stat.h>
#if !defined(__pnacl__)
#include <sys/syscall.h>
#endif
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#if defined(__linux__) && !defined(__pnacl__)
#include <sys/prctl.h> // NOLINT, for prctl
#endif
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \ #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
defined(__NetBSD__) || defined(__OpenBSD__) defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/sysctl.h> // NOLINT, for sysctl #include <sys/sysctl.h> // NOLINT, for sysctl
...@@ -56,6 +50,14 @@ ...@@ -56,6 +50,14 @@
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#if V8_OS_LINUX
#include <sys/prctl.h> // NOLINT, for prctl
#endif
#if !V8_OS_NACL
#include <sys/syscall.h>
#endif
namespace v8 { namespace v8 {
namespace base { namespace base {
...@@ -223,11 +225,11 @@ void OS::DebugBreak() { ...@@ -223,11 +225,11 @@ void OS::DebugBreak() {
#elif V8_HOST_ARCH_MIPS64 #elif V8_HOST_ARCH_MIPS64
asm("break"); asm("break");
#elif V8_HOST_ARCH_IA32 #elif V8_HOST_ARCH_IA32
#if defined(__native_client__) #if V8_OS_NACL
asm("hlt"); asm("hlt");
#else #else
asm("int $3"); asm("int $3");
#endif // __native_client__ #endif // V8_OS_NACL
#elif V8_HOST_ARCH_X64 #elif V8_HOST_ARCH_X64
asm("int $3"); asm("int $3");
#else #else
...@@ -268,12 +270,17 @@ int OS::GetCurrentThreadId() { ...@@ -268,12 +270,17 @@ int OS::GetCurrentThreadId() {
// //
int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
#if V8_OS_NACL
// Optionally used in Logger::ResourceEvent.
return -1;
#else
struct rusage usage; struct rusage usage;
if (getrusage(RUSAGE_SELF, &usage) < 0) return -1; if (getrusage(RUSAGE_SELF, &usage) < 0) return -1;
*secs = usage.ru_utime.tv_sec; *secs = usage.ru_utime.tv_sec;
*usecs = usage.ru_utime.tv_usec; *usecs = usage.ru_utime.tv_usec;
return 0; return 0;
#endif
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <errno.h> #include <errno.h>
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/base/platform/elapsed-timer.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
namespace v8 { namespace v8 {
...@@ -106,6 +107,17 @@ void Semaphore::Wait() { ...@@ -106,6 +107,17 @@ void Semaphore::Wait() {
bool Semaphore::WaitFor(const TimeDelta& rel_time) { bool Semaphore::WaitFor(const TimeDelta& rel_time) {
#if V8_OS_NACL
// PNaCL doesn't support sem_timedwait, do ugly busy waiting.
ElapsedTimer timer;
timer.Start();
do {
int result = sem_trywait(&native_handle_);
if (result == 0) return true;
DCHECK(errno == EAGAIN || error == EINTR);
} while (!timer.HasExpired(rel_time));
return false;
#else
// Compute the time for end of timeout. // Compute the time for end of timeout.
const Time time = Time::NowFromSystemTime() + rel_time; const Time time = Time::NowFromSystemTime() + rel_time;
const struct timespec ts = time.ToTimespec(); const struct timespec ts = time.ToTimespec();
...@@ -129,6 +141,7 @@ bool Semaphore::WaitFor(const TimeDelta& rel_time) { ...@@ -129,6 +141,7 @@ bool Semaphore::WaitFor(const TimeDelta& rel_time) {
DCHECK_EQ(-1, result); DCHECK_EQ(-1, result);
DCHECK_EQ(EINTR, errno); DCHECK_EQ(EINTR, errno);
} }
#endif
} }
#elif V8_OS_WIN #elif V8_OS_WIN
......
...@@ -91,6 +91,9 @@ int64_t SysInfo::AmountOfPhysicalMemory() { ...@@ -91,6 +91,9 @@ int64_t SysInfo::AmountOfPhysicalMemory() {
return 0; return 0;
} }
return static_cast<int64_t>(stat_buf.st_size); return static_cast<int64_t>(stat_buf.st_size);
#elif V8_OS_NACL
// No support for _SC_PHYS_PAGES, assume 2GB.
return static_cast<int64_t>(1) << 31;
#elif V8_OS_POSIX #elif V8_OS_POSIX
long pages = sysconf(_SC_PHYS_PAGES); // NOLINT(runtime/int) long pages = sysconf(_SC_PHYS_PAGES); // NOLINT(runtime/int)
long page_size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int) long page_size = sysconf(_SC_PAGESIZE); // NOLINT(runtime/int)
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/select.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -16,6 +15,9 @@ ...@@ -16,6 +15,9 @@
#include "src/d8.h" #include "src/d8.h"
#if !V8_OS_NACL
#include <sys/select.h>
#endif
namespace v8 { namespace v8 {
...@@ -102,11 +104,16 @@ static bool WaitOnFD(int fd, ...@@ -102,11 +104,16 @@ static bool WaitOnFD(int fd,
} }
timeout.tv_usec = (read_timeout % 1000) * 1000; timeout.tv_usec = (read_timeout % 1000) * 1000;
timeout.tv_sec = read_timeout / 1000; timeout.tv_sec = read_timeout / 1000;
#if V8_OS_NACL
// PNaCL has no support for select.
int number_of_fds_ready = -1;
#else
int number_of_fds_ready = select(fd + 1, int number_of_fds_ready = select(fd + 1,
&readfds, &readfds,
&writefds, &writefds,
&exceptfds, &exceptfds,
read_timeout != -1 ? &timeout : NULL); read_timeout != -1 ? &timeout : NULL);
#endif
return number_of_fds_ready == 1; return number_of_fds_ready == 1;
} }
...@@ -547,8 +554,12 @@ void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -547,8 +554,12 @@ void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) {
return; return;
} }
if (args[0]->IsNumber()) { if (args[0]->IsNumber()) {
mode_t mask = args[0]->Int32Value(); #if V8_OS_NACL
int previous = umask(mask); // PNaCL has no support for umask.
int previous = 0;
#else
int previous = umask(args[0]->Int32Value());
#endif
args.GetReturnValue().Set(previous); args.GetReturnValue().Set(previous);
return; return;
} else { } else {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <signal.h> #include <signal.h>
#include <sys/time.h> #include <sys/time.h>
#if !V8_OS_QNX #if !V8_OS_QNX && !V8_OS_NACL
#include <sys/syscall.h> // NOLINT #include <sys/syscall.h> // NOLINT
#endif #endif
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include <mach/mach.h> #include <mach/mach.h>
// OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h> // OpenBSD doesn't have <ucontext.h>. ucontext_t lives in <signal.h>
// and is a typedef for struct sigcontext. There is no uc_mcontext. // and is a typedef for struct sigcontext. There is no uc_mcontext.
#elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) \ #elif(!V8_OS_ANDROID || defined(__BIONIC_HAVE_UCONTEXT_T)) && \
&& !V8_OS_OPENBSD !V8_OS_OPENBSD && !V8_OS_NACL
#include <ucontext.h> #include <ucontext.h>
#endif #endif
...@@ -294,6 +294,7 @@ class SignalHandler : public AllStatic { ...@@ -294,6 +294,7 @@ class SignalHandler : public AllStatic {
private: private:
static void Install() { static void Install() {
#if !V8_OS_NACL
struct sigaction sa; struct sigaction sa;
sa.sa_sigaction = &HandleProfilerSignal; sa.sa_sigaction = &HandleProfilerSignal;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
...@@ -304,16 +305,21 @@ class SignalHandler : public AllStatic { ...@@ -304,16 +305,21 @@ class SignalHandler : public AllStatic {
#endif #endif
signal_handler_installed_ = signal_handler_installed_ =
(sigaction(SIGPROF, &sa, &old_signal_handler_) == 0); (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
#endif
} }
static void Restore() { static void Restore() {
#if !V8_OS_NACL
if (signal_handler_installed_) { if (signal_handler_installed_) {
sigaction(SIGPROF, &old_signal_handler_, 0); sigaction(SIGPROF, &old_signal_handler_, 0);
signal_handler_installed_ = false; signal_handler_installed_ = false;
} }
#endif
} }
#if !V8_OS_NACL
static void HandleProfilerSignal(int signal, siginfo_t* info, void* context); static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);
#endif
// Protects the process wide state below. // Protects the process wide state below.
static base::Mutex* mutex_; static base::Mutex* mutex_;
static int client_count_; static int client_count_;
...@@ -328,13 +334,10 @@ struct sigaction SignalHandler::old_signal_handler_; ...@@ -328,13 +334,10 @@ struct sigaction SignalHandler::old_signal_handler_;
bool SignalHandler::signal_handler_installed_ = false; bool SignalHandler::signal_handler_installed_ = false;
// As Native Client does not support signal handling, profiling is disabled.
#if !V8_OS_NACL
void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
void* context) { void* context) {
#if V8_OS_NACL
// As Native Client does not support signal handling, profiling
// is disabled.
return;
#else
USE(info); USE(info);
if (signal != SIGPROF) return; if (signal != SIGPROF) return;
Isolate* isolate = Isolate::UnsafeCurrent(); Isolate* isolate = Isolate::UnsafeCurrent();
...@@ -477,8 +480,8 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, ...@@ -477,8 +480,8 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
#endif // V8_OS_QNX #endif // V8_OS_QNX
#endif // USE_SIMULATOR #endif // USE_SIMULATOR
sampler->SampleStack(state); sampler->SampleStack(state);
#endif // V8_OS_NACL
} }
#endif // V8_OS_NACL
#endif #endif
......
...@@ -21621,7 +21621,7 @@ THREADED_TEST(JSONParseNumber) { ...@@ -21621,7 +21621,7 @@ THREADED_TEST(JSONParseNumber) {
} }
#if V8_OS_POSIX #if V8_OS_POSIX && !V8_OS_NACL
class ThreadInterruptTest { class ThreadInterruptTest {
public: public:
ThreadInterruptTest() : sem_(0), sem_value_(0) { } ThreadInterruptTest() : sem_(0), sem_value_(0) { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment