summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/v8/src/platform-linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/src/platform-linux.cc')
-rw-r--r--src/3rdparty/v8/src/platform-linux.cc106
1 files changed, 70 insertions, 36 deletions
diff --git a/src/3rdparty/v8/src/platform-linux.cc b/src/3rdparty/v8/src/platform-linux.cc
index 18f59dd..e6c328f 100644
--- a/src/3rdparty/v8/src/platform-linux.cc
+++ b/src/3rdparty/v8/src/platform-linux.cc
@@ -53,6 +53,13 @@
#include <errno.h>
#include <stdarg.h>
+// GLibc on ARM defines mcontext_t has a typedef for 'struct sigcontext'.
+// Old versions of the C library <signal.h> didn't define the type.
+#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T) && \
+ defined(__arm__) && !defined(__BIONIC_HAVE_STRUCT_SIGCONTEXT)
+#include <asm/sigcontext.h>
+#endif
+
#undef MAP_TYPE
#include "v8.h"
@@ -132,12 +139,18 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
// facility is universally available on the ARM architectures,
// so it's up to individual OSes to provide such.
switch (feature) {
+ case VFP2:
+ search_string = "vfp";
+ break;
case VFP3:
search_string = "vfpv3";
break;
case ARMv7:
search_string = "ARMv7";
break;
+ case SUDIV:
+ search_string = "idiva";
+ break;
default:
UNREACHABLE();
}
@@ -161,6 +174,23 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) {
}
+CpuImplementer OS::GetCpuImplementer() {
+ static bool use_cached_value = false;
+ static CpuImplementer cached_value = UNKNOWN_IMPLEMENTER;
+ if (use_cached_value) {
+ return cached_value;
+ }
+ if (CPUInfoContainsString("CPU implementer\t: 0x41")) {
+ cached_value = ARM_IMPLEMENTER;
+ } else if (CPUInfoContainsString("CPU implementer\t: 0x51")) {
+ cached_value = QUALCOMM_IMPLEMENTER;
+ } else {
+ cached_value = UNKNOWN_IMPLEMENTER;
+ }
+ use_cached_value = true;
+ return cached_value;
+}
+
bool OS::ArmUsingHardFloat() {
// GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
// the Floating Point ABI used (PCS stands for Procedure Call Standard).
@@ -197,6 +227,7 @@ bool OS::ArmUsingHardFloat() {
#endif
#undef GCC_VERSION
}
+
#endif // def __arm__
@@ -501,9 +532,6 @@ void OS::LogSharedLibraryAddresses() {
}
-static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
-
-
void OS::SignalCodeMovingGC() {
// Support for ll_prof.py.
//
@@ -514,7 +542,7 @@ void OS::SignalCodeMovingGC() {
// by the kernel and allows us to synchronize V8 code log and the
// kernel log.
int size = sysconf(_SC_PAGESIZE);
- FILE* f = fopen(kGCFakeMmap, "w+");
+ FILE* f = fopen(FLAG_gc_fake_mmap, "w+");
void* addr = mmap(OS::GetRandomMmapAddr(),
size,
PROT_READ | PROT_EXEC,
@@ -693,6 +721,11 @@ bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
}
+bool VirtualMemory::HasLazyCommits() {
+ return true;
+}
+
+
class Thread::PlatformData : public Malloced {
public:
PlatformData() : thread_(kNoThread) {}
@@ -903,32 +936,30 @@ Semaphore* OS::CreateSemaphore(int count) {
}
-#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
-// Android runs a fairly new Linux kernel, so signal info is there,
-// but the C library doesn't have the structs defined.
+#if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
+
+// Not all versions of Android's C library provide ucontext_t.
+// Detect this and provide custom but compatible definitions. Note that these
+// follow the GLibc naming convention to access register values from
+// mcontext_t.
+//
+// See http://code.google.com/p/android/issues/detail?id=34784
+
+#if defined(__arm__)
-struct sigcontext {
- uint32_t trap_no;
- uint32_t error_code;
- uint32_t oldmask;
- uint32_t gregs[16];
- uint32_t arm_cpsr;
- uint32_t fault_address;
-};
-typedef uint32_t __sigset_t;
typedef struct sigcontext mcontext_t;
+
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
+ // Other fields are not used by V8, don't define them here.
} ucontext_t;
-enum ArmRegisters {R15 = 15, R13 = 13, R11 = 11};
-#elif !defined(__GLIBC__) && defined(__mips__)
+#elif defined(__mips__)
// MIPS version of sigcontext, for Android bionic.
-struct sigcontext {
+typedef struct {
uint32_t regmask;
uint32_t status;
uint64_t pc;
@@ -947,44 +978,44 @@ struct sigcontext {
uint32_t lo2;
uint32_t hi3;
uint32_t lo3;
-};
-typedef uint32_t __sigset_t;
-typedef struct sigcontext mcontext_t;
+} mcontext_t;
+
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
+ // Other fields are not used by V8, don't define them here.
} ucontext_t;
-#elif !defined(__GLIBC__) && defined(__i386__)
+#elif defined(__i386__)
// x86 version for Android.
-struct sigcontext {
+typedef struct {
uint32_t gregs[19];
void* fpregs;
uint32_t oldmask;
uint32_t cr2;
-};
+} mcontext_t;
-typedef uint32_t __sigset_t;
-typedef struct sigcontext mcontext_t;
+typedef uint32_t kernel_sigset_t[2]; // x86 kernel uses 64-bit signal masks
typedef struct ucontext {
uint32_t uc_flags;
struct ucontext* uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
- __sigset_t uc_sigmask;
+ // Other fields are not used by V8, don't define them here.
} ucontext_t;
enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 };
#endif
+#endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T)
static int GetThreadID() {
- // Glibc doesn't provide a wrapper for gettid(2).
-#if defined(ANDROID)
- return syscall(__NR_gettid);
+#if defined(__ANDROID__)
+ // Android's C library provides gettid(2).
+ return gettid();
#else
+ // Glibc doesn't provide a wrapper for gettid(2).
return syscall(SYS_gettid);
#endif
}
@@ -1023,8 +1054,10 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
#elif V8_HOST_ARCH_ARM
-// An undefined macro evaluates to 0, so this applies to Android's Bionic also.
-#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+#if defined(__GLIBC__) && !defined(__UCLIBC__) && \
+ (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+ // Old GLibc ARM versions used a gregs[] array to access the register
+ // values from mcontext_t.
sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
@@ -1032,7 +1065,8 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->pc = reinterpret_cast<Address>(mcontext.arm_pc);
sample->sp = reinterpret_cast<Address>(mcontext.arm_sp);
sample->fp = reinterpret_cast<Address>(mcontext.arm_fp);
-#endif // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+#endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
+ // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
#elif V8_HOST_ARCH_MIPS
sample->pc = reinterpret_cast<Address>(mcontext.pc);
sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]);