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

Side by Side Diff: runtime/vm/flags.cc

Issue 299143007: Show flags in Observatory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweaks Created 6 years, 7 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 | « runtime/vm/flags.h ('k') | runtime/vm/service.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 (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/os.h" 9 #include "vm/os.h"
9 10
10 namespace dart { 11 namespace dart {
11 12
12 DEFINE_FLAG(bool, print_flags, false, "Print flags as they are being parsed."); 13 DEFINE_FLAG(bool, print_flags, false, "Print flags as they are being parsed.");
13 DEFINE_FLAG(bool, ignore_unrecognized_flags, false, 14 DEFINE_FLAG(bool, ignore_unrecognized_flags, false,
14 "Ignore unrecognized flags."); 15 "Ignore unrecognized flags.");
15 16
17 bool Flags::initialized_ = false;
18
16 // List of registered flags. 19 // List of registered flags.
17 Flag* Flags::flags_ = NULL; 20 Flag** Flags::flags_ = NULL;
18 21 intptr_t Flags::capacity_ = 0;
19 bool Flags::initialized_ = false; 22 intptr_t Flags::num_flags_ = 0;
20 23
21 class Flag { 24 class Flag {
22 public: 25 public:
23 enum FlagType { 26 enum FlagType {
24 kBoolean, 27 kBoolean,
25 kInteger, 28 kInteger,
26 kString, 29 kString,
27 kFunc, 30 kFunc,
28 kNumFlagTypes 31 kNumFlagTypes
29 }; 32 };
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 default: 68 default:
66 UNREACHABLE(); 69 UNREACHABLE();
67 break; 70 break;
68 } 71 }
69 } 72 }
70 73
71 bool IsUnrecognized() const { 74 bool IsUnrecognized() const {
72 return (type_ == kBoolean) && (bool_ptr_ == NULL); 75 return (type_ == kBoolean) && (bool_ptr_ == NULL);
73 } 76 }
74 77
75 Flag* next_;
76 const char* name_; 78 const char* name_;
77 const char* comment_; 79 const char* comment_;
78 union { 80 union {
79 void* addr_; 81 void* addr_;
80 bool* bool_ptr_; 82 bool* bool_ptr_;
81 int* int_ptr_; 83 int* int_ptr_;
82 charp* charp_ptr_; 84 charp* charp_ptr_;
83 FlagHandler handler_; 85 FlagHandler handler_;
84 }; 86 };
85 FlagType type_; 87 FlagType type_;
88 bool changed_;
86 }; 89 };
87 90
88 91
89 Flag* Flags::Lookup(const char* name) { 92 Flag* Flags::Lookup(const char* name) {
90 Flag* cur = Flags::flags_; 93 for (intptr_t i = 0; i < num_flags_; i++) {
91 while (cur != NULL) { 94 Flag* flag = flags_[i];
92 if (strcmp(cur->name_, name) == 0) { 95 if (strcmp(flag->name_, name) == 0) {
93 return cur; 96 return flag;
94 } 97 }
95 cur = cur->next_;
96 } 98 }
97 return NULL; 99 return NULL;
98 } 100 }
99 101
100 102
103 void Flags::AddFlag(Flag* flag) {
104 ASSERT(!initialized_);
105 if (num_flags_ == capacity_) {
106 if (flags_ == NULL) {
107 capacity_ = 256;
108 flags_ = new Flag*[capacity_];
Cutch 2014/05/26 05:48:33 My preference would be for calloc / realloc.
109 } else {
110 intptr_t new_capacity = capacity_ * 2;
111 Flag** new_flags = new Flag*[new_capacity];
Cutch 2014/05/26 05:48:33 realloc instead
112 for (intptr_t i = 0; i < num_flags_; i++) {
113 new_flags[i] = flags_[i];
114 }
115 delete flags_;
Cutch 2014/05/26 05:48:33 if you stick with new, this must be array delete:
turnidge 2014/05/27 21:26:00 Fixed delete. Didn't go to realloc because I don'
116 flags_ = new_flags;
117 capacity_ = new_capacity;
118 }
119 }
120 flags_[num_flags_++] = flag;
121 }
122
123
101 bool Flags::Register_bool(bool* addr, 124 bool Flags::Register_bool(bool* addr,
102 const char* name, 125 const char* name,
103 bool default_value, 126 bool default_value,
104 const char* comment) { 127 const char* comment) {
105 Flag* flag = Lookup(name); 128 Flag* flag = Lookup(name);
106 if (flag != NULL) { 129 if (flag != NULL) {
107 ASSERT(flag->IsUnrecognized()); 130 ASSERT(flag->IsUnrecognized());
108 return default_value; 131 return default_value;
109 } 132 }
110 flag = new Flag(name, comment, addr, Flag::kBoolean); 133 flag = new Flag(name, comment, addr, Flag::kBoolean);
111 flag->next_ = Flags::flags_; 134 AddFlag(flag);
112 Flags::flags_ = flag;
113
114 return default_value; 135 return default_value;
115 } 136 }
116 137
117 138
118 int Flags::Register_int(int* addr, 139 int Flags::Register_int(int* addr,
119 const char* name, 140 const char* name,
120 int default_value, 141 int default_value,
121 const char* comment) { 142 const char* comment) {
122 ASSERT(Lookup(name) == NULL); 143 ASSERT(Lookup(name) == NULL);
123 144
124 Flag* flag = new Flag(name, comment, addr, Flag::kInteger); 145 Flag* flag = new Flag(name, comment, addr, Flag::kInteger);
125 flag->next_ = Flags::flags_; 146 AddFlag(flag);
126 Flags::flags_ = flag;
127 147
128 return default_value; 148 return default_value;
129 } 149 }
130 150
131 151
132 const char* Flags::Register_charp(charp* addr, 152 const char* Flags::Register_charp(charp* addr,
133 const char* name, 153 const char* name,
134 const char* default_value, 154 const char* default_value,
135 const char* comment) { 155 const char* comment) {
136 ASSERT(Lookup(name) == NULL); 156 ASSERT(Lookup(name) == NULL);
137 Flag* flag = new Flag(name, comment, addr, Flag::kString); 157 Flag* flag = new Flag(name, comment, addr, Flag::kString);
138 flag->next_ = Flags::flags_; 158 AddFlag(flag);
139 Flags::flags_ = flag;
140 return default_value; 159 return default_value;
141 } 160 }
142 161
143 162
144 bool Flags::Register_func(FlagHandler handler, 163 bool Flags::Register_func(FlagHandler handler,
145 const char* name, 164 const char* name,
146 const char* comment) { 165 const char* comment) {
147 ASSERT(Lookup(name) == NULL); 166 ASSERT(Lookup(name) == NULL);
148 Flag* flag = new Flag(name, comment, handler); 167 Flag* flag = new Flag(name, comment, handler);
149 flag->next_ = Flags::flags_; 168 AddFlag(flag);
150 Flags::flags_ = flag;
151 return false; 169 return false;
152 } 170 }
153 171
154 172
155 static void Normalize(char* s) { 173 static void Normalize(char* s) {
156 intptr_t len = strlen(s); 174 intptr_t len = strlen(s);
157 for (intptr_t i = 0; i < len; i++) { 175 for (intptr_t i = 0; i < len; i++) {
158 if (s[i] == '-') { 176 if (s[i] == '-') {
159 s[i] = '_'; 177 s[i] = '_';
160 } 178 }
161 } 179 }
162 } 180 }
163 181
164 182
183 bool Flags::SetFlagFromString(Flag* flag, const char* argument) {
184 ASSERT(!flag->IsUnrecognized());
185 switch (flag->type_) {
186 case Flag::kBoolean: {
187 if (strcmp(argument, "true") == 0) {
188 *flag->bool_ptr_ = true;
189 } else if (strcmp(argument, "false") == 0) {
190 *flag->bool_ptr_ = false;
191 } else {
192 return false;
193 }
194 break;
195 }
196 case Flag::kString: {
197 *flag->charp_ptr_ = argument == NULL ? NULL : strdup(argument);
198 break;
199 }
200 case Flag::kInteger: {
201 char* endptr = NULL;
202 int val = strtol(argument, &endptr, 10);
203 if (endptr != argument) {
204 *flag->int_ptr_ = val;
205 }
206 break;
207 }
208 case Flag::kFunc: {
209 if (strcmp(argument, "true") == 0) {
210 (flag->handler_)(true);
211 } else if (strcmp(argument, "false") == 0) {
212 (flag->handler_)(false);
213 } else {
214 return false;
215 }
216 break;
217 }
218 default: {
219 UNREACHABLE();
220 return false;
221 }
222 }
223 flag->changed_ = true;
224 return true;
225 }
226
227
165 void Flags::Parse(const char* option) { 228 void Flags::Parse(const char* option) {
166 // Find the beginning of the option argument, if it exists. 229 // Find the beginning of the option argument, if it exists.
167 const char* equals = option; 230 const char* equals = option;
168 while ((*equals != '\0') && (*equals != '=')) { 231 while ((*equals != '\0') && (*equals != '=')) {
169 equals++; 232 equals++;
170 } 233 }
171 234
172 const char* argument = NULL; 235 const char* argument = NULL;
173 236
174 // Determine if this is an option argument. 237 // Determine if this is an option argument.
(...skipping 29 matching lines...) Expand all
204 if (flag == NULL) { 267 if (flag == NULL) {
205 // Collect unrecognized flags. 268 // Collect unrecognized flags.
206 char* new_flag = new char[name_len + 1]; 269 char* new_flag = new char[name_len + 1];
207 strncpy(new_flag, option, name_len); 270 strncpy(new_flag, option, name_len);
208 new_flag[name_len] = '\0'; 271 new_flag[name_len] = '\0';
209 Flags::Register_bool(NULL, new_flag, true, NULL); 272 Flags::Register_bool(NULL, new_flag, true, NULL);
210 } else { 273 } else {
211 // Only set values for recognized flags, skip collected 274 // Only set values for recognized flags, skip collected
212 // unrecognized flags. 275 // unrecognized flags.
213 if (!flag->IsUnrecognized()) { 276 if (!flag->IsUnrecognized()) {
214 switch (flag->type_) { 277 if (!SetFlagFromString(flag, argument)) {
215 case Flag::kBoolean: { 278 OS::Print("Ignoring flag: %s is an invalid value for flag %s\n",
216 if (strcmp(argument, "true") == 0) { 279 argument, name);
217 *flag->bool_ptr_ = true;
218 } else if (strcmp(argument, "false") == 0) {
219 *flag->bool_ptr_ = false;
220 } else {
221 OS::Print("Ignoring flag: %s is a bool flag.\n", name);
222 }
223 break;
224 }
225 case Flag::kString: {
226 *flag->charp_ptr_ = argument == NULL ? NULL : strdup(argument);
227 break;
228 }
229 case Flag::kInteger: {
230 char* endptr = NULL;
231 int val = strtol(argument, &endptr, 10);
232 if (endptr != argument) {
233 *flag->int_ptr_ = val;
234 }
235 break;
236 }
237 case Flag::kFunc: {
238 if (strcmp(argument, "true") == 0) {
239 (flag->handler_)(true);
240 } else if (strcmp(argument, "false") == 0) {
241 (flag->handler_)(false);
242 } else {
243 OS::Print("Ignoring flag: %s is a bool flag.\n", name);
244 }
245 break;
246 }
247 default: {
248 UNREACHABLE();
249 break;
250 }
251 } 280 }
252 } 281 }
253 } 282 }
254 283
255 delete[] name; 284 delete[] name;
256 } 285 }
257 286
258 287
259 static bool IsValidFlag(const char* name, 288 static bool IsValidFlag(const char* name,
260 const char* prefix, 289 const char* prefix,
261 intptr_t prefix_length) { 290 intptr_t prefix_length) {
262 intptr_t name_length = strlen(name); 291 intptr_t name_length = strlen(name);
263 return ((name_length > prefix_length) && 292 return ((name_length > prefix_length) &&
264 (strncmp(name, prefix, prefix_length) == 0)); 293 (strncmp(name, prefix, prefix_length) == 0));
265 } 294 }
266 295
267 296
297 int Flags::CompareFlagNames(const void* left, const void* right) {
298 const Flag* left_flag = *reinterpret_cast<const Flag* const *>(left);
299 const Flag* right_flag = *reinterpret_cast<const Flag* const *>(right);
300 return strcmp(left_flag->name_, right_flag->name_);
301 }
302
303
268 bool Flags::ProcessCommandLineFlags(int number_of_vm_flags, 304 bool Flags::ProcessCommandLineFlags(int number_of_vm_flags,
269 const char** vm_flags) { 305 const char** vm_flags) {
270 if (initialized_) { 306 if (initialized_) {
271 return false; 307 return false;
272 } 308 }
273 309
274 initialized_ = true; 310 initialized_ = true;
311 qsort(flags_, num_flags_, sizeof flags_[0], CompareFlagNames);
275 312
276 const char* kPrefix = "--"; 313 const char* kPrefix = "--";
277 const intptr_t kPrefixLen = strlen(kPrefix); 314 const intptr_t kPrefixLen = strlen(kPrefix);
278 315
279 int i = 0; 316 int i = 0;
280 while ((i < number_of_vm_flags) && 317 while ((i < number_of_vm_flags) &&
281 IsValidFlag(vm_flags[i], kPrefix, kPrefixLen)) { 318 IsValidFlag(vm_flags[i], kPrefix, kPrefixLen)) {
282 const char* option = vm_flags[i] + kPrefixLen; 319 const char* option = vm_flags[i] + kPrefixLen;
283 Parse(option); 320 Parse(option);
284 i++; 321 i++;
285 } 322 }
286 323
287 if (!FLAG_ignore_unrecognized_flags) { 324 if (!FLAG_ignore_unrecognized_flags) {
288 int unrecognized_count = 0; 325 int unrecognized_count = 0;
289 Flag* flag = Flags::flags_; 326 for (intptr_t j = 0; j < num_flags_; j++) {
290 while (flag != NULL) { 327 Flag* flag = flags_[j];
291 if (flag->IsUnrecognized()) { 328 if (flag->IsUnrecognized()) {
292 if (unrecognized_count == 0) { 329 if (unrecognized_count == 0) {
293 OS::PrintErr("Unrecognized flags: %s", flag->name_); 330 OS::PrintErr("Unrecognized flags: %s", flag->name_);
294 } else { 331 } else {
295 OS::PrintErr(", %s", flag->name_); 332 OS::PrintErr(", %s", flag->name_);
296 } 333 }
297 unrecognized_count++; 334 unrecognized_count++;
298 } 335 }
299 flag = flag->next_;
300 } 336 }
301 if (unrecognized_count > 0) { 337 if (unrecognized_count > 0) {
302 OS::PrintErr("\n"); 338 OS::PrintErr("\n");
303 exit(255); 339 exit(255);
304 } 340 }
305 } 341 }
306 if (FLAG_print_flags) { 342 if (FLAG_print_flags) {
307 PrintFlags(); 343 PrintFlags();
308 } 344 }
309 return true; 345 return true;
310 } 346 }
311 347
348 bool Flags::SetFlag(const char* name,
349 const char* value,
350 const char** error) {
351 Flag* flag = Lookup(name);
352 if (flag == NULL) {
353 *error = "Cannot set flag: flag not found";
354 return false;
355 }
356 if (!SetFlagFromString(flag, value)) {
357 *error = "Cannot set flag: invalid value";
358 return false;
359 }
360 return true;
361 }
362
312 363
313 int Flags::CompareFlagNames(const void* left, const void* right) { 364 void Flags::PrintFlags() {
314 const Flag* left_flag = *reinterpret_cast<const Flag* const *>(left); 365 OS::Print("Flag settings:\n");
315 const Flag* right_flag = *reinterpret_cast<const Flag* const *>(right); 366 for (intptr_t i = 0; i < num_flags_; ++i) {
316 return strcmp(left_flag->name_, right_flag->name_); 367 flags_[i]->Print();
368 }
317 } 369 }
318 370
319 371
320 void Flags::PrintFlags() { 372 void Flags::PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag) {
321 OS::Print("Flag settings:\n"); 373 if (flag->IsUnrecognized() || flag->type_ == Flag::kFunc) {
322 Flag* flag = Flags::flags_; 374 return;
323 int num_flags = 0; 375 }
324 while (flag != NULL) { 376 JSONObject jsflag(jsarr);
325 num_flags++; 377 jsflag.AddProperty("name", flag->name_);
326 flag = flag->next_; 378 jsflag.AddProperty("comment", flag->comment_);
379 switch (flag->type_) {
380 case Flag::kBoolean: {
381 jsflag.AddProperty("flagType", "bool");
382 jsflag.AddProperty("valueAsString",
383 (*flag->bool_ptr_ ? "true" : "false"));
384 break;
327 } 385 }
328 Flag** flag_array = new Flag*[num_flags]; 386 case Flag::kInteger: {
329 flag = Flags::flags_; 387 jsflag.AddProperty("flagType", "int");
330 for (int i = 0; i < num_flags; ++i, flag = flag->next_) { 388 jsflag.AddPropertyF("valueAsString", "%d", *flag->int_ptr_);
331 flag_array[i] = flag; 389 break;
332 } 390 }
391 case Flag::kString: {
392 jsflag.AddProperty("flagType", "string");
393 if (flag->charp_ptr_ != NULL) {
394 jsflag.AddPropertyF("valueAsString", "%s", *flag->charp_ptr_);
395 } else {
396 // valueAsString missing means NULL.
397 }
398 break;
399 }
400 default:
401 UNREACHABLE();
402 break;
403 }
404 }
333 405
334 qsort(flag_array, num_flags, sizeof flag_array[0], CompareFlagNames);
335 406
336 for (int i = 0; i < num_flags; ++i) { 407 void Flags::PrintJSON(JSONStream* js) {
337 flag_array[i]->Print(); 408 JSONObject jsobj(js);
409 jsobj.AddProperty("type", "FlagList");
410 jsobj.AddProperty("id", "flags");
411
412 {
413 JSONArray jsarr(&jsobj, "unmodifiedFlags");
414 for (intptr_t i = 0; i < num_flags_; ++i) {
415 Flag* flag = flags_[i];
416 if (!flag->changed_) {
417 PrintFlagToJSONArray(&jsarr, flag);
418 }
338 } 419 }
339 delete[] flag_array;
340 } 420 }
421 {
422 JSONArray jsarr(&jsobj, "modifiedFlags");
423 for (intptr_t i = 0; i < num_flags_; ++i) {
424 Flag* flag = flags_[i];
425 if (flag->changed_) {
426 PrintFlagToJSONArray(&jsarr, flag);
427 }
428 }
429 }
430 }
431
341 } // namespace dart 432 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flags.h ('k') | runtime/vm/service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698