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

Side by Side Diff: src/platform-linux.cc

Issue 23401002: Fix the CPU feature detection. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Improve cpuinfo parsing. Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/platform.h ('k') | src/platform-nullos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 73
74 74
75 namespace v8 { 75 namespace v8 {
76 namespace internal { 76 namespace internal {
77 77
78 78
79 static Mutex* limit_mutex = NULL; 79 static Mutex* limit_mutex = NULL;
80 80
81 81
82 #ifdef __arm__ 82 #ifdef __arm__
83 static bool CPUInfoContainsString(const char * search_string) {
84 const char* file_name = "/proc/cpuinfo";
85 // This is written as a straight shot one pass parser
86 // and not using STL string and ifstream because,
87 // on Linux, it's reading from a (non-mmap-able)
88 // character special device.
89 FILE* f = NULL;
90 const char* what = search_string;
91
92 if (NULL == (f = fopen(file_name, "r"))) {
93 OS::PrintError("Failed to open /proc/cpuinfo\n");
94 return false;
95 }
96
97 int k;
98 while (EOF != (k = fgetc(f))) {
99 if (k == *what) {
100 ++what;
101 while ((*what != '\0') && (*what == fgetc(f))) {
102 ++what;
103 }
104 if (*what == '\0') {
105 fclose(f);
106 return true;
107 } else {
108 what = search_string;
109 }
110 }
111 }
112 fclose(f);
113
114 // Did not find string in the proc file.
115 return false;
116 }
117
118
119 bool OS::ArmCpuHasFeature(CpuFeature feature) {
120 const char* search_string = NULL;
121 // Simple detection of VFP at runtime for Linux.
122 // It is based on /proc/cpuinfo, which reveals hardware configuration
123 // to user-space applications. According to ARM (mid 2009), no similar
124 // facility is universally available on the ARM architectures,
125 // so it's up to individual OSes to provide such.
126 switch (feature) {
127 case VFP3:
128 search_string = "vfpv3";
129 break;
130 case NEON:
131 search_string = "neon";
132 break;
133 case ARMv7:
134 search_string = "ARMv7";
135 break;
136 case SUDIV:
137 search_string = "idiva";
138 break;
139 case VFP32DREGS:
140 // This case is handled specially below.
141 break;
142 default:
143 UNREACHABLE();
144 }
145
146 if (feature == VFP32DREGS) {
147 return ArmCpuHasFeature(VFP3) && !CPUInfoContainsString("d16");
148 }
149
150 if (CPUInfoContainsString(search_string)) {
151 return true;
152 }
153
154 if (feature == VFP3) {
155 // Some old kernels will report vfp not vfpv3. Here we make a last attempt
156 // to detect vfpv3 by checking for vfp *and* neon, since neon is only
157 // available on architectures with vfpv3.
158 // Checking neon on its own is not enough as it is possible to have neon
159 // without vfp.
160 if (CPUInfoContainsString("vfp") && CPUInfoContainsString("neon")) {
161 return true;
162 }
163 }
164
165 return false;
166 }
167
168
169 CpuImplementer OS::GetCpuImplementer() {
170 static bool use_cached_value = false;
171 static CpuImplementer cached_value = UNKNOWN_IMPLEMENTER;
172 if (use_cached_value) {
173 return cached_value;
174 }
175 if (CPUInfoContainsString("CPU implementer\t: 0x41")) {
176 cached_value = ARM_IMPLEMENTER;
177 } else if (CPUInfoContainsString("CPU implementer\t: 0x51")) {
178 cached_value = QUALCOMM_IMPLEMENTER;
179 } else {
180 cached_value = UNKNOWN_IMPLEMENTER;
181 }
182 use_cached_value = true;
183 return cached_value;
184 }
185
186
187 CpuPart OS::GetCpuPart(CpuImplementer implementer) {
188 static bool use_cached_value = false;
189 static CpuPart cached_value = CPU_UNKNOWN;
190 if (use_cached_value) {
191 return cached_value;
192 }
193 if (implementer == ARM_IMPLEMENTER) {
194 if (CPUInfoContainsString("CPU part\t: 0xc0f")) {
195 cached_value = CORTEX_A15;
196 } else if (CPUInfoContainsString("CPU part\t: 0xc0c")) {
197 cached_value = CORTEX_A12;
198 } else if (CPUInfoContainsString("CPU part\t: 0xc09")) {
199 cached_value = CORTEX_A9;
200 } else if (CPUInfoContainsString("CPU part\t: 0xc08")) {
201 cached_value = CORTEX_A8;
202 } else if (CPUInfoContainsString("CPU part\t: 0xc07")) {
203 cached_value = CORTEX_A7;
204 } else if (CPUInfoContainsString("CPU part\t: 0xc05")) {
205 cached_value = CORTEX_A5;
206 } else {
207 cached_value = CPU_UNKNOWN;
208 }
209 } else {
210 cached_value = CPU_UNKNOWN;
211 }
212 use_cached_value = true;
213 return cached_value;
214 }
215
216 83
217 bool OS::ArmUsingHardFloat() { 84 bool OS::ArmUsingHardFloat() {
218 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify 85 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
219 // the Floating Point ABI used (PCS stands for Procedure Call Standard). 86 // the Floating Point ABI used (PCS stands for Procedure Call Standard).
220 // We use these as well as a couple of other defines to statically determine 87 // We use these as well as a couple of other defines to statically determine
221 // what FP ABI used. 88 // what FP ABI used.
222 // GCC versions 4.4 and below don't support hard-fp. 89 // GCC versions 4.4 and below don't support hard-fp.
223 // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or 90 // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
224 // __ARM_PCS_VFP. 91 // __ARM_PCS_VFP.
225 92
(...skipping 22 matching lines...) Expand all
248 "http://code.google.com/p/v8/issues/detail?id=2140" 115 "http://code.google.com/p/v8/issues/detail?id=2140"
249 116
250 #endif 117 #endif
251 #endif 118 #endif
252 #undef GCC_VERSION 119 #undef GCC_VERSION
253 } 120 }
254 121
255 #endif // def __arm__ 122 #endif // def __arm__
256 123
257 124
258 #ifdef __mips__
259 bool OS::MipsCpuHasFeature(CpuFeature feature) {
260 const char* search_string = NULL;
261 const char* file_name = "/proc/cpuinfo";
262 // Simple detection of FPU at runtime for Linux.
263 // It is based on /proc/cpuinfo, which reveals hardware configuration
264 // to user-space applications. According to MIPS (early 2010), no similar
265 // facility is universally available on the MIPS architectures,
266 // so it's up to individual OSes to provide such.
267 //
268 // This is written as a straight shot one pass parser
269 // and not using STL string and ifstream because,
270 // on Linux, it's reading from a (non-mmap-able)
271 // character special device.
272
273 switch (feature) {
274 case FPU:
275 search_string = "FPU";
276 break;
277 default:
278 UNREACHABLE();
279 }
280
281 FILE* f = NULL;
282 const char* what = search_string;
283
284 if (NULL == (f = fopen(file_name, "r"))) {
285 OS::PrintError("Failed to open /proc/cpuinfo\n");
286 return false;
287 }
288
289 int k;
290 while (EOF != (k = fgetc(f))) {
291 if (k == *what) {
292 ++what;
293 while ((*what != '\0') && (*what == fgetc(f))) {
294 ++what;
295 }
296 if (*what == '\0') {
297 fclose(f);
298 return true;
299 } else {
300 what = search_string;
301 }
302 }
303 }
304 fclose(f);
305
306 // Did not find string in the proc file.
307 return false;
308 }
309 #endif // def __mips__
310
311
312 const char* OS::LocalTimezone(double time) { 125 const char* OS::LocalTimezone(double time) {
313 if (std::isnan(time)) return ""; 126 if (std::isnan(time)) return "";
314 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); 127 time_t tv = static_cast<time_t>(floor(time/msPerSecond));
315 struct tm* t = localtime(&tv); 128 struct tm* t = localtime(&tv);
316 if (NULL == t) return ""; 129 if (NULL == t) return "";
317 return t->tm_zone; 130 return t->tm_zone;
318 } 131 }
319 132
320 133
321 double OS::LocalTimeOffset() { 134 double OS::LocalTimeOffset() {
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 limit_mutex = CreateMutex(); 574 limit_mutex = CreateMutex();
762 } 575 }
763 576
764 577
765 void OS::TearDown() { 578 void OS::TearDown() {
766 delete limit_mutex; 579 delete limit_mutex;
767 } 580 }
768 581
769 582
770 } } // namespace v8::internal 583 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform.h ('k') | src/platform-nullos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698