8199406: Performance drop with Java JDK 1.8.0_162-b32 jdk8u162-b38

Fri, 30 Mar 2018 20:09:45 +0000

author
poonam
date
Fri, 30 Mar 2018 20:09:45 +0000
changeset 9391
405800ccc4c7
parent 9384
444777020b0b
child 9392
e863aba6538b

8199406: Performance drop with Java JDK 1.8.0_162-b32
Summary: Improve the nmethod unloading times by optimizing the search for an itable stub in VtableStubs array
Reviewed-by: kvn, coleenp, tschatzl

src/share/vm/code/codeBlob.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/codeBlob.hpp file | annotate | diff | comparison | revisions
src/share/vm/code/compiledIC.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/vtableStubs.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/vtableStubs.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/compiledICHolder.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/compiledICHolder.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/code/codeBlob.cpp	Wed Mar 21 12:05:05 2018 -0700
     1.2 +++ b/src/share/vm/code/codeBlob.cpp	Fri Mar 30 20:09:45 2018 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -289,6 +289,28 @@
    1.11    return blob;
    1.12  }
    1.13  
    1.14 +VtableBlob::VtableBlob(const char* name, int size) :
    1.15 +  BufferBlob(name, size) {
    1.16 +}
    1.17 +
    1.18 +VtableBlob* VtableBlob::create(const char* name, int buffer_size) {
    1.19 +  ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
    1.20 +
    1.21 +  VtableBlob* blob = NULL;
    1.22 +  unsigned int size = sizeof(VtableBlob);
    1.23 +  // align the size to CodeEntryAlignment
    1.24 +  size = align_code_offset(size);
    1.25 +  size += round_to(buffer_size, oopSize);
    1.26 +  assert(name != NULL, "must provide a name");
    1.27 +  {
    1.28 +    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    1.29 +    blob = new (size) VtableBlob(name, size);
    1.30 +  }
    1.31 +  // Track memory usage statistic after releasing CodeCache_lock
    1.32 +  MemoryService::track_code_cache_memory_usage();
    1.33 +
    1.34 +  return blob;
    1.35 +}
    1.36  
    1.37  //----------------------------------------------------------------------------------------------------
    1.38  // Implementation of MethodHandlesAdapterBlob
     2.1 --- a/src/share/vm/code/codeBlob.hpp	Wed Mar 21 12:05:05 2018 -0700
     2.2 +++ b/src/share/vm/code/codeBlob.hpp	Fri Mar 30 20:09:45 2018 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -101,6 +101,7 @@
    2.11    virtual bool is_exception_stub() const         { return false; }
    2.12    virtual bool is_safepoint_stub() const              { return false; }
    2.13    virtual bool is_adapter_blob() const                { return false; }
    2.14 +  virtual bool is_vtable_blob() const                 { return false; }
    2.15    virtual bool is_method_handles_adapter_blob() const { return false; }
    2.16  
    2.17    virtual bool is_compiled_by_c2() const         { return false; }
    2.18 @@ -202,6 +203,7 @@
    2.19  class BufferBlob: public CodeBlob {
    2.20    friend class VMStructs;
    2.21    friend class AdapterBlob;
    2.22 +  friend class VtableBlob;
    2.23    friend class MethodHandlesAdapterBlob;
    2.24  
    2.25   private:
    2.26 @@ -246,6 +248,18 @@
    2.27    virtual bool is_adapter_blob() const { return true; }
    2.28  };
    2.29  
    2.30 +//---------------------------------------------------------------------------------------------------
    2.31 +class VtableBlob: public BufferBlob {
    2.32 +private:
    2.33 +  VtableBlob(const char*, int);
    2.34 +
    2.35 +public:
    2.36 +  // Creation
    2.37 +  static VtableBlob* create(const char* name, int buffer_size);
    2.38 +
    2.39 +  // Typing
    2.40 +  virtual bool is_vtable_blob() const { return true; }
    2.41 +};
    2.42  
    2.43  //----------------------------------------------------------------------------------------------------
    2.44  // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
     3.1 --- a/src/share/vm/code/compiledIC.cpp	Wed Mar 21 12:05:05 2018 -0700
     3.2 +++ b/src/share/vm/code/compiledIC.cpp	Fri Mar 30 20:09:45 2018 +0000
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -232,7 +232,7 @@
    3.11      assert(k->verify_itable_index(itable_index), "sanity check");
    3.12  #endif //ASSERT
    3.13      CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
    3.14 -                                                    call_info->resolved_klass()());
    3.15 +                                                    call_info->resolved_klass()(), false);
    3.16      holder->claim();
    3.17      InlineCacheBuffer::create_transition_stub(this, holder, entry);
    3.18    } else {
    3.19 @@ -270,7 +270,7 @@
    3.20    assert(!is_optimized(), "an optimized call cannot be megamorphic");
    3.21  
    3.22    // Cannot rely on cached_value. It is either an interface or a method.
    3.23 -  return VtableStubs::is_entry_point(ic_destination());
    3.24 +  return VtableStubs::entry_point(ic_destination()) != NULL;
    3.25  }
    3.26  
    3.27  bool CompiledIC::is_call_to_compiled() const {
    3.28 @@ -534,9 +534,11 @@
    3.29      return true;
    3.30    }
    3.31    // itable stubs also use CompiledICHolder
    3.32 -  if (VtableStubs::is_entry_point(entry) && VtableStubs::stub_containing(entry)->is_itable_stub()) {
    3.33 -    return true;
    3.34 +  if (cb != NULL && cb->is_vtable_blob()) {
    3.35 +    VtableStub* s = VtableStubs::entry_point(entry);
    3.36 +    return (s != NULL) && s->is_itable_stub();
    3.37    }
    3.38 +
    3.39    return false;
    3.40  }
    3.41  
     4.1 --- a/src/share/vm/code/vtableStubs.cpp	Wed Mar 21 12:05:05 2018 -0700
     4.2 +++ b/src/share/vm/code/vtableStubs.cpp	Fri Mar 30 20:09:45 2018 +0000
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -60,7 +60,7 @@
    4.11  
    4.12     // There is a dependency on the name of the blob in src/share/vm/prims/jvmtiCodeBlobEvents.cpp
    4.13     // If changing the name, update the other file accordingly.
    4.14 -    BufferBlob* blob = BufferBlob::create("vtable chunks", bytes);
    4.15 +    VtableBlob* blob = VtableBlob::create("vtable chunks", bytes);
    4.16      if (blob == NULL) {
    4.17        return NULL;
    4.18      }
    4.19 @@ -167,17 +167,18 @@
    4.20    _number_of_vtable_stubs++;
    4.21  }
    4.22  
    4.23 -
    4.24 -bool VtableStubs::is_entry_point(address pc) {
    4.25 +VtableStub* VtableStubs::entry_point(address pc) {
    4.26    MutexLocker ml(VtableStubs_lock);
    4.27    VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset());
    4.28    uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index());
    4.29    VtableStub* s;
    4.30    for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {}
    4.31 -  return s == stub;
    4.32 +  if (s == stub) {
    4.33 +    return s;
    4.34 +  }
    4.35 +  return NULL;
    4.36  }
    4.37  
    4.38 -
    4.39  bool VtableStubs::contains(address pc) {
    4.40    // simple solution for now - we may want to use
    4.41    // a faster way if this function is called often
     5.1 --- a/src/share/vm/code/vtableStubs.hpp	Wed Mar 21 12:05:05 2018 -0700
     5.2 +++ b/src/share/vm/code/vtableStubs.hpp	Fri Mar 30 20:09:45 2018 +0000
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -126,7 +126,7 @@
    5.11   public:
    5.12    static address     find_vtable_stub(int vtable_index) { return find_stub(true,  vtable_index); }
    5.13    static address     find_itable_stub(int itable_index) { return find_stub(false, itable_index); }
    5.14 -  static bool        is_entry_point(address pc);                     // is pc a vtable stub entry point?
    5.15 +  static VtableStub* entry_point(address pc);                        // vtable stub entry point for a pc
    5.16    static bool        contains(address pc);                           // is pc within any stub?
    5.17    static VtableStub* stub_containing(address pc);                    // stub containing pc or NULL
    5.18    static int         number_of_vtable_stubs() { return _number_of_vtable_stubs; }
     6.1 --- a/src/share/vm/oops/compiledICHolder.cpp	Wed Mar 21 12:05:05 2018 -0700
     6.2 +++ b/src/share/vm/oops/compiledICHolder.cpp	Fri Mar 30 20:09:45 2018 +0000
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -24,30 +24,12 @@
    6.11  
    6.12  #include "precompiled.hpp"
    6.13  #include "oops/compiledICHolder.hpp"
    6.14 -#include "oops/klass.hpp"
    6.15 -#include "oops/method.hpp"
    6.16  #include "oops/oop.inline2.hpp"
    6.17  
    6.18  volatile int CompiledICHolder::_live_count;
    6.19  volatile int CompiledICHolder::_live_not_claimed_count;
    6.20  
    6.21  
    6.22 -bool CompiledICHolder::is_loader_alive(BoolObjectClosure* is_alive) {
    6.23 -  if (_holder_metadata->is_method()) {
    6.24 -    if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) {
    6.25 -      return false;
    6.26 -    }
    6.27 -  } else if (_holder_metadata->is_klass()) {
    6.28 -    if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) {
    6.29 -      return false;
    6.30 -    }
    6.31 -  }
    6.32 -  if (!_holder_klass->is_loader_alive(is_alive)) {
    6.33 -    return false;
    6.34 -  }
    6.35 -  return true;
    6.36 -}
    6.37 -
    6.38  // Printing
    6.39  
    6.40  void CompiledICHolder::print_on(outputStream* st) const {
     7.1 --- a/src/share/vm/oops/compiledICHolder.hpp	Wed Mar 21 12:05:05 2018 -0700
     7.2 +++ b/src/share/vm/oops/compiledICHolder.hpp	Fri Mar 30 20:09:45 2018 +0000
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -26,6 +26,8 @@
    7.11  #define SHARE_VM_OOPS_COMPILEDICHOLDEROOP_HPP
    7.12  
    7.13  #include "oops/oop.hpp"
    7.14 +#include "oops/klass.hpp"
    7.15 +#include "oops/method.hpp"
    7.16  
    7.17  // A CompiledICHolder* is a helper object for the inline cache implementation.
    7.18  // It holds:
    7.19 @@ -48,11 +50,12 @@
    7.20    Metadata* _holder_metadata;
    7.21    Klass*    _holder_klass;    // to avoid name conflict with oopDesc::_klass
    7.22    CompiledICHolder* _next;
    7.23 +  bool _is_metadata_method;
    7.24  
    7.25   public:
    7.26    // Constructor
    7.27 -  CompiledICHolder(Metadata* metadata, Klass* klass)
    7.28 -      : _holder_metadata(metadata), _holder_klass(klass) {
    7.29 +  CompiledICHolder(Metadata* metadata, Klass* klass, bool is_method = true)
    7.30 +      : _holder_metadata(metadata), _holder_klass(klass), _is_metadata_method(is_method) {
    7.31  #ifdef ASSERT
    7.32      Atomic::inc(&_live_count);
    7.33      Atomic::inc(&_live_not_claimed_count);
    7.34 @@ -82,7 +85,16 @@
    7.35    CompiledICHolder* next()     { return _next; }
    7.36    void set_next(CompiledICHolder* n) { _next = n; }
    7.37  
    7.38 -  bool is_loader_alive(BoolObjectClosure* is_alive);
    7.39 +  inline bool is_loader_alive(BoolObjectClosure* is_alive) {
    7.40 +    Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata;
    7.41 +    if (!k->is_loader_alive(is_alive)) {
    7.42 +      return false;
    7.43 +    }
    7.44 +    if (!_holder_klass->is_loader_alive(is_alive)) {
    7.45 +      return false;
    7.46 +    }
    7.47 +    return true;
    7.48 +  }
    7.49  
    7.50    // Verify
    7.51    void verify_on(outputStream* st);

mercurial