OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flags.h" | 5 #include "vm/flags.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/json_stream.h" | 8 #include "vm/json_stream.h" |
9 #include "vm/os.h" | 9 #include "vm/os.h" |
10 | 10 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 #else // !PRODUCT && !PRECOMPILED | 53 #else // !PRODUCT && !PRECOMPILED |
54 #define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment) \ | 54 #define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment) \ |
55 type FLAG_##name = \ | 55 type FLAG_##name = \ |
56 Flags::Register_##type(&FLAG_##name, #name, default_value, comment); | 56 Flags::Register_##type(&FLAG_##name, #name, default_value, comment); |
57 #define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type, \ | 57 #define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type, \ |
58 default_value, comment) \ | 58 default_value, comment) \ |
59 type FLAG_##name = \ | 59 type FLAG_##name = \ |
60 Flags::Register_##type(&FLAG_##name, #name, default_value, comment); | 60 Flags::Register_##type(&FLAG_##name, #name, default_value, comment); |
61 #endif | 61 #endif |
62 | 62 |
63 | |
64 // Define all of the non-product flags here. | 63 // Define all of the non-product flags here. |
65 FLAG_LIST(PRODUCT_FLAG_MARCO, | 64 FLAG_LIST(PRODUCT_FLAG_MARCO, |
66 RELEASE_FLAG_MARCO, | 65 RELEASE_FLAG_MARCO, |
67 DEBUG_FLAG_MARCO, | 66 DEBUG_FLAG_MARCO, |
68 PRECOMPILE_FLAG_MARCO) | 67 PRECOMPILE_FLAG_MARCO) |
69 | 68 |
70 #undef RELEASE_FLAG_MARCO | 69 #undef RELEASE_FLAG_MARCO |
71 #undef DEBUG_FLAG_MARCO | 70 #undef DEBUG_FLAG_MARCO |
72 #undef PRODUCT_FLAG_MARCO | 71 #undef PRODUCT_FLAG_MARCO |
73 #undef PRECOMPILE_FLAG_MARCO | 72 #undef PRECOMPILE_FLAG_MARCO |
74 | 73 |
75 | |
76 bool Flags::initialized_ = false; | 74 bool Flags::initialized_ = false; |
77 | 75 |
78 // List of registered flags. | 76 // List of registered flags. |
79 Flag** Flags::flags_ = NULL; | 77 Flag** Flags::flags_ = NULL; |
80 intptr_t Flags::capacity_ = 0; | 78 intptr_t Flags::capacity_ = 0; |
81 intptr_t Flags::num_flags_ = 0; | 79 intptr_t Flags::num_flags_ = 0; |
82 | 80 |
83 class Flag { | 81 class Flag { |
84 public: | 82 public: |
85 enum FlagType { kBoolean, kInteger, kUint64, kString, kFunc, kNumFlagTypes }; | 83 enum FlagType { kBoolean, kInteger, kUint64, kString, kFunc, kNumFlagTypes }; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 bool* bool_ptr_; | 135 bool* bool_ptr_; |
138 int* int_ptr_; | 136 int* int_ptr_; |
139 uint64_t* uint64_ptr_; | 137 uint64_t* uint64_ptr_; |
140 charp* charp_ptr_; | 138 charp* charp_ptr_; |
141 FlagHandler handler_; | 139 FlagHandler handler_; |
142 }; | 140 }; |
143 FlagType type_; | 141 FlagType type_; |
144 bool changed_; | 142 bool changed_; |
145 }; | 143 }; |
146 | 144 |
147 | |
148 Flag* Flags::Lookup(const char* name) { | 145 Flag* Flags::Lookup(const char* name) { |
149 for (intptr_t i = 0; i < num_flags_; i++) { | 146 for (intptr_t i = 0; i < num_flags_; i++) { |
150 Flag* flag = flags_[i]; | 147 Flag* flag = flags_[i]; |
151 if (strcmp(flag->name_, name) == 0) { | 148 if (strcmp(flag->name_, name) == 0) { |
152 return flag; | 149 return flag; |
153 } | 150 } |
154 } | 151 } |
155 return NULL; | 152 return NULL; |
156 } | 153 } |
157 | 154 |
158 | |
159 bool Flags::IsSet(const char* name) { | 155 bool Flags::IsSet(const char* name) { |
160 Flag* flag = Lookup(name); | 156 Flag* flag = Lookup(name); |
161 return (flag != NULL) && (flag->type_ == Flag::kBoolean) && | 157 return (flag != NULL) && (flag->type_ == Flag::kBoolean) && |
162 (flag->bool_ptr_ != NULL) && (*flag->bool_ptr_ == true); | 158 (flag->bool_ptr_ != NULL) && (*flag->bool_ptr_ == true); |
163 } | 159 } |
164 | 160 |
165 | |
166 void Flags::AddFlag(Flag* flag) { | 161 void Flags::AddFlag(Flag* flag) { |
167 ASSERT(!initialized_); | 162 ASSERT(!initialized_); |
168 if (num_flags_ == capacity_) { | 163 if (num_flags_ == capacity_) { |
169 if (flags_ == NULL) { | 164 if (flags_ == NULL) { |
170 capacity_ = 256; | 165 capacity_ = 256; |
171 flags_ = new Flag*[capacity_]; | 166 flags_ = new Flag*[capacity_]; |
172 } else { | 167 } else { |
173 intptr_t new_capacity = capacity_ * 2; | 168 intptr_t new_capacity = capacity_ * 2; |
174 Flag** new_flags = new Flag*[new_capacity]; | 169 Flag** new_flags = new Flag*[new_capacity]; |
175 for (intptr_t i = 0; i < num_flags_; i++) { | 170 for (intptr_t i = 0; i < num_flags_; i++) { |
176 new_flags[i] = flags_[i]; | 171 new_flags[i] = flags_[i]; |
177 } | 172 } |
178 delete[] flags_; | 173 delete[] flags_; |
179 flags_ = new_flags; | 174 flags_ = new_flags; |
180 capacity_ = new_capacity; | 175 capacity_ = new_capacity; |
181 } | 176 } |
182 } | 177 } |
183 flags_[num_flags_++] = flag; | 178 flags_[num_flags_++] = flag; |
184 } | 179 } |
185 | 180 |
186 | |
187 bool Flags::Register_bool(bool* addr, | 181 bool Flags::Register_bool(bool* addr, |
188 const char* name, | 182 const char* name, |
189 bool default_value, | 183 bool default_value, |
190 const char* comment) { | 184 const char* comment) { |
191 Flag* flag = Lookup(name); | 185 Flag* flag = Lookup(name); |
192 if (flag != NULL) { | 186 if (flag != NULL) { |
193 ASSERT(flag->IsUnrecognized()); | 187 ASSERT(flag->IsUnrecognized()); |
194 return default_value; | 188 return default_value; |
195 } | 189 } |
196 flag = new Flag(name, comment, addr, Flag::kBoolean); | 190 flag = new Flag(name, comment, addr, Flag::kBoolean); |
197 AddFlag(flag); | 191 AddFlag(flag); |
198 return default_value; | 192 return default_value; |
199 } | 193 } |
200 | 194 |
201 | |
202 int Flags::Register_int(int* addr, | 195 int Flags::Register_int(int* addr, |
203 const char* name, | 196 const char* name, |
204 int default_value, | 197 int default_value, |
205 const char* comment) { | 198 const char* comment) { |
206 ASSERT(Lookup(name) == NULL); | 199 ASSERT(Lookup(name) == NULL); |
207 | 200 |
208 Flag* flag = new Flag(name, comment, addr, Flag::kInteger); | 201 Flag* flag = new Flag(name, comment, addr, Flag::kInteger); |
209 AddFlag(flag); | 202 AddFlag(flag); |
210 | 203 |
211 return default_value; | 204 return default_value; |
212 } | 205 } |
213 | 206 |
214 | |
215 uint64_t Flags::Register_uint64_t(uint64_t* addr, | 207 uint64_t Flags::Register_uint64_t(uint64_t* addr, |
216 const char* name, | 208 const char* name, |
217 uint64_t default_value, | 209 uint64_t default_value, |
218 const char* comment) { | 210 const char* comment) { |
219 ASSERT(Lookup(name) == NULL); | 211 ASSERT(Lookup(name) == NULL); |
220 | 212 |
221 Flag* flag = new Flag(name, comment, addr, Flag::kUint64); | 213 Flag* flag = new Flag(name, comment, addr, Flag::kUint64); |
222 AddFlag(flag); | 214 AddFlag(flag); |
223 | 215 |
224 return default_value; | 216 return default_value; |
225 } | 217 } |
226 | 218 |
227 | |
228 const char* Flags::Register_charp(charp* addr, | 219 const char* Flags::Register_charp(charp* addr, |
229 const char* name, | 220 const char* name, |
230 const char* default_value, | 221 const char* default_value, |
231 const char* comment) { | 222 const char* comment) { |
232 ASSERT(Lookup(name) == NULL); | 223 ASSERT(Lookup(name) == NULL); |
233 Flag* flag = new Flag(name, comment, addr, Flag::kString); | 224 Flag* flag = new Flag(name, comment, addr, Flag::kString); |
234 AddFlag(flag); | 225 AddFlag(flag); |
235 return default_value; | 226 return default_value; |
236 } | 227 } |
237 | 228 |
238 | |
239 bool Flags::Register_func(FlagHandler handler, | 229 bool Flags::Register_func(FlagHandler handler, |
240 const char* name, | 230 const char* name, |
241 const char* comment) { | 231 const char* comment) { |
242 ASSERT(Lookup(name) == NULL); | 232 ASSERT(Lookup(name) == NULL); |
243 Flag* flag = new Flag(name, comment, handler); | 233 Flag* flag = new Flag(name, comment, handler); |
244 AddFlag(flag); | 234 AddFlag(flag); |
245 return false; | 235 return false; |
246 } | 236 } |
247 | 237 |
248 | |
249 static void Normalize(char* s) { | 238 static void Normalize(char* s) { |
250 intptr_t len = strlen(s); | 239 intptr_t len = strlen(s); |
251 for (intptr_t i = 0; i < len; i++) { | 240 for (intptr_t i = 0; i < len; i++) { |
252 if (s[i] == '-') { | 241 if (s[i] == '-') { |
253 s[i] = '_'; | 242 s[i] = '_'; |
254 } | 243 } |
255 } | 244 } |
256 } | 245 } |
257 | 246 |
258 | |
259 bool Flags::SetFlagFromString(Flag* flag, const char* argument) { | 247 bool Flags::SetFlagFromString(Flag* flag, const char* argument) { |
260 ASSERT(!flag->IsUnrecognized()); | 248 ASSERT(!flag->IsUnrecognized()); |
261 switch (flag->type_) { | 249 switch (flag->type_) { |
262 case Flag::kBoolean: { | 250 case Flag::kBoolean: { |
263 if (strcmp(argument, "true") == 0) { | 251 if (strcmp(argument, "true") == 0) { |
264 *flag->bool_ptr_ = true; | 252 *flag->bool_ptr_ = true; |
265 } else if (strcmp(argument, "false") == 0) { | 253 } else if (strcmp(argument, "false") == 0) { |
266 *flag->bool_ptr_ = false; | 254 *flag->bool_ptr_ = false; |
267 } else { | 255 } else { |
268 return false; | 256 return false; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 } | 303 } |
316 default: { | 304 default: { |
317 UNREACHABLE(); | 305 UNREACHABLE(); |
318 return false; | 306 return false; |
319 } | 307 } |
320 } | 308 } |
321 flag->changed_ = true; | 309 flag->changed_ = true; |
322 return true; | 310 return true; |
323 } | 311 } |
324 | 312 |
325 | |
326 void Flags::Parse(const char* option) { | 313 void Flags::Parse(const char* option) { |
327 // Find the beginning of the option argument, if it exists. | 314 // Find the beginning of the option argument, if it exists. |
328 const char* equals = option; | 315 const char* equals = option; |
329 while ((*equals != '\0') && (*equals != '=')) { | 316 while ((*equals != '\0') && (*equals != '=')) { |
330 equals++; | 317 equals++; |
331 } | 318 } |
332 | 319 |
333 const char* argument = NULL; | 320 const char* argument = NULL; |
334 | 321 |
335 // Determine if this is an option argument. | 322 // Determine if this is an option argument. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 if (!SetFlagFromString(flag, argument)) { | 362 if (!SetFlagFromString(flag, argument)) { |
376 OS::Print("Ignoring flag: %s is an invalid value for flag %s\n", | 363 OS::Print("Ignoring flag: %s is an invalid value for flag %s\n", |
377 argument, name); | 364 argument, name); |
378 } | 365 } |
379 } | 366 } |
380 } | 367 } |
381 | 368 |
382 delete[] name; | 369 delete[] name; |
383 } | 370 } |
384 | 371 |
385 | |
386 static bool IsValidFlag(const char* name, | 372 static bool IsValidFlag(const char* name, |
387 const char* prefix, | 373 const char* prefix, |
388 intptr_t prefix_length) { | 374 intptr_t prefix_length) { |
389 intptr_t name_length = strlen(name); | 375 intptr_t name_length = strlen(name); |
390 return ((name_length > prefix_length) && | 376 return ((name_length > prefix_length) && |
391 (strncmp(name, prefix, prefix_length) == 0)); | 377 (strncmp(name, prefix, prefix_length) == 0)); |
392 } | 378 } |
393 | 379 |
394 | |
395 int Flags::CompareFlagNames(const void* left, const void* right) { | 380 int Flags::CompareFlagNames(const void* left, const void* right) { |
396 const Flag* left_flag = *reinterpret_cast<const Flag* const*>(left); | 381 const Flag* left_flag = *reinterpret_cast<const Flag* const*>(left); |
397 const Flag* right_flag = *reinterpret_cast<const Flag* const*>(right); | 382 const Flag* right_flag = *reinterpret_cast<const Flag* const*>(right); |
398 return strcmp(left_flag->name_, right_flag->name_); | 383 return strcmp(left_flag->name_, right_flag->name_); |
399 } | 384 } |
400 | 385 |
401 | |
402 bool Flags::ProcessCommandLineFlags(int number_of_vm_flags, | 386 bool Flags::ProcessCommandLineFlags(int number_of_vm_flags, |
403 const char** vm_flags) { | 387 const char** vm_flags) { |
404 if (initialized_) { | 388 if (initialized_) { |
405 return false; | 389 return false; |
406 } | 390 } |
407 | 391 |
408 qsort(flags_, num_flags_, sizeof flags_[0], CompareFlagNames); | 392 qsort(flags_, num_flags_, sizeof flags_[0], CompareFlagNames); |
409 | 393 |
410 const char* const kPrefix = "--"; | 394 const char* const kPrefix = "--"; |
411 const intptr_t kPrefixLen = strlen(kPrefix); | 395 const intptr_t kPrefixLen = strlen(kPrefix); |
(...skipping 25 matching lines...) Expand all Loading... |
437 } | 421 } |
438 } | 422 } |
439 if (FLAG_print_flags) { | 423 if (FLAG_print_flags) { |
440 PrintFlags(); | 424 PrintFlags(); |
441 } | 425 } |
442 | 426 |
443 initialized_ = true; | 427 initialized_ = true; |
444 return true; | 428 return true; |
445 } | 429 } |
446 | 430 |
447 | |
448 bool Flags::SetFlag(const char* name, const char* value, const char** error) { | 431 bool Flags::SetFlag(const char* name, const char* value, const char** error) { |
449 Flag* flag = Lookup(name); | 432 Flag* flag = Lookup(name); |
450 if (flag == NULL) { | 433 if (flag == NULL) { |
451 *error = "Cannot set flag: flag not found"; | 434 *error = "Cannot set flag: flag not found"; |
452 return false; | 435 return false; |
453 } | 436 } |
454 if (!SetFlagFromString(flag, value)) { | 437 if (!SetFlagFromString(flag, value)) { |
455 *error = "Cannot set flag: invalid value"; | 438 *error = "Cannot set flag: invalid value"; |
456 return false; | 439 return false; |
457 } | 440 } |
458 return true; | 441 return true; |
459 } | 442 } |
460 | 443 |
461 | |
462 void Flags::PrintFlags() { | 444 void Flags::PrintFlags() { |
463 OS::Print("Flag settings:\n"); | 445 OS::Print("Flag settings:\n"); |
464 for (intptr_t i = 0; i < num_flags_; ++i) { | 446 for (intptr_t i = 0; i < num_flags_; ++i) { |
465 flags_[i]->Print(); | 447 flags_[i]->Print(); |
466 } | 448 } |
467 } | 449 } |
468 | 450 |
469 | |
470 #ifndef PRODUCT | 451 #ifndef PRODUCT |
471 void Flags::PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag) { | 452 void Flags::PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag) { |
472 if (!FLAG_support_service) { | 453 if (!FLAG_support_service) { |
473 return; | 454 return; |
474 } | 455 } |
475 if (flag->IsUnrecognized() || flag->type_ == Flag::kFunc) { | 456 if (flag->IsUnrecognized() || flag->type_ == Flag::kFunc) { |
476 return; | 457 return; |
477 } | 458 } |
478 JSONObject jsflag(jsarr); | 459 JSONObject jsflag(jsarr); |
479 jsflag.AddProperty("name", flag->name_); | 460 jsflag.AddProperty("name", flag->name_); |
(...skipping 24 matching lines...) Expand all Loading... |
504 // valueAsString missing means NULL. | 485 // valueAsString missing means NULL. |
505 } | 486 } |
506 break; | 487 break; |
507 } | 488 } |
508 default: | 489 default: |
509 UNREACHABLE(); | 490 UNREACHABLE(); |
510 break; | 491 break; |
511 } | 492 } |
512 } | 493 } |
513 | 494 |
514 | |
515 void Flags::PrintJSON(JSONStream* js) { | 495 void Flags::PrintJSON(JSONStream* js) { |
516 if (!FLAG_support_service) { | 496 if (!FLAG_support_service) { |
517 return; | 497 return; |
518 } | 498 } |
519 JSONObject jsobj(js); | 499 JSONObject jsobj(js); |
520 jsobj.AddProperty("type", "FlagList"); | 500 jsobj.AddProperty("type", "FlagList"); |
521 JSONArray jsarr(&jsobj, "flags"); | 501 JSONArray jsarr(&jsobj, "flags"); |
522 for (intptr_t i = 0; i < num_flags_; ++i) { | 502 for (intptr_t i = 0; i < num_flags_; ++i) { |
523 PrintFlagToJSONArray(&jsarr, flags_[i]); | 503 PrintFlagToJSONArray(&jsarr, flags_[i]); |
524 } | 504 } |
525 } | 505 } |
526 #endif // !PRODUCT | 506 #endif // !PRODUCT |
527 | 507 |
528 } // namespace dart | 508 } // namespace dart |
OLD | NEW |