< prev index next >

src/hotspot/share/code/compiledMethod.cpp

Print this page




   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 "code/compiledIC.hpp"
  27 #include "code/compiledMethod.inline.hpp"

  28 #include "code/scopeDesc.hpp"
  29 #include "code/codeCache.hpp"
  30 #include "code/icBuffer.hpp"
  31 #include "gc/shared/barrierSet.hpp"
  32 #include "gc/shared/gcBehaviours.hpp"
  33 #include "interpreter/bytecode.inline.hpp"
  34 #include "logging/log.hpp"
  35 #include "logging/logTag.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/methodData.hpp"
  38 #include "oops/method.inline.hpp"
  39 #include "prims/methodHandles.hpp"

  40 #include "runtime/handles.inline.hpp"
  41 #include "runtime/mutexLocker.hpp"

  42 
  43 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout,
  44                                int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps,
  45                                bool caller_must_gc_arguments)
  46   : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
  47     _mark_for_deoptimization_status(not_marked),
  48     _method(method),
  49     _gc_data(NULL)
  50 {
  51   init_defaults();
  52 }
  53 
  54 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size,
  55                                int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size,
  56                                OopMapSet* oop_maps, bool caller_must_gc_arguments)
  57   : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb,
  58              frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
  59     _mark_for_deoptimization_status(not_marked),
  60     _method(method),
  61     _gc_data(NULL)


 619       break;
 620     }
 621   }
 622 
 623   return true;
 624 }
 625 
 626 // Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found
 627 // to not be inherently safe. There is a chance that fields are seen which are not properly
 628 // initialized. This happens despite the fact that nmethods_do() asserts the CodeCache_lock
 629 // to be held.
 630 // To bundle knowledge about necessary checks in one place, this function was introduced.
 631 // It is not claimed that these checks are sufficient, but they were found to be necessary.
 632 bool CompiledMethod::nmethod_access_is_safe(nmethod* nm) {
 633   Method* method = (nm == NULL) ? NULL : nm->method();  // nm->method() may be uninitialized, i.e. != NULL, but invalid
 634   return (nm != NULL) && (method != NULL) && (method->signature() != NULL) &&
 635          !nm->is_zombie() && !nm->is_not_installed() &&
 636          os::is_readable_pointer(method) &&
 637          os::is_readable_pointer(method->constants()) &&
 638          os::is_readable_pointer(method->signature());








































 639 }
 640 
 641 class HasEvolDependency : public MetadataClosure {
 642   bool _has_evol_dependency;
 643  public:
 644   HasEvolDependency() : _has_evol_dependency(false) {}
 645   void do_metadata(Metadata* md) {
 646     if (md->is_method()) {
 647       Method* method = (Method*)md;
 648       if (method->is_old()) {
 649         _has_evol_dependency = true;
 650       }
 651     }
 652   }
 653   bool has_evol_dependency() const { return _has_evol_dependency; }
 654 };
 655 
 656 bool CompiledMethod::has_evol_metadata() {
 657   // Check the metadata in relocIter and CompiledIC and also deoptimize
 658   // any nmethod that has reference to old methods.


   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 "code/compiledIC.hpp"
  27 #include "code/compiledMethod.inline.hpp"
  28 #include "code/exceptionHandlerTable.hpp"
  29 #include "code/scopeDesc.hpp"
  30 #include "code/codeCache.hpp"
  31 #include "code/icBuffer.hpp"
  32 #include "gc/shared/barrierSet.hpp"
  33 #include "gc/shared/gcBehaviours.hpp"
  34 #include "interpreter/bytecode.inline.hpp"
  35 #include "logging/log.hpp"
  36 #include "logging/logTag.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "oops/methodData.hpp"
  39 #include "oops/method.inline.hpp"
  40 #include "prims/methodHandles.hpp"
  41 #include "runtime/deoptimization.hpp"
  42 #include "runtime/handles.inline.hpp"
  43 #include "runtime/mutexLocker.hpp"
  44 #include "runtime/sharedRuntime.hpp"
  45 
  46 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout,
  47                                int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps,
  48                                bool caller_must_gc_arguments)
  49   : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
  50     _mark_for_deoptimization_status(not_marked),
  51     _method(method),
  52     _gc_data(NULL)
  53 {
  54   init_defaults();
  55 }
  56 
  57 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size,
  58                                int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size,
  59                                OopMapSet* oop_maps, bool caller_must_gc_arguments)
  60   : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb,
  61              frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments),
  62     _mark_for_deoptimization_status(not_marked),
  63     _method(method),
  64     _gc_data(NULL)


 622       break;
 623     }
 624   }
 625 
 626   return true;
 627 }
 628 
 629 // Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found
 630 // to not be inherently safe. There is a chance that fields are seen which are not properly
 631 // initialized. This happens despite the fact that nmethods_do() asserts the CodeCache_lock
 632 // to be held.
 633 // To bundle knowledge about necessary checks in one place, this function was introduced.
 634 // It is not claimed that these checks are sufficient, but they were found to be necessary.
 635 bool CompiledMethod::nmethod_access_is_safe(nmethod* nm) {
 636   Method* method = (nm == NULL) ? NULL : nm->method();  // nm->method() may be uninitialized, i.e. != NULL, but invalid
 637   return (nm != NULL) && (method != NULL) && (method->signature() != NULL) &&
 638          !nm->is_zombie() && !nm->is_not_installed() &&
 639          os::is_readable_pointer(method) &&
 640          os::is_readable_pointer(method->constants()) &&
 641          os::is_readable_pointer(method->signature());
 642 }
 643 
 644 address CompiledMethod::continuation_for_implicit_exception(address pc, bool for_div0_check) {
 645   // Exception happened outside inline-cache check code => we are inside
 646   // an active nmethod => use cpc to determine a return address
 647   int exception_offset = pc - code_begin();
 648   int cont_offset = ImplicitExceptionTable(this).continuation_offset( exception_offset );
 649 #ifdef ASSERT
 650   if (cont_offset == 0) {
 651     Thread* thread = Thread::current();
 652     ResetNoHandleMark rnm; // Might be called from LEAF/QUICK ENTRY
 653     HandleMark hm(thread);
 654     ResourceMark rm(thread);
 655     CodeBlob* cb = CodeCache::find_blob(pc);
 656     assert(cb != NULL && cb == this, "");
 657     ttyLocker ttyl;
 658     tty->print_cr("implicit exception happened at " INTPTR_FORMAT, p2i(pc));
 659     print();
 660     method()->print_codes();
 661     print_code();
 662     print_pcs();
 663   }
 664 #endif
 665   if (cont_offset == 0) {
 666     // Let the normal error handling report the exception
 667     return NULL;
 668   }
 669   if (cont_offset == exception_offset) {
 670 #if INCLUDE_JVMCI
 671     Deoptimization::DeoptReason deopt_reason = for_div0_check ? Deoptimization::Reason_div0_check : Deoptimization::Reason_null_check;
 672     JavaThread *thread = JavaThread::current();
 673     thread->set_jvmci_implicit_exception_pc(pc);
 674     thread->set_pending_deoptimization(Deoptimization::make_trap_request(deopt_reason,
 675                                                                          Deoptimization::Action_reinterpret));
 676     return (SharedRuntime::deopt_blob()->implicit_exception_uncommon_trap());
 677 #else
 678     ShouldNotReachHere();
 679 #endif
 680   }
 681   return code_begin() + cont_offset;
 682 }
 683 
 684 class HasEvolDependency : public MetadataClosure {
 685   bool _has_evol_dependency;
 686  public:
 687   HasEvolDependency() : _has_evol_dependency(false) {}
 688   void do_metadata(Metadata* md) {
 689     if (md->is_method()) {
 690       Method* method = (Method*)md;
 691       if (method->is_old()) {
 692         _has_evol_dependency = true;
 693       }
 694     }
 695   }
 696   bool has_evol_dependency() const { return _has_evol_dependency; }
 697 };
 698 
 699 bool CompiledMethod::has_evol_metadata() {
 700   // Check the metadata in relocIter and CompiledIC and also deoptimize
 701   // any nmethod that has reference to old methods.
< prev index next >