diff --git a/.hgtags b/.hgtags index e90cd1bccdadc98ed0402417802a0afe99bff25b..11162d27fa806969cdf1cba623b9f725a61adde6 100644 --- a/.hgtags +++ b/.hgtags @@ -1140,6 +1140,7 @@ d2ebd6530396b0afc700cd1a8eaf1f7a7f9fce8d jdk8u162-b36 a17bab9405474602b18cd62e060a09b17d6413ac jdk8u171-b00 ebfd57cc21e6b7f0c22b17c666b6b28c9340e207 jdk8u171-b01 1acd7c1b80241def8fac90f70b0df16356adad47 jdk8u171-b02 +5587cde50bbc2aa031aefb47eaa36b041f5e7c4b jdk8u181-b00 5587cde50bbc2aa031aefb47eaa36b041f5e7c4b jdk8u171-b03 99ef466523302cfbd00496cf6575a00c8637b884 jdk8u171-b04 08326a76b14888908523cf2bb1105de63b43544d jdk8u171-b05 @@ -1163,3 +1164,6 @@ a311a45523b19d59f77e76b0441a2085bb5355c8 jdk8u172-b07 aafd1bb21e2636ba982d3eae162f5c635a1df03a jdk8u172-b09 dcd3ace969fcde4eedaddba629647656289d4264 jdk8u172-b10 083a9d6562100353708e4b73656282b21a78f714 jdk8u172-b11 +6e2be123a2e1c7671086c767e79ffe8ad5d4f9ca jdk8u181-b01 +1d0b6fcff115a57ca02081da84589630ba282789 jdk8u181-b02 +1127faef22f14d56cdd6c0c8bded598f492c2611 jdk8u181-b03 diff --git a/src/os/linux/vm/os_linux.hpp b/src/os/linux/vm/os_linux.hpp index c56983cdd1a5bcf632b28edc92016dc942b7a577..d382c9840e09411f09e741754ad1c1e7a9384d13 100644 --- a/src/os/linux/vm/os_linux.hpp +++ b/src/os/linux/vm/os_linux.hpp @@ -285,8 +285,8 @@ private: static void set_numa_bitmask_isbitset(numa_bitmask_isbitset_func_t func) { _numa_bitmask_isbitset = func; } static void set_numa_distance(numa_distance_func_t func) { _numa_distance = func; } static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } - static void set_numa_all_nodes_ptr(struct bitmask **ptr) { _numa_all_nodes_ptr = *ptr; } - static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = *ptr; } + static void set_numa_all_nodes_ptr(struct bitmask **ptr) { _numa_all_nodes_ptr = (ptr == NULL ? NULL : *ptr); } + static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = (ptr == NULL ? NULL : *ptr); } static int sched_getcpu_syscall(void); public: static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } @@ -330,6 +330,18 @@ public: static bool isnode_in_existing_nodes(unsigned int n) { if (_numa_bitmask_isbitset != NULL && _numa_nodes_ptr != NULL) { return _numa_bitmask_isbitset(_numa_nodes_ptr, n); + } else if (_numa_bitmask_isbitset != NULL && _numa_all_nodes_ptr != NULL) { + // Not all libnuma API v2 implement numa_nodes_ptr, so it's not possible + // to trust the API version for checking its absence. On the other hand, + // numa_nodes_ptr found in libnuma 2.0.9 and above is the only way to get + // a complete view of all numa nodes in the system, hence numa_nodes_ptr + // is used to handle CPU and nodes on architectures (like PowerPC) where + // there can exist nodes with CPUs but no memory or vice-versa and the + // nodes may be non-contiguous. For most of the architectures, like + // x86_64, numa_node_ptr presents the same node set as found in + // numa_all_nodes_ptr so it's possible to use numa_all_nodes_ptr as a + // substitute. + return _numa_bitmask_isbitset(_numa_all_nodes_ptr, n); } else return 0; } diff --git a/src/share/vm/code/codeBlob.cpp b/src/share/vm/code/codeBlob.cpp index ee0d17de2ca1524617845b5f4a73b495d1ff2cb8..87ae60f81ec44ff834d272332e07b358d1d91292 100644 --- a/src/share/vm/code/codeBlob.cpp +++ b/src/share/vm/code/codeBlob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -289,6 +289,28 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { return blob; } +VtableBlob::VtableBlob(const char* name, int size) : + BufferBlob(name, size) { +} + +VtableBlob* VtableBlob::create(const char* name, int buffer_size) { + ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock + + VtableBlob* blob = NULL; + unsigned int size = sizeof(VtableBlob); + // align the size to CodeEntryAlignment + size = align_code_offset(size); + size += round_to(buffer_size, oopSize); + assert(name != NULL, "must provide a name"); + { + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + blob = new (size) VtableBlob(name, size); + } + // Track memory usage statistic after releasing CodeCache_lock + MemoryService::track_code_cache_memory_usage(); + + return blob; +} //---------------------------------------------------------------------------------------------------- // Implementation of MethodHandlesAdapterBlob diff --git a/src/share/vm/code/codeBlob.hpp b/src/share/vm/code/codeBlob.hpp index db270f135cec5e77e8af2f5a2e1c9b5fe8fcb55d..4f83fac6a2601cc66d75104d2b5bafe01e7c4df1 100644 --- a/src/share/vm/code/codeBlob.hpp +++ b/src/share/vm/code/codeBlob.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,6 +101,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { virtual bool is_exception_stub() const { return false; } virtual bool is_safepoint_stub() const { return false; } virtual bool is_adapter_blob() const { return false; } + virtual bool is_vtable_blob() const { return false; } virtual bool is_method_handles_adapter_blob() const { return false; } virtual bool is_compiled_by_c2() const { return false; } @@ -202,6 +203,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { class BufferBlob: public CodeBlob { friend class VMStructs; friend class AdapterBlob; + friend class VtableBlob; friend class MethodHandlesAdapterBlob; private: @@ -246,6 +248,18 @@ public: virtual bool is_adapter_blob() const { return true; } }; +//--------------------------------------------------------------------------------------------------- +class VtableBlob: public BufferBlob { +private: + VtableBlob(const char*, int); + +public: + // Creation + static VtableBlob* create(const char* name, int buffer_size); + + // Typing + virtual bool is_vtable_blob() const { return true; } +}; //---------------------------------------------------------------------------------------------------- // MethodHandlesAdapterBlob: used to hold MethodHandles adapters diff --git a/src/share/vm/code/compiledIC.cpp b/src/share/vm/code/compiledIC.cpp index 783fe9dd467bd166b1afcf546be3692db7bda1e0..63821c0613067bb0f04c20c53b5753439ab985b3 100644 --- a/src/share/vm/code/compiledIC.cpp +++ b/src/share/vm/code/compiledIC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -232,7 +232,7 @@ bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecod assert(k->verify_itable_index(itable_index), "sanity check"); #endif //ASSERT CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(), - call_info->resolved_klass()()); + call_info->resolved_klass()(), false); holder->claim(); InlineCacheBuffer::create_transition_stub(this, holder, entry); } else { @@ -270,7 +270,7 @@ bool CompiledIC::is_megamorphic() const { assert(!is_optimized(), "an optimized call cannot be megamorphic"); // Cannot rely on cached_value. It is either an interface or a method. - return VtableStubs::is_entry_point(ic_destination()); + return VtableStubs::entry_point(ic_destination()) != NULL; } bool CompiledIC::is_call_to_compiled() const { @@ -534,9 +534,11 @@ bool CompiledIC::is_icholder_entry(address entry) { return true; } // itable stubs also use CompiledICHolder - if (VtableStubs::is_entry_point(entry) && VtableStubs::stub_containing(entry)->is_itable_stub()) { - return true; + if (cb != NULL && cb->is_vtable_blob()) { + VtableStub* s = VtableStubs::entry_point(entry); + return (s != NULL) && s->is_itable_stub(); } + return false; } diff --git a/src/share/vm/code/vtableStubs.cpp b/src/share/vm/code/vtableStubs.cpp index ac99da40e1cff85316369a816ceeec50dd04efc9..8424378d7eea416e5191aee5fdf7c4787335c3bf 100644 --- a/src/share/vm/code/vtableStubs.cpp +++ b/src/share/vm/code/vtableStubs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ void* VtableStub::operator new(size_t size, int code_size) throw() { // There is a dependency on the name of the blob in src/share/vm/prims/jvmtiCodeBlobEvents.cpp // If changing the name, update the other file accordingly. - BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); + VtableBlob* blob = VtableBlob::create("vtable chunks", bytes); if (blob == NULL) { return NULL; } @@ -167,17 +167,18 @@ void VtableStubs::enter(bool is_vtable_stub, int vtable_index, VtableStub* s) { _number_of_vtable_stubs++; } - -bool VtableStubs::is_entry_point(address pc) { +VtableStub* VtableStubs::entry_point(address pc) { MutexLocker ml(VtableStubs_lock); VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index()); VtableStub* s; for (s = _table[hash]; s != NULL && s != stub; s = s->next()) {} - return s == stub; + if (s == stub) { + return s; + } + return NULL; } - bool VtableStubs::contains(address pc) { // simple solution for now - we may want to use // a faster way if this function is called often diff --git a/src/share/vm/code/vtableStubs.hpp b/src/share/vm/code/vtableStubs.hpp index b3d4f2d838ef0c0a239e4effd12f284e0d6fedc4..04f3e7e3cdebf88d0b406e0badcc44ea13220101 100644 --- a/src/share/vm/code/vtableStubs.hpp +++ b/src/share/vm/code/vtableStubs.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -126,7 +126,7 @@ class VtableStubs : AllStatic { public: static address find_vtable_stub(int vtable_index) { return find_stub(true, vtable_index); } static address find_itable_stub(int itable_index) { return find_stub(false, itable_index); } - static bool is_entry_point(address pc); // is pc a vtable stub entry point? + static VtableStub* entry_point(address pc); // vtable stub entry point for a pc static bool contains(address pc); // is pc within any stub? static VtableStub* stub_containing(address pc); // stub containing pc or NULL static int number_of_vtable_stubs() { return _number_of_vtable_stubs; } diff --git a/src/share/vm/oops/compiledICHolder.cpp b/src/share/vm/oops/compiledICHolder.cpp index f5af2d4139e8be7b8f91bb2f3b97c5e2e7042f31..568f2fe25654aaef10ec13394af651b700086e7a 100644 --- a/src/share/vm/oops/compiledICHolder.cpp +++ b/src/share/vm/oops/compiledICHolder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,30 +24,12 @@ #include "precompiled.hpp" #include "oops/compiledICHolder.hpp" -#include "oops/klass.hpp" -#include "oops/method.hpp" #include "oops/oop.inline2.hpp" volatile int CompiledICHolder::_live_count; volatile int CompiledICHolder::_live_not_claimed_count; -bool CompiledICHolder::is_loader_alive(BoolObjectClosure* is_alive) { - if (_holder_metadata->is_method()) { - if (!((Method*)_holder_metadata)->method_holder()->is_loader_alive(is_alive)) { - return false; - } - } else if (_holder_metadata->is_klass()) { - if (!((Klass*)_holder_metadata)->is_loader_alive(is_alive)) { - return false; - } - } - if (!_holder_klass->is_loader_alive(is_alive)) { - return false; - } - return true; -} - // Printing void CompiledICHolder::print_on(outputStream* st) const { diff --git a/src/share/vm/oops/compiledICHolder.hpp b/src/share/vm/oops/compiledICHolder.hpp index 8e1f20e2277bdbbd339438e818810ee8d1f24ad5..63d3a87d0efdfd7978c6010a05613230f4809b3d 100644 --- a/src/share/vm/oops/compiledICHolder.hpp +++ b/src/share/vm/oops/compiledICHolder.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ #define SHARE_VM_OOPS_COMPILEDICHOLDEROOP_HPP #include "oops/oop.hpp" +#include "oops/klass.hpp" +#include "oops/method.hpp" // A CompiledICHolder* is a helper object for the inline cache implementation. // It holds: @@ -48,11 +50,12 @@ class CompiledICHolder : public CHeapObj { Metadata* _holder_metadata; Klass* _holder_klass; // to avoid name conflict with oopDesc::_klass CompiledICHolder* _next; + bool _is_metadata_method; public: // Constructor - CompiledICHolder(Metadata* metadata, Klass* klass) - : _holder_metadata(metadata), _holder_klass(klass) { + CompiledICHolder(Metadata* metadata, Klass* klass, bool is_method = true) + : _holder_metadata(metadata), _holder_klass(klass), _is_metadata_method(is_method) { #ifdef ASSERT Atomic::inc(&_live_count); Atomic::inc(&_live_not_claimed_count); @@ -82,7 +85,16 @@ class CompiledICHolder : public CHeapObj { CompiledICHolder* next() { return _next; } void set_next(CompiledICHolder* n) { _next = n; } - bool is_loader_alive(BoolObjectClosure* is_alive); + inline bool is_loader_alive(BoolObjectClosure* is_alive) { + Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata; + if (!k->is_loader_alive(is_alive)) { + return false; + } + if (!_holder_klass->is_loader_alive(is_alive)) { + return false; + } + return true; + } // Verify void verify_on(outputStream* st); diff --git a/src/share/vm/opto/ifnode.cpp b/src/share/vm/opto/ifnode.cpp index a5f0f3458f6bc890555213c66bb7bd2097fa7cb5..3101455e2b2236cc6675f505ef9c9dd2c6782e67 100644 --- a/src/share/vm/opto/ifnode.cpp +++ b/src/share/vm/opto/ifnode.cpp @@ -453,6 +453,9 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) { // offset. Return 2 if we had to negate the test. Index is NULL if the check // is versus a constant. int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) { + if (outcnt() != 2) { + return 0; + } Node* b = in(1); if (b == NULL || !b->is_Bool()) return 0; BoolNode* bn = b->as_Bool();