37 #include <sys/syspage.h>
55 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
60 static V8_INLINE void __cpuid(
int cpu_info[4],
int info_type) {
61 #if defined(__i386__) && defined(__pic__)
65 "mov %%ebx, %%edi\n\t"
67 "xchg %%edi, %%ebx\n\t"
68 :
"=a"(cpu_info[0]),
"=D"(cpu_info[1]),
"=c"(cpu_info[2]),
"=d"(cpu_info[3])
74 :
"=a"(cpu_info[0]),
"=b"(cpu_info[1]),
"=c"(cpu_info[2]),
"=d"(cpu_info[3])
77 #endif // defined(__i386__) && defined(__pic__)
80 #endif // !V8_LIBC_MSVCRT
82 #elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_MIPS
92 #define HWCAP_SWP (1 << 0)
93 #define HWCAP_HALF (1 << 1)
94 #define HWCAP_THUMB (1 << 2)
95 #define HWCAP_26BIT (1 << 3)
96 #define HWCAP_FAST_MULT (1 << 4)
97 #define HWCAP_FPA (1 << 5)
98 #define HWCAP_VFP (1 << 6)
99 #define HWCAP_EDSP (1 << 7)
100 #define HWCAP_JAVA (1 << 8)
101 #define HWCAP_IWMMXT (1 << 9)
102 #define HWCAP_CRUNCH (1 << 10)
103 #define HWCAP_THUMBEE (1 << 11)
104 #define HWCAP_NEON (1 << 12)
105 #define HWCAP_VFPv3 (1 << 13)
106 #define HWCAP_VFPv3D16 (1 << 14)
107 #define HWCAP_TLS (1 << 15)
108 #define HWCAP_VFPv4 (1 << 16)
109 #define HWCAP_IDIVA (1 << 17)
110 #define HWCAP_IDIVT (1 << 18)
111 #define HWCAP_VFPD32 (1 << 19)
112 #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
113 #define HWCAP_LPAE (1 << 20)
118 static uint32_t ReadELFHWCaps() {
120 FILE*
fp = fopen(
"/proc/self/auxv",
"r");
122 struct { uint32_t tag; uint32_t value; } entry;
124 size_t n = fread(&entry,
sizeof(entry), 1, fp);
125 if (n == 0 || (entry.tag == 0 && entry.value == 0)) {
128 if (entry.tag == AT_HWCAP) {
129 result = entry.value;
138 #endif // V8_HOST_ARCH_ARM
143 CPUInfo() : datalen_(0) {
147 static const char PATHNAME[] =
"/proc/cpuinfo";
148 FILE* fp = fopen(PATHNAME,
"r");
152 size_t n = fread(buffer, 1,
sizeof(buffer), fp);
162 data_ =
new char[datalen_ + 1];
163 fp = fopen(PATHNAME,
"r");
165 for (
size_t offset = 0; offset < datalen_; ) {
166 size_t n = fread(data_ + offset, 1, datalen_ - offset, fp);
176 data_[datalen_] =
'\0';
187 char* ExtractField(
const char* field)
const {
191 size_t fieldlen = strlen(field);
194 p = strstr(p, field);
198 if (p == data_ || p[-1] ==
'\n') {
205 p = strchr(p + fieldlen,
':');
206 if (p ==
NULL || !isspace(p[1])) {
212 char* q = strchr(p,
'\n');
214 q = data_ + datalen_;
219 char* result =
new char[len + 1];
220 if (result !=
NULL) {
221 memcpy(result, p, len);
234 static bool HasListItem(
const char* list,
const char* item) {
235 ssize_t item_len = strlen(item);
236 const char* p = list;
240 while (isspace(*p)) ++p;
244 while (*q !=
'\0' && !isspace(*q)) ++q;
246 if (item_len == q - p && memcmp(p, item, item_len) == 0) {
257 #endif // V8_OS_LINUX
259 #endif // V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
261 CPU::CPU() : stepping_(0),
285 has_vfp3_d32_(
false) {
286 memcpy(vendor_,
"Unknown", 8);
287 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
297 __cpuid(cpu_info, 0);
298 unsigned num_ids = cpu_info[0];
299 std::swap(cpu_info[2], cpu_info[3]);
300 memcpy(vendor_, cpu_info + 1, 12);
305 __cpuid(cpu_info, 1);
306 stepping_ = cpu_info[0] & 0xf;
307 model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0);
308 family_ = (cpu_info[0] >> 8) & 0xf;
309 type_ = (cpu_info[0] >> 12) & 0x3;
310 ext_model_ = (cpu_info[0] >> 16) & 0xf;
311 ext_family_ = (cpu_info[0] >> 20) & 0xff;
312 has_fpu_ = (cpu_info[3] & 0x00000001) != 0;
313 has_cmov_ = (cpu_info[3] & 0x00008000) != 0;
314 has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
315 has_sse_ = (cpu_info[3] & 0x02000000) != 0;
316 has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
317 has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
318 has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
319 has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
320 has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
324 __cpuid(cpu_info, 0x80000000);
325 unsigned num_ext_ids = cpu_info[0];
328 if (num_ext_ids > 0x80000000) {
329 __cpuid(cpu_info, 0x80000001);
332 #if V8_HOST_ARCH_IA32
335 has_sahf_ = (cpu_info[2] & 0x00000001) != 0;
339 #elif V8_HOST_ARCH_ARM
346 char* implementer = cpu_info.ExtractField(
"CPU implementer");
347 if (implementer !=
NULL) {
349 implementer_ = strtol(implementer, &end, 0);
350 if (end == implementer) {
353 delete[] implementer;
357 char* part = cpu_info.ExtractField(
"CPU part");
360 part_ = strtol(part, &end, 0);
373 char* architecture = cpu_info.ExtractField(
"CPU architecture");
374 if (architecture !=
NULL) {
376 architecture_ = strtol(architecture, &end, 10);
377 if (end == architecture) {
380 delete[] architecture;
392 if (architecture_ == 7) {
393 char*
processor = cpu_info.ExtractField(
"Processor");
394 if (HasListItem(processor,
"(v6l)")) {
402 uint32_t hwcaps = ReadELFHWCaps();
404 has_idiva_ = (hwcaps & HWCAP_IDIVA) != 0;
405 has_neon_ = (hwcaps & HWCAP_NEON) != 0;
406 has_thumbee_ = (hwcaps & HWCAP_THUMBEE) != 0;
407 has_vfp_ = (hwcaps & HWCAP_VFP) != 0;
408 has_vfp3_ = (hwcaps & (HWCAP_VFPv3 | HWCAP_VFPv3D16 | HWCAP_VFPv4)) != 0;
409 has_vfp3_d32_ = (has_vfp3_ && ((hwcaps & HWCAP_VFPv3D16) == 0 ||
410 (hwcaps & HWCAP_VFPD32) != 0));
413 char* features = cpu_info.ExtractField(
"Features");
414 has_idiva_ = HasListItem(features,
"idiva");
415 has_neon_ = HasListItem(features,
"neon");
416 has_thumbee_ = HasListItem(features,
"thumbee");
417 has_vfp_ = HasListItem(features,
"vfp");
418 if (HasListItem(features,
"vfpv3")) {
420 has_vfp3_d32_ =
true;
421 }
else if (HasListItem(features,
"vfpv3d16")) {
431 if (has_vfp_ && has_neon_) {
436 if (architecture_ < 7 && has_vfp3_) {
441 if (architecture_ >= 7) {
446 if (has_thumbee_ && architecture_ < 6) {
455 uint32_t cpu_flags = SYSPAGE_ENTRY(cpuinfo)->flags;
456 if (cpu_flags & ARM_CPU_FLAG_V7) {
459 }
else if (cpu_flags & ARM_CPU_FLAG_V6) {
464 ASSERT(architecture_ >= 6);
465 has_fpu_ = (cpu_flags & CPU_FLAG_FPU) != 0;
467 if (cpu_flags & ARM_CPU_FLAG_NEON) {
469 has_vfp3_ = has_vfp_;
470 #ifdef ARM_CPU_FLAG_VFP_D32
471 has_vfp3_d32_ = (cpu_flags & ARM_CPU_FLAG_VFP_D32) != 0;
474 has_idiva_ = (cpu_flags & ARM_CPU_FLAG_IDIV) != 0;
476 #endif // V8_OS_LINUX
478 #elif V8_HOST_ARCH_MIPS
486 char* cpu_model = cpu_info.ExtractField(
"cpu model");
487 has_fpu_ = HasListItem(cpu_model,
"FPU");
495 int CPU::NumberOfProcessorsOnline() {
498 GetSystemInfo(&info);
499 return info.dwNumberOfProcessors;
501 return static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
#define ASSERT(condition)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
ProfilerEventsProcessor * processor() const