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

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: gen js + code review 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
101 bool Flags::IsSet(const char* name) { 103 bool Flags::IsSet(const char* name) {
102 Flag* flag = Lookup(name); 104 Flag* flag = Lookup(name);
103 return (flag != NULL) && 105 return (flag != NULL) &&
104 (flag->type_ == Flag::kBoolean) && 106 (flag->type_ == Flag::kBoolean) &&
105 (flag->bool_ptr_ != NULL) && 107 (flag->bool_ptr_ != NULL) &&
106 (*flag->bool_ptr_ == true); 108 (*flag->bool_ptr_ == true);
107 } 109 }
108 110
109 111
112 void Flags::AddFlag(Flag* flag) {
113 ASSERT(!initialized_);
114 if (num_flags_ == capacity_) {
115 if (flags_ == NULL) {
116 capacity_ = 256;
117 flags_ = new Flag*[capacity_];
118 } else {
119 intptr_t new_capacity = capacity_ * 2;
120 Flag** new_flags = new Flag*[new_capacity];
121 for (intptr_t i = 0; i < num_flags_; i++) {
122 new_flags[i] = flags_[i];
123 }
124 delete [] flags_;
125 flags_ = new_flags;
126 capacity_ = new_capacity;
127 }
128 }
129 flags_[num_flags_++] = flag;
130 }
131
132
110 bool Flags::Register_bool(bool* addr, 133 bool Flags::Register_bool(bool* addr,
111 const char* name, 134 const char* name,
112 bool default_value, 135 bool default_value,
113 const char* comment) { 136 const char* comment) {
114 Flag* flag = Lookup(name); 137 Flag* flag = Lookup(name);
115 if (flag != NULL) { 138 if (flag != NULL) {
116 ASSERT(flag->IsUnrecognized()); 139 ASSERT(flag->IsUnrecognized());
117 return default_value; 140 return default_value;
118 } 141 }
119 flag = new Flag(name, comment, addr, Flag::kBoolean); 142 flag = new Flag(name, comment, addr, Flag::kBoolean);
120 flag->next_ = Flags::flags_; 143 AddFlag(flag);
121 Flags::flags_ = flag;
122
123 return default_value; 144 return default_value;
124 } 145 }
125 146
126 147
127 int Flags::Register_int(int* addr, 148 int Flags::Register_int(int* addr,
128 const char* name, 149 const char* name,
129 int default_value, 150 int default_value,
130 const char* comment) { 151 const char* comment) {
131 ASSERT(Lookup(name) == NULL); 152 ASSERT(Lookup(name) == NULL);
132 153
133 Flag* flag = new Flag(name, comment, addr, Flag::kInteger); 154 Flag* flag = new Flag(name, comment, addr, Flag::kInteger);
134 flag->next_ = Flags::flags_; 155 AddFlag(flag);
135 Flags::flags_ = flag;
136 156
137 return default_value; 157 return default_value;
138 } 158 }
139 159
140 160
141 const char* Flags::Register_charp(charp* addr, 161 const char* Flags::Register_charp(charp* addr,
142 const char* name, 162 const char* name,
143 const char* default_value, 163 const char* default_value,
144 const char* comment) { 164 const char* comment) {
145 ASSERT(Lookup(name) == NULL); 165 ASSERT(Lookup(name) == NULL);
146 Flag* flag = new Flag(name, comment, addr, Flag::kString); 166 Flag* flag = new Flag(name, comment, addr, Flag::kString);
147 flag->next_ = Flags::flags_; 167 AddFlag(flag);
148 Flags::flags_ = flag;
149 return default_value; 168 return default_value;
150 } 169 }
151 170
152 171
153 bool Flags::Register_func(FlagHandler handler, 172 bool Flags::Register_func(FlagHandler handler,
154 const char* name, 173 const char* name,
155 const char* comment) { 174 const char* comment) {
156 ASSERT(Lookup(name) == NULL); 175 ASSERT(Lookup(name) == NULL);
157 Flag* flag = new Flag(name, comment, handler); 176 Flag* flag = new Flag(name, comment, handler);
158 flag->next_ = Flags::flags_; 177 AddFlag(flag);
159 Flags::flags_ = flag;
160 return false; 178 return false;
161 } 179 }
162 180
163 181
164 static void Normalize(char* s) { 182 static void Normalize(char* s) {
165 intptr_t len = strlen(s); 183 intptr_t len = strlen(s);
166 for (intptr_t i = 0; i < len; i++) { 184 for (intptr_t i = 0; i < len; i++) {
167 if (s[i] == '-') { 185 if (s[i] == '-') {
168 s[i] = '_'; 186 s[i] = '_';
169 } 187 }
170 } 188 }
171 } 189 }
172 190
173 191
192 bool Flags::SetFlagFromString(Flag* flag, const char* argument) {
193 ASSERT(!flag->IsUnrecognized());
194 switch (flag->type_) {
195 case Flag::kBoolean: {
196 if (strcmp(argument, "true") == 0) {
197 *flag->bool_ptr_ = true;
198 } else if (strcmp(argument, "false") == 0) {
199 *flag->bool_ptr_ = false;
200 } else {
201 return false;
202 }
203 break;
204 }
205 case Flag::kString: {
206 *flag->charp_ptr_ = argument == NULL ? NULL : strdup(argument);
207 break;
208 }
209 case Flag::kInteger: {
210 char* endptr = NULL;
211 int val = strtol(argument, &endptr, 10);
212 if (endptr != argument) {
213 *flag->int_ptr_ = val;
214 }
215 break;
216 }
217 case Flag::kFunc: {
218 if (strcmp(argument, "true") == 0) {
219 (flag->handler_)(true);
220 } else if (strcmp(argument, "false") == 0) {
221 (flag->handler_)(false);
222 } else {
223 return false;
224 }
225 break;
226 }
227 default: {
228 UNREACHABLE();
229 return false;
230 }
231 }
232 flag->changed_ = true;
233 return true;
234 }
235
236
174 void Flags::Parse(const char* option) { 237 void Flags::Parse(const char* option) {
175 // Find the beginning of the option argument, if it exists. 238 // Find the beginning of the option argument, if it exists.
176 const char* equals = option; 239 const char* equals = option;
177 while ((*equals != '\0') && (*equals != '=')) { 240 while ((*equals != '\0') && (*equals != '=')) {
178 equals++; 241 equals++;
179 } 242 }
180 243
181 const char* argument = NULL; 244 const char* argument = NULL;
182 245
183 // Determine if this is an option argument. 246 // Determine if this is an option argument.
(...skipping 29 matching lines...) Expand all
213 if (flag == NULL) { 276 if (flag == NULL) {
214 // Collect unrecognized flags. 277 // Collect unrecognized flags.
215 char* new_flag = new char[name_len + 1]; 278 char* new_flag = new char[name_len + 1];
216 strncpy(new_flag, option, name_len); 279 strncpy(new_flag, option, name_len);
217 new_flag[name_len] = '\0'; 280 new_flag[name_len] = '\0';
218 Flags::Register_bool(NULL, new_flag, true, NULL); 281 Flags::Register_bool(NULL, new_flag, true, NULL);
219 } else { 282 } else {
220 // Only set values for recognized flags, skip collected 283 // Only set values for recognized flags, skip collected
221 // unrecognized flags. 284 // unrecognized flags.
222 if (!flag->IsUnrecognized()) { 285 if (!flag->IsUnrecognized()) {
223 switch (flag->type_) { 286 if (!SetFlagFromString(flag, argument)) {
224 case Flag::kBoolean: { 287 OS::Print("Ignoring flag: %s is an invalid value for flag %s\n",
225 if (strcmp(argument, "true") == 0) { 288 argument, name);
226 *flag->bool_ptr_ = true;
227 } else if (strcmp(argument, "false") == 0) {
228 *flag->bool_ptr_ = false;
229 } else {
230 OS::Print("Ignoring flag: %s is a bool flag.\n", name);
231 }
232 break;
233 }
234 case Flag::kString: {
235 *flag->charp_ptr_ = argument == NULL ? NULL : strdup(argument);
236 break;
237 }
238 case Flag::kInteger: {
239 char* endptr = NULL;
240 int val = strtol(argument, &endptr, 10);
241 if (endptr != argument) {
242 *flag->int_ptr_ = val;
243 }
244 break;
245 }
246 case Flag::kFunc: {
247 if (strcmp(argument, "true") == 0) {
248 (flag->handler_)(true);
249 } else if (strcmp(argument, "false") == 0) {
250 (flag->handler_)(false);
251 } else {
252 OS::Print("Ignoring flag: %s is a bool flag.\n", name);
253 }
254 break;
255 }
256 default: {
257 UNREACHABLE();
258 break;
259 }
260 } 289 }
261 } 290 }
262 } 291 }
263 292
264 delete[] name; 293 delete[] name;
265 } 294 }
266 295
267 296
268 static bool IsValidFlag(const char* name, 297 static bool IsValidFlag(const char* name,
269 const char* prefix, 298 const char* prefix,
270 intptr_t prefix_length) { 299 intptr_t prefix_length) {
271 intptr_t name_length = strlen(name); 300 intptr_t name_length = strlen(name);
272 return ((name_length > prefix_length) && 301 return ((name_length > prefix_length) &&
273 (strncmp(name, prefix, prefix_length) == 0)); 302 (strncmp(name, prefix, prefix_length) == 0));
274 } 303 }
275 304
276 305
306 int Flags::CompareFlagNames(const void* left, const void* right) {
307 const Flag* left_flag = *reinterpret_cast<const Flag* const *>(left);
308 const Flag* right_flag = *reinterpret_cast<const Flag* const *>(right);
309 return strcmp(left_flag->name_, right_flag->name_);
310 }
311
312
277 bool Flags::ProcessCommandLineFlags(int number_of_vm_flags, 313 bool Flags::ProcessCommandLineFlags(int number_of_vm_flags,
278 const char** vm_flags) { 314 const char** vm_flags) {
279 if (initialized_) { 315 if (initialized_) {
280 return false; 316 return false;
281 } 317 }
282 318
283 initialized_ = true; 319 qsort(flags_, num_flags_, sizeof flags_[0], CompareFlagNames);
284 320
285 const char* kPrefix = "--"; 321 const char* kPrefix = "--";
286 const intptr_t kPrefixLen = strlen(kPrefix); 322 const intptr_t kPrefixLen = strlen(kPrefix);
287 323
288 int i = 0; 324 int i = 0;
289 while ((i < number_of_vm_flags) && 325 while ((i < number_of_vm_flags) &&
290 IsValidFlag(vm_flags[i], kPrefix, kPrefixLen)) { 326 IsValidFlag(vm_flags[i], kPrefix, kPrefixLen)) {
291 const char* option = vm_flags[i] + kPrefixLen; 327 const char* option = vm_flags[i] + kPrefixLen;
292 Parse(option); 328 Parse(option);
293 i++; 329 i++;
294 } 330 }
295 331
296 if (!FLAG_ignore_unrecognized_flags) { 332 if (!FLAG_ignore_unrecognized_flags) {
297 int unrecognized_count = 0; 333 int unrecognized_count = 0;
298 Flag* flag = Flags::flags_; 334 for (intptr_t j = 0; j < num_flags_; j++) {
299 while (flag != NULL) { 335 Flag* flag = flags_[j];
300 if (flag->IsUnrecognized()) { 336 if (flag->IsUnrecognized()) {
301 if (unrecognized_count == 0) { 337 if (unrecognized_count == 0) {
302 OS::PrintErr("Unrecognized flags: %s", flag->name_); 338 OS::PrintErr("Unrecognized flags: %s", flag->name_);
303 } else { 339 } else {
304 OS::PrintErr(", %s", flag->name_); 340 OS::PrintErr(", %s", flag->name_);
305 } 341 }
306 unrecognized_count++; 342 unrecognized_count++;
307 } 343 }
308 flag = flag->next_;
309 } 344 }
310 if (unrecognized_count > 0) { 345 if (unrecognized_count > 0) {
311 OS::PrintErr("\n"); 346 OS::PrintErr("\n");
312 exit(255); 347 exit(255);
313 } 348 }
314 } 349 }
315 if (FLAG_print_flags) { 350 if (FLAG_print_flags) {
316 PrintFlags(); 351 PrintFlags();
317 } 352 }
353
354 initialized_ = true;
355 return true;
356 }
357
358 bool Flags::SetFlag(const char* name,
359 const char* value,
360 const char** error) {
361 Flag* flag = Lookup(name);
362 if (flag == NULL) {
363 *error = "Cannot set flag: flag not found";
364 return false;
365 }
366 if (!SetFlagFromString(flag, value)) {
367 *error = "Cannot set flag: invalid value";
368 return false;
369 }
318 return true; 370 return true;
319 } 371 }
320 372
321 373
322 int Flags::CompareFlagNames(const void* left, const void* right) { 374 void Flags::PrintFlags() {
323 const Flag* left_flag = *reinterpret_cast<const Flag* const *>(left); 375 OS::Print("Flag settings:\n");
324 const Flag* right_flag = *reinterpret_cast<const Flag* const *>(right); 376 for (intptr_t i = 0; i < num_flags_; ++i) {
325 return strcmp(left_flag->name_, right_flag->name_); 377 flags_[i]->Print();
378 }
326 } 379 }
327 380
328 381
329 void Flags::PrintFlags() { 382 void Flags::PrintFlagToJSONArray(JSONArray* jsarr, const Flag* flag) {
330 OS::Print("Flag settings:\n"); 383 if (flag->IsUnrecognized() || flag->type_ == Flag::kFunc) {
331 Flag* flag = Flags::flags_; 384 return;
332 int num_flags = 0; 385 }
333 while (flag != NULL) { 386 JSONObject jsflag(jsarr);
334 num_flags++; 387 jsflag.AddProperty("name", flag->name_);
335 flag = flag->next_; 388 jsflag.AddProperty("comment", flag->comment_);
389 switch (flag->type_) {
390 case Flag::kBoolean: {
391 jsflag.AddProperty("flagType", "bool");
392 jsflag.AddProperty("valueAsString",
393 (*flag->bool_ptr_ ? "true" : "false"));
394 break;
336 } 395 }
337 Flag** flag_array = new Flag*[num_flags]; 396 case Flag::kInteger: {
338 flag = Flags::flags_; 397 jsflag.AddProperty("flagType", "int");
339 for (int i = 0; i < num_flags; ++i, flag = flag->next_) { 398 jsflag.AddPropertyF("valueAsString", "%d", *flag->int_ptr_);
340 flag_array[i] = flag; 399 break;
341 } 400 }
401 case Flag::kString: {
402 jsflag.AddProperty("flagType", "string");
403 if (flag->charp_ptr_ != NULL) {
404 jsflag.AddPropertyF("valueAsString", "%s", *flag->charp_ptr_);
405 } else {
406 // valueAsString missing means NULL.
407 }
408 break;
409 }
410 default:
411 UNREACHABLE();
412 break;
413 }
414 }
342 415
343 qsort(flag_array, num_flags, sizeof flag_array[0], CompareFlagNames);
344 416
345 for (int i = 0; i < num_flags; ++i) { 417 void Flags::PrintJSON(JSONStream* js) {
346 flag_array[i]->Print(); 418 JSONObject jsobj(js);
419 jsobj.AddProperty("type", "FlagList");
420 jsobj.AddProperty("id", "flags");
421
422 {
423 JSONArray jsarr(&jsobj, "unmodifiedFlags");
424 for (intptr_t i = 0; i < num_flags_; ++i) {
425 Flag* flag = flags_[i];
426 if (!flag->changed_) {
427 PrintFlagToJSONArray(&jsarr, flag);
428 }
347 } 429 }
348 delete[] flag_array;
349 } 430 }
431 {
432 JSONArray jsarr(&jsobj, "modifiedFlags");
433 for (intptr_t i = 0; i < num_flags_; ++i) {
434 Flag* flag = flags_[i];
435 if (flag->changed_) {
436 PrintFlagToJSONArray(&jsarr, flag);
437 }
438 }
439 }
440 }
441
350 } // namespace dart 442 } // 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