diff --git a/make/bsd/makefiles/jsig.make b/make/bsd/makefiles/jsig.make index b4802fb5069c3f00ab3923ee5c51e9269fdc4a5b..67cb4296eb1064c728e3ea6696e7064390873ad9 100644 --- a/make/bsd/makefiles/jsig.make +++ b/make/bsd/makefiles/jsig.make @@ -62,7 +62,7 @@ endif $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< + $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $< ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) ifeq ($(OS_VENDOR), Darwin) $(DSYMUTIL) $@ diff --git a/src/cpu/zero/vm/entry_zero.hpp b/src/cpu/zero/vm/entry_zero.hpp index 20f5d33dfd54a18dcfae074f1380cca237e8a3a6..73987f0610cedaa7eaf45abd3ba61d0017a66ba3 100644 --- a/src/cpu/zero/vm/entry_zero.hpp +++ b/src/cpu/zero/vm/entry_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright 2008, 2009, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,6 +26,8 @@ #ifndef CPU_ZERO_VM_ENTRY_ZERO_HPP #define CPU_ZERO_VM_ENTRY_ZERO_HPP +#include "interpreter/cppInterpreter.hpp" + class ZeroEntry { public: ZeroEntry() { diff --git a/src/cpu/zero/vm/nativeInst_zero.cpp b/src/cpu/zero/vm/nativeInst_zero.cpp index 98a2121a8da87eac44e95f2ade0701f89903ca74..bd9a7039bb7b26aeb12efd369cb6da17c6fd60c5 100644 --- a/src/cpu/zero/vm/nativeInst_zero.cpp +++ b/src/cpu/zero/vm/nativeInst_zero.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright 2008 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,6 +25,8 @@ #include "precompiled.hpp" #include "assembler_zero.inline.hpp" +#include "entry_zero.hpp" +#include "interpreter/cppInterpreter.hpp" #include "memory/resourceArea.hpp" #include "nativeInst_zero.hpp" #include "oops/oop.inline.hpp" diff --git a/src/os/linux/vm/os_linux.hpp b/src/os/linux/vm/os_linux.hpp index 7825a6f811629421cf6168786e6580ecf0678f51..bcf45f2e1813859028f14b9e6079da6641ebdd70 100644 --- a/src/os/linux/vm/os_linux.hpp +++ b/src/os/linux/vm/os_linux.hpp @@ -284,8 +284,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; } @@ -329,6 +329,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/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index f64c60e08a3cec104452bbbbaa28a7a694938f51..5a614b6a22462dd4558f7023c573bde1326b2586 100644 --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -547,9 +547,8 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t // normal bytecode execution. thread->clear_exception_oop_and_pc(); - Handle original_exception(thread, exception()); - - continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false); + bool recursive_exception = false; + continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false, recursive_exception); // If an exception was thrown during exception dispatch, the exception oop may have changed thread->set_exception_oop(exception()); thread->set_exception_pc(pc); @@ -557,8 +556,9 @@ JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* t // the exception cache is used only by non-implicit exceptions // Update the exception cache only when there didn't happen // another exception during the computation of the compiled - // exception handler. - if (continuation != NULL && original_exception() == exception()) { + // exception handler. Checking for exception oop equality is not + // sufficient because some exceptions are pre-allocated and reused. + if (continuation != NULL && !recursive_exception) { nm->add_handler_for_exception_and_pc(exception, pc, continuation); } } 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/codeCache.cpp b/src/share/vm/code/codeCache.cpp index c9059d73c67f0e5962ff49a6fb6ac58f3bcc06b0..9e5b7e98c73458e9e8b3ddef3b37918dbcdd7924 100644 --- a/src/share/vm/code/codeCache.cpp +++ b/src/share/vm/code/codeCache.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 @@ -41,6 +41,7 @@ #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/arguments.hpp" +#include "runtime/deoptimization.hpp" #include "runtime/icache.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" 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/interpreter/cppInterpreterGenerator.hpp b/src/share/vm/interpreter/cppInterpreterGenerator.hpp index c27805e3ec9800e06131821a1c50377f9ce30ab6..b753027f6c6c25e0c99b5664ef4765a091d67236 100644 --- a/src/share/vm/interpreter/cppInterpreterGenerator.hpp +++ b/src/share/vm/interpreter/cppInterpreterGenerator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -29,6 +29,9 @@ // of the template interpreter generator. #ifdef CC_INTERP +#ifdef TARGET_ARCH_zero +# include "entry_zero.hpp" +#endif class CppInterpreterGenerator: public AbstractInterpreterGenerator { protected: diff --git a/src/share/vm/interpreter/interpreter.hpp b/src/share/vm/interpreter/interpreter.hpp index d3792f8477dcc964123e65c83dfa450e72f153ed..1f18ce17f1fa8eafb8c0d8cbc4ee21dc1effe2b1 100644 --- a/src/share/vm/interpreter/interpreter.hpp +++ b/src/share/vm/interpreter/interpreter.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 @@ -28,11 +28,9 @@ #include "code/stubs.hpp" #include "interpreter/cppInterpreter.hpp" #include "interpreter/templateInterpreter.hpp" -#ifdef ZERO #ifdef TARGET_ARCH_zero # include "entry_zero.hpp" #endif -#endif // This file contains the platform-independent parts // of the interpreter and the interpreter generator. diff --git a/src/share/vm/interpreter/interpreterRuntime.cpp b/src/share/vm/interpreter/interpreterRuntime.cpp index 877c1ce32a129b260dc4739e86ef55e26b089b80..b5a72296fe89357d9847bb20e419dcd592b776ba 100644 --- a/src/share/vm/interpreter/interpreterRuntime.cpp +++ b/src/share/vm/interpreter/interpreterRuntime.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 @@ -320,6 +320,8 @@ IRT_ENTRY(void, InterpreterRuntime::throw_StackOverflowError(JavaThread* thread) Handle exception = get_preinitialized_exception( SystemDictionary::StackOverflowError_klass(), CHECK); + // Increment counter for hs_err file reporting + Atomic::inc(&Exceptions::_stack_overflow_errors); THROW_HANDLE(exception); IRT_END diff --git a/src/share/vm/memory/metaspace.cpp b/src/share/vm/memory/metaspace.cpp index 764b425e484224840e8fb318cde83812eb372e99..64f1abd820cea6c6c125c3cdcee460cd225331a9 100644 --- a/src/share/vm/memory/metaspace.cpp +++ b/src/share/vm/memory/metaspace.cpp @@ -3098,13 +3098,24 @@ void Metaspace::allocate_metaspace_compressed_klass_ptrs(char* requested_addr, a initialize_class_space(metaspace_rs); if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) { - gclog_or_tty->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: " SIZE_FORMAT, - Universe::narrow_klass_base(), Universe::narrow_klass_shift()); - gclog_or_tty->print_cr("Compressed class space size: " SIZE_FORMAT " Address: " PTR_FORMAT " Req Addr: " PTR_FORMAT, - compressed_class_space_size(), metaspace_rs.base(), requested_addr); + print_compressed_class_space(gclog_or_tty, requested_addr); } } +void Metaspace::print_compressed_class_space(outputStream* st, const char* requested_addr) { + st->print_cr("Narrow klass base: " PTR_FORMAT ", Narrow klass shift: %d", + p2i(Universe::narrow_klass_base()), Universe::narrow_klass_shift()); + if (_class_space_list != NULL) { + address base = (address)_class_space_list->current_virtual_space()->bottom(); + st->print("Compressed class space size: " SIZE_FORMAT " Address: " PTR_FORMAT, + compressed_class_space_size(), p2i(base)); + if (requested_addr != 0) { + st->print(" Req Addr: " PTR_FORMAT, p2i(requested_addr)); + } + st->cr(); + } + } + // For UseCompressedClassPointers the class space is reserved above the top of // the Java heap. The argument passed in is at the base of the compressed space. void Metaspace::initialize_class_space(ReservedSpace rs) { diff --git a/src/share/vm/memory/metaspace.hpp b/src/share/vm/memory/metaspace.hpp index 051f35b0b8caf7569a6a52bbf331adad26d9c1a5..36b00a521f222c2c949090cadd2a2ecfffd168c4 100644 --- a/src/share/vm/memory/metaspace.hpp +++ b/src/share/vm/memory/metaspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -259,6 +259,8 @@ class Metaspace : public CHeapObj { // Debugging support void verify(); + static void print_compressed_class_space(outputStream* st, const char* requested_addr = 0); + class AllocRecordClosure : public StackObj { public: virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0; diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp index 2e1e90f9787227c6da400b81694a285d09d1263c..efac8e1072aa7b72c46e36f055946e966564bbee 100644 --- a/src/share/vm/memory/universe.cpp +++ b/src/share/vm/memory/universe.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, 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 @@ -882,7 +882,7 @@ jint Universe::initialize_heap() { Universe::set_narrow_ptrs_base(Universe::narrow_oop_base()); if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) { - Universe::print_compressed_oops_mode(); + Universe::print_compressed_oops_mode(tty); } } // Universe::narrow_oop_base() is one page below the heap. @@ -904,23 +904,21 @@ jint Universe::initialize_heap() { return JNI_OK; } -void Universe::print_compressed_oops_mode() { - tty->cr(); - tty->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", +void Universe::print_compressed_oops_mode(outputStream* st) { + st->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", Universe::heap()->base(), Universe::heap()->reserved_region().byte_size()/M); - tty->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode())); + st->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode())); if (Universe::narrow_oop_base() != 0) { - tty->print(":" PTR_FORMAT, Universe::narrow_oop_base()); + st->print(":" PTR_FORMAT, Universe::narrow_oop_base()); } if (Universe::narrow_oop_shift() != 0) { - tty->print(", Oop shift amount: %d", Universe::narrow_oop_shift()); + st->print(", Oop shift amount: %d", Universe::narrow_oop_shift()); } - tty->cr(); - tty->cr(); + st->cr(); } // Reserve the Java heap, which is now the same for all GCs. diff --git a/src/share/vm/memory/universe.hpp b/src/share/vm/memory/universe.hpp index 3c6a89d2c94d12eb1483e6ab1b48ec1ae7ca9835..8909c6d1b43c031fb9a94f4c197059bf79ccfdfb 100644 --- a/src/share/vm/memory/universe.hpp +++ b/src/share/vm/memory/universe.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, 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 @@ -375,7 +375,7 @@ class Universe: AllStatic { static void set_narrow_ptrs_base(address a) { _narrow_ptrs_base = a; } static address narrow_ptrs_base() { return _narrow_ptrs_base; } - static void print_compressed_oops_mode(); + static void print_compressed_oops_mode(outputStream* st); // this is set in vm_version on sparc (and then reset in universe afaict) static void set_narrow_oop_shift(int shift) { 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(); diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp index 6ef48fd61a7fceefe2bf2c3b9bacf81c9d778a04..7ee5331938741fee08efb365def7a5452ef051e4 100644 --- a/src/share/vm/opto/library_call.cpp +++ b/src/share/vm/opto/library_call.cpp @@ -6026,7 +6026,7 @@ bool LibraryCallKit::inline_montgomeryMultiply() { } assert(UseMontgomeryMultiplyIntrinsic, "not implemented on this platform"); - const char* stubName = "montgomery_square"; + const char* stubName = "montgomery_multiply"; assert(callee()->signature()->size() == 7, "montgomeryMultiply has 7 parameters"); diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp index c4bac05179bd1d35305ef5a1ef06077413042923..4cf1afb4ab78ac893b5eb81b41641e0c8a74c9ce 100644 --- a/src/share/vm/opto/runtime.cpp +++ b/src/share/vm/opto/runtime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, 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 @@ -1234,17 +1234,23 @@ JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* t force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc); if (handler_address == NULL) { - Handle original_exception(thread, exception()); - handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true); + bool recursive_exception = false; + handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); assert (handler_address != NULL, "must have compiled handler"); // Update the exception cache only when the unwind was not forced // and there didn't happen another exception during the computation of the - // compiled exception handler. - if (!force_unwind && original_exception() == exception()) { + // compiled exception handler. Checking for exception oop equality is not + // sufficient because some exceptions are pre-allocated and reused. + if (!force_unwind && !recursive_exception) { nm->add_handler_for_exception_and_pc(exception,pc,handler_address); } } else { - assert(handler_address == SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true), "Must be the same"); +#ifdef ASSERT + bool recursive_exception = false; + address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); + assert(recursive_exception || (handler_address == computed_address), err_msg("Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT, + p2i(handler_address), p2i(computed_address))); +#endif } } diff --git a/src/share/vm/prims/jvmtiTagMap.cpp b/src/share/vm/prims/jvmtiTagMap.cpp index 1ae7ce63d4d64f99fc2b7274fb7934d68714e280..c45181dc79edc827832e7c5ab845b75e5947d2be 100644 --- a/src/share/vm/prims/jvmtiTagMap.cpp +++ b/src/share/vm/prims/jvmtiTagMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -47,6 +47,7 @@ #include "services/serviceUtil.hpp" #include "utilities/macros.hpp" #if INCLUDE_ALL_GCS +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" #endif // INCLUDE_ALL_GCS @@ -1519,6 +1520,14 @@ class TagObjectCollector : public JvmtiTagHashmapEntryClosure { if (_tags[i] == entry->tag()) { oop o = entry->object(); assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); +#if INCLUDE_ALL_GCS + if (UseG1GC) { + // The reference in this tag map could be the only (implicitly weak) + // reference to that object. If we hand it out, we need to keep it live wrt + // SATB marking similar to other j.l.ref.Reference referents. + G1SATBCardTableModRefBS::enqueue(o); + } +#endif jobject ref = JNIHandles::make_local(JavaThread::current(), o); _object_results->append(ref); _tag_results->append((uint64_t)entry->tag()); diff --git a/src/share/vm/runtime/frame.hpp b/src/share/vm/runtime/frame.hpp index c83808b6a9b81d5b97897564aec0bfac165218af..255596e9051c3193312da49100d219697b69112a 100644 --- a/src/share/vm/runtime/frame.hpp +++ b/src/share/vm/runtime/frame.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, 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 @@ -45,11 +45,9 @@ # include "adfiles/adGlobals_ppc_64.hpp" #endif #endif // COMPILER2 -#ifdef ZERO #ifdef TARGET_ARCH_zero # include "stack_zero.hpp" #endif -#endif typedef class BytecodeInterpreter* interpreterState; diff --git a/src/share/vm/runtime/frame.inline.hpp b/src/share/vm/runtime/frame.inline.hpp index ce725956dee4da1a18046c79135db02d4dce913d..37d13f8455d4b7b324ff65e2ac869de5051c53a5 100644 --- a/src/share/vm/runtime/frame.inline.hpp +++ b/src/share/vm/runtime/frame.inline.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 @@ -46,14 +46,12 @@ #ifdef TARGET_ARCH_ppc # include "jniTypes_ppc.hpp" #endif -#ifdef ZERO #ifdef TARGET_ARCH_zero # include "entryFrame_zero.hpp" # include "fakeStubFrame_zero.hpp" # include "interpreterFrame_zero.hpp" # include "sharkFrame_zero.hpp" #endif -#endif // This file holds platform-independent bodies of inline functions for frames. diff --git a/src/share/vm/runtime/os.cpp b/src/share/vm/runtime/os.cpp index 06e81a554ff6e96295ae1cffc322d53451afdf19..808fa2716f86ad69c3153fe0ad5f8837cb5a1b74 100644 --- a/src/share/vm/runtime/os.cpp +++ b/src/share/vm/runtime/os.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, 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 @@ -847,7 +847,7 @@ void os::print_cpu_info(outputStream* st) { pd_print_cpu_info(st); } -void os::print_date_and_time(outputStream *st) { +void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) { const int secs_per_day = 86400; const int secs_per_hour = 3600; const int secs_per_min = 60; @@ -856,6 +856,12 @@ void os::print_date_and_time(outputStream *st) { (void)time(&tloc); st->print("time: %s", ctime(&tloc)); // ctime adds newline. + struct tm tz; + if (localtime_pd(&tloc, &tz) != NULL) { + ::strftime(buf, buflen, "%Z", &tz); + st->print_cr("timezone: %s", buf); + } + double t = os::elapsedTime(); // NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in // Linux. Must be a bug in glibc ? Workaround is to round "t" to int diff --git a/src/share/vm/runtime/os.hpp b/src/share/vm/runtime/os.hpp index 6f85ff9c1251bac9252e8da93d975cacde9ab9ea..03afd1ba257a3409719fc012be322abfda1acb45 100644 --- a/src/share/vm/runtime/os.hpp +++ b/src/share/vm/runtime/os.hpp @@ -621,7 +621,7 @@ class os: AllStatic { static void print_register_info(outputStream* st, void* context); static void print_siginfo(outputStream* st, void* siginfo); static void print_signal_handlers(outputStream* st, char* buf, size_t buflen); - static void print_date_and_time(outputStream* st); + static void print_date_and_time(outputStream* st, char* buf, size_t buflen); static void print_location(outputStream* st, intptr_t x, bool verbose = false); static size_t lasterror(char *buf, size_t len); diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index 8ffa8ab31935f829b4985abb696becb28af42cff..d14f173265c1483de5dee33993c7da31215a2490 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.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 @@ -639,7 +639,7 @@ JRT_END // ret_pc points into caller; we are returning caller's exception handler // for given exception address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, - bool force_unwind, bool top_frame_only) { + bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred) { assert(nm != NULL, "must exist"); ResourceMark rm; @@ -667,6 +667,7 @@ address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, // BCI of the exception handler which caused the exception to be // thrown (bugs 4307310 and 4546590). Set "exception" reference // argument to ensure that the correct exception is thrown (4870175). + recursive_exception_occurred = true; exception = Handle(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; if (handler_bci >= 0) { @@ -758,6 +759,8 @@ JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread)) if (StackTraceInThrowable) { java_lang_Throwable::fill_in_stack_trace(exception); } + // Increment counter for hs_err file reporting + Atomic::inc(&Exceptions::_stack_overflow_errors); throw_and_post_jvmti_exception(thread, exception); JRT_END diff --git a/src/share/vm/runtime/sharedRuntime.hpp b/src/share/vm/runtime/sharedRuntime.hpp index 2167eb8d977e9f94913280b6bb1b12a6f31cde5c..c6a96a858efac07602da3a9a364914c5e948b120 100644 --- a/src/share/vm/runtime/sharedRuntime.hpp +++ b/src/share/vm/runtime/sharedRuntime.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 @@ -184,7 +184,7 @@ class SharedRuntime: AllStatic { // exception handling and implicit exceptions static address compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, - bool force_unwind, bool top_frame_only); + bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred); enum ImplicitExceptionKind { IMPLICIT_NULL, IMPLICIT_DIVIDE_BY_ZERO, diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index 9824febabf8b9d753fd4d255295ee8c250bff6db..68169b70c64838eaabbd0cf86c8be2abe4e0003a 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -51,11 +51,9 @@ #include "gc_implementation/g1/dirtyCardQueue.hpp" #include "gc_implementation/g1/satbQueue.hpp" #endif // INCLUDE_ALL_GCS -#ifdef ZERO #ifdef TARGET_ARCH_zero # include "stack_zero.hpp" #endif -#endif class ThreadSafepointState; class ThreadProfiler; diff --git a/src/share/vm/utilities/exceptions.cpp b/src/share/vm/utilities/exceptions.cpp index 5295c9b3608d2ac8e4f4026dfd03971b97ec767d..188e09730c3340201be4ad7a3ccfc7aa4cf56507 100644 --- a/src/share/vm/utilities/exceptions.cpp +++ b/src/share/vm/utilities/exceptions.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 @@ -154,6 +154,10 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc return; } + if (h_exception->is_a(SystemDictionary::OutOfMemoryError_klass())) { + count_out_of_memory_exceptions(h_exception); + } + assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable"); // set the pending exception @@ -228,6 +232,8 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file if (StackTraceInThrowable) { java_lang_Throwable::fill_in_stack_trace(exception, method()); } + // Increment counter for hs_err file reporting + Atomic::inc(&Exceptions::_stack_overflow_errors); } else { // if prior exception, throw that one instead exception = Handle(THREAD, THREAD->pending_exception()); @@ -404,6 +410,44 @@ Handle Exceptions::new_exception(Thread* thread, Symbol* name, h_prot, to_utf8_safe); } + +// Exception counting for hs_err file +volatile int Exceptions::_stack_overflow_errors = 0; +volatile int Exceptions::_out_of_memory_error_java_heap_errors = 0; +volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0; +volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0; + +void Exceptions::count_out_of_memory_exceptions(Handle exception) { + if (exception() == Universe::out_of_memory_error_metaspace()) { + Atomic::inc(&_out_of_memory_error_metaspace_errors); + } else if (exception() == Universe::out_of_memory_error_class_metaspace()) { + Atomic::inc(&_out_of_memory_error_class_metaspace_errors); + } else { + // everything else reported as java heap OOM + Atomic::inc(&_out_of_memory_error_java_heap_errors); + } +} + +void print_oom_count(outputStream* st, const char *err, int count) { + if (count > 0) { + st->print_cr("OutOfMemoryError %s=%d", err, count); + } +} + +bool Exceptions::has_exception_counts() { + return (_stack_overflow_errors + _out_of_memory_error_java_heap_errors + + _out_of_memory_error_metaspace_errors + _out_of_memory_error_class_metaspace_errors) > 0; +} + +void Exceptions::print_exception_counts_on_error(outputStream* st) { + print_oom_count(st, "java_heap_errors", _out_of_memory_error_java_heap_errors); + print_oom_count(st, "metaspace_errors", _out_of_memory_error_metaspace_errors); + print_oom_count(st, "class_metaspace_errors", _out_of_memory_error_class_metaspace_errors); + if (_stack_overflow_errors > 0) { + st->print_cr("StackOverflowErrors=%d", _stack_overflow_errors); + } +} + // Implementation of ExceptionMark ExceptionMark::ExceptionMark(Thread*& thread) { diff --git a/src/share/vm/utilities/exceptions.hpp b/src/share/vm/utilities/exceptions.hpp index 3dfe338ea4b4cde995852de3a688457f3248c65e..0a59d58094323bf89a87f89baaf325f02a4b80a4 100644 --- a/src/share/vm/utilities/exceptions.hpp +++ b/src/share/vm/utilities/exceptions.hpp @@ -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 @@ -102,6 +102,11 @@ class ThreadShadow: public CHeapObj { class Exceptions { static bool special_exception(Thread *thread, const char* file, int line, Handle exception); static bool special_exception(Thread* thread, const char* file, int line, Symbol* name, const char* message); + + // Count out of memory errors that are interesting in error diagnosis + static volatile int _out_of_memory_error_java_heap_errors; + static volatile int _out_of_memory_error_metaspace_errors; + static volatile int _out_of_memory_error_class_metaspace_errors; public: // this enum is defined to indicate whether it is safe to // ignore the encoding scheme of the original message string. @@ -160,6 +165,14 @@ class Exceptions { static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method); + // Exception counting for error files of interesting exceptions that may have + // caused a problem for the jvm + static volatile int _stack_overflow_errors; + + static bool has_exception_counts(); + static void count_out_of_memory_exceptions(Handle exception); + static void print_exception_counts_on_error(outputStream* st); + // for AbortVMOnException flag NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);) NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);) diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp index 15f6bf484a1d53e5088a27d2d7e3e33775e7b71a..8939da9bb4ba8d2eb5dd05b6ecd15e02f6fe00f4 100644 --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -304,6 +304,47 @@ void VMError::print_stack_trace(outputStream* st, JavaThread* jt, #endif // ZERO } +static void print_oom_reasons(outputStream* st) { + st->print_cr("# Possible reasons:"); + st->print_cr("# The system is out of physical RAM or swap space"); + if (UseCompressedOops) { + st->print_cr("# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap"); + } + if (LogBytesPerWord == 2) { + st->print_cr("# In 32 bit mode, the process size limit was hit"); + } + st->print_cr("# Possible solutions:"); + st->print_cr("# Reduce memory load on the system"); + st->print_cr("# Increase physical memory or swap space"); + st->print_cr("# Check if swap backing store is full"); + if (LogBytesPerWord == 2) { + st->print_cr("# Use 64 bit Java on a 64 bit OS"); + } + st->print_cr("# Decrease Java heap size (-Xmx/-Xms)"); + st->print_cr("# Decrease number of Java threads"); + st->print_cr("# Decrease Java thread stack sizes (-Xss)"); + st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize="); + if (UseCompressedOops) { + switch (Universe::narrow_oop_mode()) { + case Universe::UnscaledNarrowOop: + st->print_cr("# JVM is running with Unscaled Compressed Oops mode in which the Java heap is"); + st->print_cr("# placed in the first 4GB address space. The Java Heap base address is the"); + st->print_cr("# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress"); + st->print_cr("# to set the Java Heap base and to place the Java Heap above 4GB virtual address."); + break; + case Universe::ZeroBasedNarrowOop: + st->print_cr("# JVM is running with Zero Based Compressed Oops mode in which the Java heap is"); + st->print_cr("# placed in the first 32GB address space. The Java Heap base address is the"); + st->print_cr("# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress"); + st->print_cr("# to set the Java Heap base and to place the Java Heap above 32GB virtual address."); + break; + default: + break; + } + } + st->print_cr("# This output file may be truncated or incomplete."); +} + // This is the main function to report a fatal error. Only one thread can // call this function, so we don't need to worry about MT-safety. But it's // possible that the error handler itself may crash or die on an internal @@ -375,19 +416,7 @@ void VMError::report(outputStream* st) { } // In error file give some solutions if (_verbose) { - st->print_cr("# Possible reasons:"); - st->print_cr("# The system is out of physical RAM or swap space"); - st->print_cr("# In 32 bit mode, the process size limit was hit"); - st->print_cr("# Possible solutions:"); - st->print_cr("# Reduce memory load on the system"); - st->print_cr("# Increase physical memory or swap space"); - st->print_cr("# Check if swap backing store is full"); - st->print_cr("# Use 64 bit Java on a 64 bit OS"); - st->print_cr("# Decrease Java heap size (-Xmx/-Xms)"); - st->print_cr("# Decrease number of Java threads"); - st->print_cr("# Decrease Java thread stack sizes (-Xss)"); - st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize="); - st->print_cr("# This output file may be truncated or incomplete."); + print_oom_reasons(st); } else { return; // that's enough for the screen } @@ -675,6 +704,24 @@ void VMError::report(outputStream* st) { st->cr(); } + STEP(182, "(printing number of OutOfMemoryError and StackOverflow exceptions)") + + if (_verbose && Exceptions::has_exception_counts()) { + st->print_cr("OutOfMemory and StackOverflow Exception counts:"); + Exceptions::print_exception_counts_on_error(st); + st->cr(); + } + + STEP(185, "(printing compressed oops mode") + + if (_verbose && UseCompressedOops) { + Universe::print_compressed_oops_mode(st); + if (UseCompressedClassPointers) { + Metaspace::print_compressed_class_space(st); + } + st->cr(); + } + STEP(190, "(printing heap information)" ) if (_verbose && Universe::is_fully_initialized()) { @@ -780,7 +827,7 @@ void VMError::report(outputStream* st) { STEP(280, "(printing date and time)" ) if (_verbose) { - os::print_date_and_time(st); + os::print_date_and_time(st, buf, sizeof(buf)); st->cr(); } diff --git a/test/compiler/gcbarriers/PreserveFPRegistersTest.java b/test/compiler/gcbarriers/PreserveFPRegistersTest.java index c190182d29bd8ecda2b72a6c46e6c3c9b7d7c47f..5ac6a946dfd9e69a7d422f7a885aeb6aea735917 100644 --- a/test/compiler/gcbarriers/PreserveFPRegistersTest.java +++ b/test/compiler/gcbarriers/PreserveFPRegistersTest.java @@ -25,14 +25,22 @@ /** * @test * @bug 8148175 - * @run main/othervm/timeout=300 -XX:+UseG1GC -Xbatch -Xmx128m PreserveFPRegistersTest + * @requires vm.gc=="G1" | vm.gc=="null" + * @library /testlibrary /testlibrary/whitebox + * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xmx300m -XX:+UseG1GC PreserveFPRegistersTest */ + +import sun.hotspot.WhiteBox; + public class PreserveFPRegistersTest { public static void main(String... args) throws InterruptedException { new PreserveFPRegistersTest().go(); } + private static WhiteBox wb = WhiteBox.getWhiteBox(); + public final Object[][] storage; /** @@ -51,18 +59,32 @@ public class PreserveFPRegistersTest { public final int regionCount; PreserveFPRegistersTest() { - long regionSize = 1_000_000; //WB.g1RegionSize(); - + long regionSize = wb.g1RegionSize(); Runtime rt = Runtime.getRuntime(); long used = rt.totalMemory() - rt.freeMemory(); long totalFree = rt.maxMemory() - used; regionCount = (int) ( (totalFree / regionSize) * 0.9); - int refSize = 4; - + int refSize = wb.getHeapOopSize(); N = (int) ((regionSize / K ) / refSize) - 5; - storage = new Object[regionCount * K][]; - for (int i = 0; i < storage.length; i++) { - storage[i] = new Object[N]; + + System.out.println("%% Memory"); + System.out.println("%% used : " + used / 1024 + "M"); + System.out.println("%% available : " + totalFree / 1024 + "M"); + System.out.println("%% G1 Region Size: " + regionSize / 1024 + "M"); + System.out.println("%% region count : " + regionCount); + + System.out.println("%% Objects storage"); + System.out.println("%% N (array length) : " + N); + System.out.println("%% K (objects in regions): " + K); + System.out.println("%% Reference size : " + refSize); + + try { + storage = new Object[regionCount * K][]; + for (int i = 0; i < storage.length; i++) { + storage[i] = new Object[N]; + } + } catch(OutOfMemoryError e) { + throw new AssertionError("Test Failed with unexpected OutOfMemoryError exception"); } }