Mercurial > hg > graal-compiler
comparison src/share/vm/graal/graalEnv.cpp @ 19487:fb38e004503c
moved creation of String for detailed dependency failure message outside of no safepoint region
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 18 Feb 2015 21:55:31 +0100 |
parents | dd8989d5547f |
children | 29916dcee0b8 |
comparison
equal
deleted
inserted
replaced
19486:b53645225e48 | 19487:fb38e004503c |
---|---|
419 } | 419 } |
420 | 420 |
421 // ------------------------------------------------------------------ | 421 // ------------------------------------------------------------------ |
422 // Check for changes to the system dictionary during compilation | 422 // Check for changes to the system dictionary during compilation |
423 // class loads, evolution, breakpoints | 423 // class loads, evolution, breakpoints |
424 bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, GraalEnv* env, TRAPS) { | 424 bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, GraalEnv* env, char** failure_detail) { |
425 // If JVMTI capabilities were enabled during compile, the compilation is invalidated. | 425 // If JVMTI capabilities were enabled during compile, the compilation is invalidated. |
426 if (env != NULL) { | 426 if (env != NULL) { |
427 if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) { | 427 if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) { |
428 Handle message = java_lang_String::create_from_str("Hotswapping or breakpointing was enabled during compilation", THREAD); | 428 *failure_detail = (char*) "Hotswapping or breakpointing was enabled during compilation"; |
429 HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message()); | |
430 return false; | 429 return false; |
431 } | 430 } |
432 } | 431 } |
433 | 432 |
434 // Dependencies must be checked when the system dictionary changes | 433 // Dependencies must be checked when the system dictionary changes |
441 } | 440 } |
442 | 441 |
443 for (Dependencies::DepStream deps(dependencies); deps.next(); ) { | 442 for (Dependencies::DepStream deps(dependencies); deps.next(); ) { |
444 Klass* witness = deps.check_dependency(); | 443 Klass* witness = deps.check_dependency(); |
445 if (witness != NULL) { | 444 if (witness != NULL) { |
446 ResourceMark rm; | 445 // Use a fixed size buffer to prevent the string stream from |
447 stringStream st; | 446 // resizing in the context of an inner resource mark. |
447 char* buffer = NEW_RESOURCE_ARRAY(char, O_BUFLEN); | |
448 stringStream st(buffer, O_BUFLEN); | |
448 deps.print_dependency(witness, true, &st); | 449 deps.print_dependency(witness, true, &st); |
449 Handle message = java_lang_String::create_from_str(st.as_string(), THREAD); | 450 *failure_detail = st.as_string(); |
450 HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message()); | |
451 return false; | 451 return false; |
452 } | 452 } |
453 if (LogCompilation) { | 453 if (LogCompilation) { |
454 deps.log_dependency(); | 454 deps.log_dependency(); |
455 } | 455 } |
480 Handle speculation_log) { | 480 Handle speculation_log) { |
481 GRAAL_EXCEPTION_CONTEXT; | 481 GRAAL_EXCEPTION_CONTEXT; |
482 NMethodSweeper::possibly_sweep(); | 482 NMethodSweeper::possibly_sweep(); |
483 nm = NULL; | 483 nm = NULL; |
484 int comp_level = CompLevel_full_optimization; | 484 int comp_level = CompLevel_full_optimization; |
485 char* failure_detail = NULL; | |
486 GraalEnv::CodeInstallResult result; | |
485 { | 487 { |
486 // To prevent compile queue updates. | 488 // To prevent compile queue updates. |
487 MutexLocker locker(MethodCompileQueue_lock, THREAD); | 489 MutexLocker locker(MethodCompileQueue_lock, THREAD); |
488 | 490 |
489 // Prevent SystemDictionary::add_to_hierarchy from running | 491 // Prevent SystemDictionary::add_to_hierarchy from running |
492 | 494 |
493 // Encode the dependencies now, so we can check them right away. | 495 // Encode the dependencies now, so we can check them right away. |
494 dependencies->encode_content_bytes(); | 496 dependencies->encode_content_bytes(); |
495 | 497 |
496 // Check for {class loads, evolution, breakpoints} during compilation | 498 // Check for {class loads, evolution, breakpoints} during compilation |
497 if (!check_for_system_dictionary_modification(dependencies, compiled_code, env, THREAD)) { | 499 if (!check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail)) { |
498 // While not a true deoptimization, it is a preemptive decompile. | 500 // While not a true deoptimization, it is a preemptive decompile. |
499 MethodData* mdp = method()->method_data(); | 501 MethodData* mdp = method()->method_data(); |
500 if (mdp != NULL) { | 502 if (mdp != NULL) { |
501 mdp->inc_decompile_count(); | 503 mdp->inc_decompile_count(); |
502 if (mdp->decompile_count() > (uint)PerMethodRecompilationCutoff) { | 504 if (mdp->decompile_count() > (uint)PerMethodRecompilationCutoff) { |
509 | 511 |
510 // All buffers in the CodeBuffer are allocated in the CodeCache. | 512 // All buffers in the CodeBuffer are allocated in the CodeCache. |
511 // If the code buffer is created on each compile attempt | 513 // If the code buffer is created on each compile attempt |
512 // as in C2, then it must be freed. | 514 // as in C2, then it must be freed. |
513 //code_buffer->free_blob(); | 515 //code_buffer->free_blob(); |
514 return GraalEnv::dependencies_failed; | 516 result = GraalEnv::dependencies_failed; |
515 } | |
516 ImplicitExceptionTable implicit_tbl; | |
517 nm = nmethod::new_nmethod(method, | |
518 compile_id, | |
519 entry_bci, | |
520 offsets, | |
521 orig_pc_offset, | |
522 debug_info, dependencies, code_buffer, | |
523 frame_words, oop_map_set, | |
524 handler_table, &implicit_tbl, | |
525 compiler, comp_level, installed_code, speculation_log); | |
526 | |
527 // Free codeBlobs | |
528 //code_buffer->free_blob(); | |
529 | |
530 if (nm == NULL) { | |
531 // The CodeCache is full. Print out warning and disable compilation. | |
532 { | |
533 MutexUnlocker ml(Compile_lock); | |
534 MutexUnlocker locker(MethodCompileQueue_lock); | |
535 CompileBroker::handle_full_code_cache(); | |
536 } | |
537 } else { | 517 } else { |
538 nm->set_has_unsafe_access(has_unsafe_access); | 518 ImplicitExceptionTable implicit_tbl; |
539 | 519 nm = nmethod::new_nmethod(method, |
540 // Record successful registration. | 520 compile_id, |
541 // (Put nm into the task handle *before* publishing to the Java heap.) | 521 entry_bci, |
542 CompileTask* task = env == NULL ? NULL : env->task(); | 522 offsets, |
543 if (task != NULL) task->set_code(nm); | 523 orig_pc_offset, |
544 | 524 debug_info, dependencies, code_buffer, |
545 if (installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(installed_code())) { | 525 frame_words, oop_map_set, |
546 if (entry_bci == InvocationEntryBci) { | 526 handler_table, &implicit_tbl, |
547 if (TieredCompilation) { | 527 compiler, comp_level, installed_code, speculation_log); |
548 // If there is an old version we're done with it | 528 |
549 nmethod* old = method->code(); | 529 // Free codeBlobs |
550 if (TraceMethodReplacement && old != NULL) { | 530 //code_buffer->free_blob(); |
531 | |
532 if (nm == NULL) { | |
533 // The CodeCache is full. Print out warning and disable compilation. | |
534 { | |
535 MutexUnlocker ml(Compile_lock); | |
536 MutexUnlocker locker(MethodCompileQueue_lock); | |
537 CompileBroker::handle_full_code_cache(); | |
538 } | |
539 } else { | |
540 nm->set_has_unsafe_access(has_unsafe_access); | |
541 | |
542 // Record successful registration. | |
543 // (Put nm into the task handle *before* publishing to the Java heap.) | |
544 CompileTask* task = env == NULL ? NULL : env->task(); | |
545 if (task != NULL) task->set_code(nm); | |
546 | |
547 if (installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(installed_code())) { | |
548 if (entry_bci == InvocationEntryBci) { | |
549 if (TieredCompilation) { | |
550 // If there is an old version we're done with it | |
551 nmethod* old = method->code(); | |
552 if (TraceMethodReplacement && old != NULL) { | |
553 ResourceMark rm; | |
554 char *method_name = method->name_and_sig_as_C_string(); | |
555 tty->print_cr("Replacing method %s", method_name); | |
556 } | |
557 if (old != NULL ) { | |
558 old->make_not_entrant(); | |
559 } | |
560 } | |
561 if (TraceNMethodInstalls) { | |
551 ResourceMark rm; | 562 ResourceMark rm; |
552 char *method_name = method->name_and_sig_as_C_string(); | 563 char *method_name = method->name_and_sig_as_C_string(); |
553 tty->print_cr("Replacing method %s", method_name); | 564 ttyLocker ttyl; |
565 tty->print_cr("Installing method (%d) %s [entry point: %p]", | |
566 comp_level, | |
567 method_name, nm->entry_point()); | |
554 } | 568 } |
555 if (old != NULL ) { | 569 // Allow the code to be executed |
556 old->make_not_entrant(); | 570 method->set_code(method, nm); |
571 } else { | |
572 if (TraceNMethodInstalls ) { | |
573 ResourceMark rm; | |
574 char *method_name = method->name_and_sig_as_C_string(); | |
575 ttyLocker ttyl; | |
576 tty->print_cr("Installing osr method (%d) %s @ %d", | |
577 comp_level, | |
578 method_name, | |
579 entry_bci); | |
557 } | 580 } |
581 InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); | |
558 } | 582 } |
559 if (TraceNMethodInstalls) { | |
560 ResourceMark rm; | |
561 char *method_name = method->name_and_sig_as_C_string(); | |
562 ttyLocker ttyl; | |
563 tty->print_cr("Installing method (%d) %s [entry point: %p]", | |
564 comp_level, | |
565 method_name, nm->entry_point()); | |
566 } | |
567 // Allow the code to be executed | |
568 method->set_code(method, nm); | |
569 } else { | |
570 if (TraceNMethodInstalls ) { | |
571 ResourceMark rm; | |
572 char *method_name = method->name_and_sig_as_C_string(); | |
573 ttyLocker ttyl; | |
574 tty->print_cr("Installing osr method (%d) %s @ %d", | |
575 comp_level, | |
576 method_name, | |
577 entry_bci); | |
578 } | |
579 InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); | |
580 | |
581 } | 583 } |
582 } | 584 } |
583 } | 585 result = nm != NULL ? GraalEnv::ok :GraalEnv::cache_full; |
584 } | 586 } |
587 } | |
588 | |
589 // String creation must be done outside lock | |
590 if (failure_detail != NULL) { | |
591 // A failure to allocate the string is silently ignored. | |
592 Handle message = java_lang_String::create_from_str(failure_detail, THREAD); | |
593 HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message()); | |
594 } | |
595 | |
585 // JVMTI -- compiled method notification (must be done outside lock) | 596 // JVMTI -- compiled method notification (must be done outside lock) |
586 if (nm != NULL) { | 597 if (nm != NULL) { |
587 nm->post_compiled_method_load_event(); | 598 nm->post_compiled_method_load_event(); |
588 return GraalEnv::ok; | 599 } |
589 } | 600 |
590 | 601 return result; |
591 return GraalEnv::cache_full; | 602 } |
592 } | 603 |
593 |