1 /* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "compiler/compileBroker.hpp" 27 #include "compiler/directivesParser.hpp" 28 #include "memory/allocation.inline.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "runtime/os.hpp" 31 #include <string.h> 32 33 void DirectivesParser::push_tmp(CompilerDirectives* dir) { 34 _tmp_depth++; 35 dir->set_next(_tmp_top); 36 _tmp_top = dir; 37 } 38 39 CompilerDirectives* DirectivesParser::pop_tmp() { 40 if (_tmp_top == NULL) { 41 return NULL; 42 } 43 CompilerDirectives* tmp = _tmp_top; 44 _tmp_top = _tmp_top->next(); 45 tmp->set_next(NULL); 46 _tmp_depth--; 47 return tmp; 48 } 49 50 void DirectivesParser::clean_tmp() { 51 CompilerDirectives* tmp = pop_tmp(); 52 while (tmp != NULL) { 53 delete tmp; 54 tmp = pop_tmp(); 55 } 56 assert(_tmp_depth == 0, "Consistency"); 57 } 58 59 int DirectivesParser::parse_string(const char* text, outputStream* st) { 60 DirectivesParser cd(text, st, false); 61 if (cd.valid()) { 62 return cd.install_directives(); 63 } else { 64 cd.clean_tmp(); 65 st->flush(); 66 st->print_cr("Parsing of compiler directives failed"); 67 return -1; 68 } 69 } 70 71 bool DirectivesParser::has_file() { 72 return CompilerDirectivesFile != NULL; 73 } 74 75 bool DirectivesParser::parse_from_flag() { 76 return parse_from_file(CompilerDirectivesFile, tty); 77 } 78 79 bool DirectivesParser::parse_from_file(const char* filename, outputStream* st) { 80 assert(filename != NULL, "Test before calling this"); 81 if (!parse_from_file_inner(filename, st)) { 82 st->print_cr("Could not load file: %s", filename); 83 return false; 84 } 85 return true; 86 } 87 88 bool DirectivesParser::parse_from_file_inner(const char* filename, outputStream* stream) { 89 struct stat st; 90 ResourceMark rm; 91 if (os::stat(filename, &st) == 0) { 92 // found file, open it 93 int file_handle = os::open(filename, 0, 0); 94 if (file_handle != -1) { 95 // read contents into resource array 96 char* buffer = NEW_RESOURCE_ARRAY(char, st.st_size+1); 97 size_t num_read = os::read(file_handle, (char*) buffer, st.st_size); 98 buffer[num_read] = '\0'; 99 // close file 100 os::close(file_handle); 101 return parse_string(buffer, stream) > 0; 102 } 103 } 104 return false; 105 } 106 107 int DirectivesParser::install_directives() { 108 // Check limit 109 if (!DirectivesStack::check_capacity(_tmp_depth, _st)) { 110 clean_tmp(); 111 return 0; 112 } 113 114 // Pop from internal temporary stack and push to compileBroker. 115 CompilerDirectives* tmp = pop_tmp(); 116 int i = 0; 117 while (tmp != NULL) { 118 i++; 119 DirectivesStack::push(tmp); 120 tmp = pop_tmp(); 121 } 122 if (i == 0) { 123 _st->print_cr("No directives in file"); 124 return 0; 125 } else { 126 _st->print_cr("%i compiler directives added", i); 127 if (CompilerDirectivesPrint) { 128 // Print entire directives stack after new has been pushed. 129 DirectivesStack::print(_st); 130 } 131 return i; 132 } 133 } 134 135 DirectivesParser::DirectivesParser(const char* text, outputStream* st, bool silent) 136 : JSON(text, silent, st), depth(0), current_directive(NULL), current_directiveset(NULL), _tmp_top(NULL), _tmp_depth(0) { 137 #ifndef PRODUCT 138 memset(stack, 0, MAX_DEPTH * sizeof(stack[0])); 139 #endif 140 parse(); 141 } 142 143 DirectivesParser::~DirectivesParser() { 144 assert(_tmp_top == NULL, "Consistency"); 145 assert(_tmp_depth == 0, "Consistency"); 146 } 147 148 const DirectivesParser::key DirectivesParser::keys[] = { 149 // name, keytype, allow_array, allowed_mask, set_function 150 { "c1", type_c1, 0, mask(type_directives), NULL, UnknownFlagType }, 151 { "c2", type_c2, 0, mask(type_directives), NULL, UnknownFlagType }, 152 { "match", type_match, 1, mask(type_directives), NULL, UnknownFlagType }, 153 { "inline", type_inline, 1, mask(type_directives) | mask(type_c1) | mask(type_c2), NULL, UnknownFlagType }, 154 155 // Global flags 156 #define common_flag_key(name, type, dvalue, compiler) \ 157 { #name, type_flag, 0, mask(type_directives) | mask(type_c1) | mask(type_c2), &DirectiveSet::set_##name, type##Flag}, 158 compilerdirectives_common_flags(common_flag_key) 159 compilerdirectives_c2_flags(common_flag_key) 160 compilerdirectives_c1_flags(common_flag_key) 161 #undef common_flag_key 162 }; 163 164 const DirectivesParser::key DirectivesParser::dir_array_key = { 165 "top level directives array", type_dir_array, 0, 1 // Lowest bit means allow at top level 166 }; 167 const DirectivesParser::key DirectivesParser::dir_key = { 168 "top level directive", type_directives, 0, mask(type_dir_array) | 1 // Lowest bit means allow at top level 169 }; 170 const DirectivesParser::key DirectivesParser::value_array_key = { 171 "value array", type_value_array, 0, UINT_MAX // Allow all, checked by allow_array on other keys, not by allowed_mask from this key 172 }; 173 174 const DirectivesParser::key* DirectivesParser::lookup_key(const char* str, size_t len) { 175 for (size_t i = 0; i < (sizeof(keys) / sizeof(keys[0])); i++) { 176 if (strncasecmp(keys[i].name, str, len) == 0) { 177 return &keys[i]; 178 } 179 } 180 return NULL; 181 } 182 183 uint DirectivesParser::mask(keytype kt) { 184 return 1 << (kt + 1); 185 } 186 187 bool DirectivesParser::push_key(const char* str, size_t len) { 188 bool result = true; 189 const key* k = lookup_key(str, len); 190 191 if (k == NULL) { 192 // os::strdup 193 char* s = NEW_C_HEAP_ARRAY(char, len + 1, mtCompiler); 194 strncpy(s, str, len); 195 s[len] = '\0'; 196 error(KEY_ERROR, "No such key: '%s'.", s); 197 FREE_C_HEAP_ARRAY(char, s); 198 return false; 199 } 200 201 return push_key(k); 202 } 203 204 bool DirectivesParser::push_key(const key* k) { 205 assert(k->allowedmask != 0, "not allowed anywhere?"); 206 207 // Exceeding the stack should not be possible with a valid compiler directive, 208 // and an invalid should abort before this happens 209 assert(depth < MAX_DEPTH, "exceeded stack depth"); 210 if (depth >= MAX_DEPTH) { 211 error(INTERNAL_ERROR, "Stack depth exceeded."); 212 return false; 213 } 214 215 assert(stack[depth] == NULL, "element not nulled, something is wrong"); 216 217 if (depth == 0 && !(k->allowedmask & 1)) { 218 error(KEY_ERROR, "Key '%s' not allowed at top level.", k->name); 219 return false; 220 } 221 222 if (depth > 0) { 223 const key* prev = stack[depth - 1]; 224 if (!(k->allowedmask & mask(prev->type))) { 225 error(KEY_ERROR, "Key '%s' not allowed after '%s' key.", k->name, prev->name); 226 return false; 227 } 228 } 229 230 stack[depth] = k; 231 depth++; 232 return true; 233 } 234 235 const DirectivesParser::key* DirectivesParser::current_key() { 236 assert(depth > 0, "getting key from empty stack"); 237 if (depth == 0) { 238 return NULL; 239 } 240 return stack[depth - 1]; 241 } 242 243 const DirectivesParser::key* DirectivesParser::pop_key() { 244 assert(depth > 0, "popping empty stack"); 245 if (depth == 0) { 246 error(INTERNAL_ERROR, "Popping empty stack."); 247 return NULL; 248 } 249 depth--; 250 251 const key* k = stack[depth]; 252 #ifndef PRODUCT 253 stack[depth] = NULL; 254 #endif 255 256 return k; 257 } 258 259 bool DirectivesParser::set_option_flag(JSON_TYPE t, JSON_VAL* v, const key* option_key, DirectiveSet* set) { 260 261 void (DirectiveSet::*test)(void *args); 262 test = option_key->set; 263 264 switch (t) { 265 case JSON_TRUE: 266 if (option_key->flag_type != boolFlag) { 267 error(VALUE_ERROR, "Cannot use bool value for an %s flag", flag_type_names[option_key->flag_type]); 268 return false; 269 } else { 270 bool val = true; 271 (set->*test)((void *)&val); 272 } 273 break; 274 275 case JSON_FALSE: 276 if (option_key->flag_type != boolFlag) { 277 error(VALUE_ERROR, "Cannot use bool value for an %s flag", flag_type_names[option_key->flag_type]); 278 return false; 279 } else { 280 bool val = false; 281 (set->*test)((void *)&val); 282 } 283 break; 284 285 case JSON_NUMBER_INT: 286 if (option_key->flag_type != intxFlag) { 287 if (option_key->flag_type == doubleFlag) { 288 double dval = (double)v->int_value; 289 (set->*test)((void *)&dval); 290 break; 291 } 292 error(VALUE_ERROR, "Cannot use int value for an %s flag", flag_type_names[option_key->flag_type]); 293 return false; 294 } else { 295 intx ival = v->int_value; 296 (set->*test)((void *)&ival); 297 } 298 break; 299 300 case JSON_NUMBER_FLOAT: 301 if (option_key->flag_type != doubleFlag) { 302 error(VALUE_ERROR, "Cannot use double value for an %s flag", flag_type_names[option_key->flag_type]); 303 return false; 304 } else { 305 double dval = v->double_value; 306 (set->*test)((void *)&dval); 307 } 308 break; 309 310 case JSON_STRING: 311 if (option_key->flag_type != ccstrFlag && option_key->flag_type != ccstrlistFlag) { 312 error(VALUE_ERROR, "Cannot use string value for a %s flag", flag_type_names[option_key->flag_type]); 313 return false; 314 } else { 315 char* s = NEW_C_HEAP_ARRAY(char, v->str.length+1, mtCompiler); 316 strncpy(s, v->str.start, v->str.length + 1); 317 s[v->str.length] = '\0'; 318 (set->*test)((void *)&s); 319 } 320 break; 321 322 default: 323 assert(0, "Should not reach here."); 324 } 325 return true; 326 } 327 328 bool DirectivesParser::set_option(JSON_TYPE t, JSON_VAL* v) { 329 330 const key* option_key = pop_key(); 331 const key* enclosing_key = current_key(); 332 333 if (option_key->type == value_array_key.type) { 334 // Multi value array, we are really setting the value 335 // for the key one step further up. 336 option_key = pop_key(); 337 enclosing_key = current_key(); 338 339 // Repush option_key and multi value marker, since 340 // we need to keep them until all multi values are set. 341 push_key(option_key); 342 push_key(&value_array_key); 343 } 344 345 switch (option_key->type) { 346 case type_flag: 347 { 348 if (current_directiveset == NULL) { 349 assert(depth == 2, "Must not have active directive set"); 350 351 if (!set_option_flag(t, v, option_key, current_directive->_c1_store)) { 352 return false; 353 } 354 if (!set_option_flag(t, v, option_key, current_directive->_c2_store)) { 355 return false; 356 } 357 } else { 358 assert(depth > 2, "Must have active current directive set"); 359 if (!set_option_flag(t, v, option_key, current_directiveset)) { 360 return false; 361 } 362 } 363 break; 364 } 365 366 case type_match: 367 if (t != JSON_STRING) { 368 error(VALUE_ERROR, "Key of type %s needs a value of type string", option_key->name); 369 return false; 370 } 371 if (enclosing_key->type != type_directives) { 372 error(SYNTAX_ERROR, "Match keyword can only exist inside a directive"); 373 return false; 374 } 375 { 376 char* s = NEW_C_HEAP_ARRAY(char, v->str.length + 1, mtCompiler); 377 strncpy(s, v->str.start, v->str.length); 378 s[v->str.length] = '\0'; 379 380 const char* error_msg = NULL; 381 if (!current_directive->add_match(s, error_msg)) { 382 assert (error_msg != NULL, "Must have valid error message"); 383 error(VALUE_ERROR, "Method pattern error: %s", error_msg); 384 } 385 FREE_C_HEAP_ARRAY(char, s); 386 } 387 break; 388 389 case type_inline: 390 if (t != JSON_STRING) { 391 error(VALUE_ERROR, "Key of type %s needs a value of type string", option_key->name); 392 return false; 393 } 394 { 395 //char* s = strndup(v->str.start, v->str.length); 396 char* s = NEW_C_HEAP_ARRAY(char, v->str.length + 1, mtCompiler); 397 strncpy(s, v->str.start, v->str.length); 398 s[v->str.length] = '\0'; 399 400 const char* error_msg = NULL; 401 if (current_directiveset == NULL) { 402 if (current_directive->_c1_store->parse_and_add_inline(s, error_msg)) { 403 if (!current_directive->_c2_store->parse_and_add_inline(s, error_msg)) { 404 assert (error_msg != NULL, "Must have valid error message"); 405 error(VALUE_ERROR, "Method pattern error: %s", error_msg); 406 } 407 } else { 408 assert (error_msg != NULL, "Must have valid error message"); 409 error(VALUE_ERROR, "Method pattern error: %s", error_msg); 410 } 411 } else { 412 if (!current_directiveset->parse_and_add_inline(s, error_msg)) { 413 assert (error_msg != NULL, "Must have valid error message"); 414 error(VALUE_ERROR, "Method pattern error: %s", error_msg); 415 } 416 } 417 FREE_C_HEAP_ARRAY(char, s); 418 } 419 break; 420 421 case type_c1: 422 current_directiveset = current_directive->_c1_store; 423 if (t != JSON_TRUE && t != JSON_FALSE) { 424 error(VALUE_ERROR, "Key of type %s needs a true or false value", option_key->name); 425 return false; 426 } 427 break; 428 429 case type_c2: 430 current_directiveset = current_directive->_c2_store; 431 if (t != JSON_TRUE && t != JSON_FALSE) { 432 error(VALUE_ERROR, "Key of type %s needs a true or false value", option_key->name); 433 return false; 434 } 435 break; 436 437 default: 438 break; 439 } 440 441 return true; 442 } 443 444 bool DirectivesParser::callback(JSON_TYPE t, JSON_VAL* v, uint rlimit) { 445 const key* k; 446 447 if (depth == 0) { 448 switch (t) { 449 case JSON_ARRAY_BEGIN: 450 return push_key(&dir_array_key); 451 452 case JSON_OBJECT_BEGIN: 453 // push synthetic dir_array 454 push_key(&dir_array_key); 455 assert(depth == 1, "Make sure the stack are aligned with the directives"); 456 break; 457 458 default: 459 error(SYNTAX_ERROR, "DirectivesParser can only start with an array containing directive objects, or one single directive."); 460 return false; 461 } 462 } 463 if (depth == 1) { 464 switch (t) { 465 case JSON_OBJECT_BEGIN: 466 // Parsing a new directive. 467 current_directive = new CompilerDirectives(); 468 return push_key(&dir_key); 469 470 case JSON_ARRAY_END: 471 k = pop_key(); 472 473 if (k->type != type_dir_array) { 474 error(SYNTAX_ERROR, "Expected end of directives array"); 475 return false; 476 } 477 return true; 478 479 default: 480 error(SYNTAX_ERROR, "DirectivesParser can only start with an array containing directive objects, or one single directive."); 481 return false; 482 } 483 } else { 484 switch (t) { 485 case JSON_OBJECT_BEGIN: 486 k = current_key(); 487 switch (k->type) { 488 case type_c1: 489 current_directiveset = current_directive->_c1_store; 490 return true; 491 case type_c2: 492 current_directiveset = current_directive->_c2_store; 493 return true; 494 495 case type_dir_array: 496 return push_key(&dir_key); 497 498 default: 499 error(SYNTAX_ERROR, "The key '%s' does not allow an object to follow.", k->name); 500 return false; 501 } 502 return false; 503 504 case JSON_OBJECT_END: 505 k = pop_key(); 506 switch (k->type) { 507 case type_c1: 508 case type_c2: 509 // This is how we now if options apply to a single or both directive sets 510 current_directiveset = NULL; 511 break; 512 513 case type_directives: 514 // Check, finish and push to stack! 515 if (current_directive->match() == NULL) { 516 error(INTERNAL_ERROR, "Directive missing required match."); 517 return false; 518 } 519 current_directive->finalize(_st); 520 push_tmp(current_directive); 521 current_directive = NULL; 522 break; 523 524 default: 525 error(INTERNAL_ERROR, "Object end with wrong key type on stack: %s.", k->name); 526 ShouldNotReachHere(); 527 return false; 528 } 529 return true; 530 531 case JSON_ARRAY_BEGIN: 532 k = current_key(); 533 if (!(k->allow_array_value)) { 534 if (k->type == type_dir_array) { 535 error(SYNTAX_ERROR, "Array not allowed inside top level array, expected directive object."); 536 } else { 537 error(VALUE_ERROR, "The key '%s' does not allow an array of values.", k->name); 538 } 539 return false; 540 } 541 return push_key(&value_array_key); 542 543 case JSON_ARRAY_END: 544 k = pop_key(); // Pop multi value marker 545 assert(k->type == value_array_key.type, "array end for level != 0 should terminate multi value"); 546 k = pop_key(); // Pop key for option that was set 547 return true; 548 549 case JSON_KEY: 550 return push_key(v->str.start, v->str.length); 551 552 case JSON_STRING: 553 case JSON_NUMBER_INT: 554 case JSON_NUMBER_FLOAT: 555 case JSON_TRUE: 556 case JSON_FALSE: 557 case JSON_NULL: 558 return set_option(t, v); 559 560 default: 561 error(INTERNAL_ERROR, "Unknown JSON type: %d.", t); 562 ShouldNotReachHere(); 563 return false; 564 } 565 } 566 } 567 568 #ifndef PRODUCT 569 void DirectivesParser::test(const char* text, bool should_pass) { 570 DirectivesParser cd(text, tty, !VerboseInternalVMTests); 571 if (should_pass) { 572 assert(cd.valid() == true, "failed on a valid DirectivesParser string"); 573 if (VerboseInternalVMTests) { 574 tty->print("-- DirectivesParser test passed as expected --\n"); 575 } 576 } else { 577 assert(cd.valid() == false, "succeeded on an invalid DirectivesParser string"); 578 if (VerboseInternalVMTests) { 579 tty->print("-- DirectivesParser test failed as expected --\n"); 580 } 581 } 582 cd.clean_tmp(); 583 } 584 585 void DirectivesParser::test() { 586 DirectivesParser::test("{}", false); 587 DirectivesParser::test("[]", true); 588 DirectivesParser::test("[{}]", false); 589 DirectivesParser::test("[{},{}]", false); 590 DirectivesParser::test("{},{}", false); 591 592 DirectivesParser::test( 593 "[" "\n" 594 " {" "\n" 595 " match: \"foo/bar.*\"," "\n" 596 " inline : \"+java/util.*\"," "\n" 597 " PrintAssembly: true," "\n" 598 " BreakAtExecute: true," "\n" 599 " }" "\n" 600 "]" "\n", true); 601 602 DirectivesParser::test( 603 "[" "\n" 604 " [" "\n" 605 " {" "\n" 606 " match: \"foo/bar.*\"," "\n" 607 " inline : \"+java/util.*\"," "\n" 608 " PrintAssembly: true," "\n" 609 " BreakAtExecute: true," "\n" 610 " }" "\n" 611 " ]" "\n" 612 "]" "\n", false); 613 614 /*DirectivesParser::test( 615 "[" "\n" 616 " {" "\n" 617 " match: \"foo/bar.*\"," "\n" 618 " c1: {" 619 " PrintIntrinsics: false," "\n" 620 " }" "\n" 621 " }" "\n" 622 "]" "\n", false);*/ 623 624 DirectivesParser::test( 625 "[" "\n" 626 " {" "\n" 627 " match: \"foo/bar.*\"," "\n" 628 " c2: {" "\n" 629 " PrintInlining: false," "\n" 630 " }" "\n" 631 " }" "\n" 632 "]" "\n", true); 633 634 DirectivesParser::test( 635 "[" "\n" 636 " {" "\n" 637 " match: \"foo/bar.*\"," "\n" 638 " PrintInlining: [" "\n" 639 " true," "\n" 640 " false" "\n" 641 " ]," "\n" 642 " }" "\n" 643 "]" "\n", false); 644 645 DirectivesParser::test( 646 "[" "\n" 647 " {" 648 " // pattern to match against class+method+signature" "\n" 649 " // leading and trailing wildcard (*) allowed" "\n" 650 " match: \"foo/bar.*\"," "\n" 651 "" "\n" 652 " // override defaults for specified compiler" "\n" 653 " // we may differentiate between levels too. TBD." "\n" 654 " c1: {" "\n" 655 " //override c1 presets " "\n" 656 " DumpReplay: false," "\n" 657 " BreakAtCompile: true," "\n" 658 " }," "\n" 659 "" "\n" 660 " c2: {" "\n" 661 " // control inlining of method" "\n" 662 " // + force inline, - dont inline" "\n" 663 " inline : \"+java/util.*\"," "\n" 664 " PrintInlining: true," "\n" 665 " }," "\n" 666 "" "\n" 667 " // directives outside a specific preset applies to all compilers" "\n" 668 " inline : [ \"+java/util.*\", \"-com/sun.*\"]," "\n" 669 " BreakAtExecute: true," "\n" 670 " Log: true," "\n" 671 " }," "\n" 672 " {" "\n" 673 " // matching several patterns require an array" "\n" 674 " match: [\"baz.*\",\"frob.*\"]," "\n" 675 "" "\n" 676 " // applies to all compilers" "\n" 677 " // + force inline, - dont inline" "\n" 678 " inline : [ \"+java/util.*\", \"-com/sun.*\" ]," "\n" 679 " PrintInlining: true," "\n" 680 "" "\n" 681 " // force matching compiles to be blocking/syncronous" "\n" 682 " PrintNMethods: true" "\n" 683 " }," "\n" 684 "]" "\n", true); 685 686 // Test max stack depth 687 DirectivesParser::test( 688 "[" "\n" // depth 1: type_dir_array 689 " {" "\n" // depth 2: type_directives 690 " match: \"*.*\"," // match required 691 " c1:" "\n" // depth 3: type_c1 692 " {" "\n" 693 " inline:" "\n" // depth 4: type_inline 694 " [" "\n" // depth 5: type_value_array 695 " \"foo\"," "\n" 696 " \"bar\"," "\n" 697 " ]" "\n" // depth 3: pop type_value_array and type_inline keys 698 " }" "\n" // depth 2: pop type_c1 key 699 " }" "\n" // depth 1: pop type_directives key 700 "]" "\n", true); // depth 0: pop type_dir_array key 701 702 // Test max stack depth 703 DirectivesParser::test( 704 "[{c1:{c1:{c1:{c1:{c1:{c1:{c1:{}}}}}}}}]", false); 705 706 } 707 708 void DirectivesParser_test() { 709 DirectivesParser::test(); 710 } 711 712 #endif