src/share/vm/c1/c1_Runtime1.cpp

Print this page

        

*** 807,821 **** // that caller_method() == caller_code->method() int bci = vfst.bci(); Bytecodes::Code code = caller_method()->java_code_at(bci); - #ifndef PRODUCT // this is used by assertions in the access_field_patching_id BasicType patch_field_type = T_ILLEGAL; - #endif // PRODUCT bool deoptimize_for_volatile = false; int patch_field_offset = -1; KlassHandle init_klass(THREAD, NULL); // klass needed by load_klass_patching code KlassHandle load_klass(THREAD, NULL); // klass needed by load_klass_patching code Handle mirror(THREAD, NULL); // oop needed by load_mirror_patching code Handle appendix(THREAD, NULL); // oop needed by appendix_patching code --- 807,820 ---- // that caller_method() == caller_code->method() int bci = vfst.bci(); Bytecodes::Code code = caller_method()->java_code_at(bci); // this is used by assertions in the access_field_patching_id BasicType patch_field_type = T_ILLEGAL; bool deoptimize_for_volatile = false; + bool deoptimize_for_atomic = false; int patch_field_offset = -1; KlassHandle init_klass(THREAD, NULL); // klass needed by load_klass_patching code KlassHandle load_klass(THREAD, NULL); // klass needed by load_klass_patching code Handle mirror(THREAD, NULL); // oop needed by load_mirror_patching code Handle appendix(THREAD, NULL); // oop needed by appendix_patching code
*** 837,851 **** // deoptimized so that the code can be regenerated correctly. // This check is only needed for access_field_patching since this // is the path for patching field offsets. load_klass is only // used for patching references to oops which don't need special // handling in the volatile case. deoptimize_for_volatile = result.access_flags().is_volatile(); ! #ifndef PRODUCT patch_field_type = result.field_type(); ! #endif } else if (load_klass_or_mirror_patch_id) { Klass* k = NULL; switch (code) { case Bytecodes::_putstatic: case Bytecodes::_getstatic: --- 836,856 ---- // deoptimized so that the code can be regenerated correctly. // This check is only needed for access_field_patching since this // is the path for patching field offsets. load_klass is only // used for patching references to oops which don't need special // handling in the volatile case. + deoptimize_for_volatile = result.access_flags().is_volatile(); ! // If we are patching a field which should be atomic, then ! // the generated code is not correct either, force deoptimizing. ! // We need to only cover T_LONG and T_DOUBLE fields, as we can ! // break access atomicity only for them. ! patch_field_type = result.field_type(); ! deoptimize_for_atomic = (AlwaysAtomicAccesses && (patch_field_type == T_DOUBLE || patch_field_type == T_LONG)); ! } else if (load_klass_or_mirror_patch_id) { Klass* k = NULL; switch (code) { case Bytecodes::_putstatic: case Bytecodes::_getstatic:
*** 916,932 **** } } else { ShouldNotReachHere(); } ! if (deoptimize_for_volatile) { ! // At compile time we assumed the field wasn't volatile but after ! // loading it turns out it was volatile so we have to throw the // compiled code out and let it be regenerated. if (TracePatching) { tty->print_cr("Deoptimizing for patching volatile field reference"); } // It's possible the nmethod was invalidated in the last // safepoint, but if it's still alive then make it not_entrant. nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); if (nm != NULL) { nm->make_not_entrant(); --- 921,943 ---- } } else { ShouldNotReachHere(); } ! if (deoptimize_for_volatile || deoptimize_for_atomic) { ! // At compile time we assumed the field wasn't volatile/atomic but after ! // loading it turns out it was volatile/atomic so we have to throw the // compiled code out and let it be regenerated. if (TracePatching) { + if (deoptimize_for_volatile) { tty->print_cr("Deoptimizing for patching volatile field reference"); } + if (deoptimize_for_atomic) { + tty->print_cr("Deoptimizing for patching atomic field reference"); + } + } + // It's possible the nmethod was invalidated in the last // safepoint, but if it's still alive then make it not_entrant. nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); if (nm != NULL) { nm->make_not_entrant();