14 #include <sys/syspage.h>
32 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
37 static V8_INLINE void __cpuid(
int cpu_info[4],
int info_type) {
38 #if defined(__i386__) && defined(__pic__)
42 "mov %%ebx, %%edi\n\t"
44 "xchg %%edi, %%ebx\n\t"
45 :
"=a"(cpu_info[0]),
"=D"(cpu_info[1]),
"=c"(cpu_info[2]),
"=d"(cpu_info[3])
51 :
"=a"(cpu_info[0]),
"=b"(cpu_info[1]),
"=c"(cpu_info[2]),
"=d"(cpu_info[3])
59 #elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64 \
60 || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
70 #define HWCAP_SWP (1 << 0)
71 #define HWCAP_HALF (1 << 1)
72 #define HWCAP_THUMB (1 << 2)
73 #define HWCAP_26BIT (1 << 3)
74 #define HWCAP_FAST_MULT (1 << 4)
75 #define HWCAP_FPA (1 << 5)
76 #define HWCAP_VFP (1 << 6)
77 #define HWCAP_EDSP (1 << 7)
78 #define HWCAP_JAVA (1 << 8)
79 #define HWCAP_IWMMXT (1 << 9)
80 #define HWCAP_CRUNCH (1 << 10)
81 #define HWCAP_THUMBEE (1 << 11)
82 #define HWCAP_NEON (1 << 12)
83 #define HWCAP_VFPv3 (1 << 13)
84 #define HWCAP_VFPv3D16 (1 << 14)
85 #define HWCAP_TLS (1 << 15)
86 #define HWCAP_VFPv4 (1 << 16)
87 #define HWCAP_IDIVA (1 << 17)
88 #define HWCAP_IDIVT (1 << 18)
89 #define HWCAP_VFPD32 (1 << 19)
90 #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
91 #define HWCAP_LPAE (1 << 20)
98 FILE*
fp = fopen(
"/proc/self/auxv",
"r");
102 size_t n = fread(&entry,
sizeof(entry), 1,
fp);
103 if (n == 0 || (entry.tag == 0 && entry.value == 0)) {
106 if (entry.tag == AT_HWCAP) {
107 result = entry.value;
118 #if V8_HOST_ARCH_MIPS
119 int __detect_fp64_mode(
void) {
123 "lui $t0, 0x3FF0\n\t"
128 : :
"t0",
"$f0",
"$f1",
"memory");
130 return !(result == 1);
134 int __detect_mips_arch_revision(
void) {
143 class CPUInfo
FINAL {
145 CPUInfo() : datalen_(0) {
149 static const char PATHNAME[] =
"/proc/cpuinfo";
150 FILE*
fp = fopen(PATHNAME,
"r");
154 size_t n = fread(buffer, 1,
sizeof(buffer),
fp);
164 data_ =
new char[datalen_ + 1];
165 fp = fopen(PATHNAME,
"r");
167 for (
size_t offset = 0; offset < datalen_; ) {
168 size_t n = fread(data_ + offset, 1, datalen_ - offset,
fp);
178 data_[datalen_] =
'\0';
189 char* ExtractField(
const char* field)
const {
193 size_t fieldlen = strlen(field);
196 p = strstr(p, field);
200 if (p == data_ || p[-1] ==
'\n') {
207 p = strchr(p + fieldlen,
':');
208 if (p ==
NULL || !isspace(p[1])) {
214 char* q = strchr(p,
'\n');
216 q = data_ + datalen_;
221 char* result =
new char[len + 1];
222 if (result !=
NULL) {
223 memcpy(result, p, len);
234 #if V8_HOST_ARCH_ARM || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
237 static bool HasListItem(
const char* list,
const char* item) {
238 ssize_t item_len = strlen(item);
239 const char* p = list;
243 while (isspace(*p)) ++p;
247 while (*q !=
'\0' && !isspace(*q)) ++q;
249 if (item_len == q - p && memcmp(p, item, item_len) == 0) {
266 CPU::CPU() : stepping_(0),
290 has_vfp3_d32_(
false),
291 is_fp64_mode_(
false) {
292 memcpy(vendor_,
"Unknown", 8);
293 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
303 __cpuid(cpu_info, 0);
304 unsigned num_ids = cpu_info[0];
305 std::swap(cpu_info[2], cpu_info[3]);
306 memcpy(vendor_, cpu_info + 1, 12);
311 __cpuid(cpu_info, 1);
312 stepping_ = cpu_info[0] & 0xf;
313 model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0);
314 family_ = (cpu_info[0] >> 8) & 0xf;
315 type_ = (cpu_info[0] >> 12) & 0x3;
316 ext_model_ = (cpu_info[0] >> 16) & 0xf;
317 ext_family_ = (cpu_info[0] >> 20) & 0xff;
318 has_fpu_ = (cpu_info[3] & 0x00000001) != 0;
319 has_cmov_ = (cpu_info[3] & 0x00008000) != 0;
320 has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
321 has_sse_ = (cpu_info[3] & 0x02000000) != 0;
322 has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
323 has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
324 has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
325 has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
326 has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
329 #if V8_HOST_ARCH_IA32
334 __cpuid(cpu_info, 0x80000000);
335 unsigned num_ext_ids = cpu_info[0];
338 if (num_ext_ids > 0x80000000) {
339 __cpuid(cpu_info, 0x80000001);
341 has_sahf_ = (cpu_info[2] & 0x00000001) != 0;
345 #elif V8_HOST_ARCH_ARM
352 char* implementer = cpu_info.ExtractField(
"CPU implementer");
353 if (implementer !=
NULL) {
355 implementer_ = strtol(implementer, &end, 0);
356 if (end == implementer) {
359 delete[] implementer;
363 char* part = cpu_info.ExtractField(
"CPU part");
366 part_ = strtol(part, &end, 0);
379 char* architecture = cpu_info.ExtractField(
"CPU architecture");
380 if (architecture !=
NULL) {
382 architecture_ = strtol(architecture, &end, 10);
383 if (end == architecture) {
386 delete[] architecture;
398 if (architecture_ == 7) {
399 char* processor = cpu_info.ExtractField(
"Processor");
400 if (HasListItem(processor,
"(v6l)")) {
410 has_idiva_ = (hwcaps & HWCAP_IDIVA) != 0;
411 has_neon_ = (hwcaps & HWCAP_NEON) != 0;
412 has_vfp_ = (hwcaps & HWCAP_VFP) != 0;
413 has_vfp3_ = (hwcaps & (HWCAP_VFPv3 | HWCAP_VFPv3D16 | HWCAP_VFPv4)) != 0;
414 has_vfp3_d32_ = (has_vfp3_ && ((hwcaps & HWCAP_VFPv3D16) == 0 ||
415 (hwcaps & HWCAP_VFPD32) != 0));
418 char* features = cpu_info.ExtractField(
"Features");
419 has_idiva_ = HasListItem(features,
"idiva");
420 has_neon_ = HasListItem(features,
"neon");
421 has_thumb2_ = HasListItem(features,
"thumb2");
422 has_vfp_ = HasListItem(features,
"vfp");
423 if (HasListItem(features,
"vfpv3d16")) {
425 }
else if (HasListItem(features,
"vfpv3")) {
427 has_vfp3_d32_ =
true;
436 if (has_vfp_ && has_neon_) {
441 if (architecture_ < 7 && has_vfp3_) {
446 if (architecture_ >= 7) {
451 if (has_thumb2_ && architecture_ < 6) {
460 uint32_t cpu_flags = SYSPAGE_ENTRY(cpuinfo)->flags;
461 if (cpu_flags & ARM_CPU_FLAG_V7) {
464 }
else if (cpu_flags & ARM_CPU_FLAG_V6) {
469 DCHECK(architecture_ >= 6);
470 has_fpu_ = (cpu_flags & CPU_FLAG_FPU) != 0;
472 if (cpu_flags & ARM_CPU_FLAG_NEON) {
474 has_vfp3_ = has_vfp_;
475 #ifdef ARM_CPU_FLAG_VFP_D32
476 has_vfp3_d32_ = (cpu_flags & ARM_CPU_FLAG_VFP_D32) != 0;
479 has_idiva_ = (cpu_flags & ARM_CPU_FLAG_IDIV) != 0;
483 #elif V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
491 char* cpu_model = cpu_info.ExtractField(
"cpu model");
492 has_fpu_ = HasListItem(cpu_model,
"FPU");
494 #ifdef V8_HOST_ARCH_MIPS
495 is_fp64_mode_ = __detect_fp64_mode();
496 architecture_ = __detect_mips_arch_revision();
499 #elif V8_HOST_ARCH_ARM64
504 char* implementer = cpu_info.ExtractField(
"CPU implementer");
505 if (implementer !=
NULL) {
507 implementer_ = strtol(implementer, &end, 0);
508 if (end == implementer) {
511 delete[] implementer;
515 char* part = cpu_info.ExtractField(
"CPU part");
518 part_ = strtol(part, &end, 0);
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Debugger support for the V8 JavaScript engine.