# HG changeset patch # User jdv # Date 1552293327 -19800 # Node ID 86ed45a9dedb28b8369c99f4e9f52c950c0cd185 # Parent 48f2dc62ba772b18b6bcd33a8208b654cb51a548# Parent 744dc9c336762662e5c60d0fb45ebf91cc47ac35 Merge diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/os/posix/os_posix.cpp --- a/src/hotspot/os/posix/os_posix.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/os/posix/os_posix.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -31,6 +31,7 @@ #include "runtime/interfaceSupport.inline.hpp" #include "services/memTracker.hpp" #include "utilities/align.hpp" +#include "utilities/events.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/macros.hpp" #include "utilities/vmError.hpp" @@ -1269,6 +1270,15 @@ return true; } +bool os::signal_sent_by_kill(const void* siginfo) { + const siginfo_t* const si = (const siginfo_t*)siginfo; + return si->si_code == SI_USER || si->si_code == SI_QUEUE +#ifdef SI_TKILL + || si->si_code == SI_TKILL +#endif + ; +} + void os::print_siginfo(outputStream* os, const void* si0) { const siginfo_t* const si = (const siginfo_t*) si0; @@ -1299,7 +1309,7 @@ // so it depends on the context which member to use. For synchronous error signals, // we print si_addr, unless the signal was sent by another process or thread, in // which case we print out pid or tid of the sender. - if (si->si_code == SI_USER || si->si_code == SI_QUEUE) { + if (signal_sent_by_kill(si)) { const pid_t pid = si->si_pid; os->print(", si_pid: %ld", (long) pid); if (IS_VALID_PID(pid)) { @@ -1325,6 +1335,25 @@ } +bool os::signal_thread(Thread* thread, int sig, const char* reason) { + OSThread* osthread = thread->osthread(); + if (osthread) { +#if defined (SOLARIS) + // Note: we cannot use pthread_kill on Solaris - not because + // its missing, but because we do not have the pthread_t id. + int status = thr_kill(osthread->thread_id(), sig); +#else + int status = pthread_kill(osthread->pthread_id(), sig); +#endif + if (status == 0) { + Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.", + sig, p2i(thread), reason); + return true; + } + } + return false; +} + int os::Posix::unblock_thread_signal_mask(const sigset_t *set) { return pthread_sigmask(SIG_UNBLOCK, set, NULL); } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/os/windows/os_windows.cpp --- a/src/hotspot/os/windows/os_windows.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/os/windows/os_windows.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -1797,6 +1797,11 @@ st->cr(); } +bool os::signal_sent_by_kill(const void* siginfo) { + // TODO: Is this possible? + return false; +} + void os::print_siginfo(outputStream *st, const void* siginfo) { const EXCEPTION_RECORD* const er = (EXCEPTION_RECORD*)siginfo; st->print("siginfo:"); @@ -1830,6 +1835,11 @@ st->cr(); } +bool os::signal_thread(Thread* thread, int sig, const char* reason) { + // TODO: Can we kill thread? + return false; +} + void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { // do nothing } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/ci/ciReplay.cpp --- a/src/hotspot/share/ci/ciReplay.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/ci/ciReplay.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -274,15 +274,42 @@ // Parse a sequence of raw data encoded as bytes and return the // resulting data. char* parse_data(const char* tag, int& length) { - if (!parse_tag_and_count(tag, length)) { + int read_size = 0; + if (!parse_tag_and_count(tag, read_size)) { return NULL; } - char * result = NEW_RESOURCE_ARRAY(char, length); - for (int i = 0; i < length; i++) { + int actual_size = sizeof(MethodData); + char *result = NEW_RESOURCE_ARRAY(char, actual_size); + int i = 0; + if (read_size != actual_size) { + tty->print_cr("Warning: ciMethodData parsing sees MethodData size %i in file, current is %i", read_size, + actual_size); + // Replay serializes the entire MethodData, but the data is at the end. + // If the MethodData instance size has changed, we can pad or truncate in the beginning + int padding = actual_size - read_size; + if (padding > 0) { + // pad missing data with zeros + tty->print_cr("- Padding MethodData"); + for (; i < padding; i++) { + result[i] = 0; + } + } else if (padding < 0) { + // drop some data + tty->print_cr("- Truncating MethodData"); + for (int j = 0; j < -padding; j++) { + int val = parse_int("data"); + // discard val + } + } + } + + assert(i < actual_size, "At least some data must remain to be copied"); + for (; i < actual_size; i++) { int val = parse_int("data"); result[i] = val; } + length = actual_size; return result; } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/classfile/classFileParser.cpp --- a/src/hotspot/share/classfile/classFileParser.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/classfile/classFileParser.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -52,7 +52,7 @@ #include "oops/klass.inline.hpp" #include "oops/klassVtable.hpp" #include "oops/metadata.hpp" -#include "oops/method.hpp" +#include "oops/method.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" @@ -1974,46 +1974,6 @@ return localvariable_table_start; } - -void ClassFileParser::parse_type_array(u2 array_length, - u4 code_length, - u4* const u1_index, - u4* const u2_index, - u1* const u1_array, - u2* const u2_array, - TRAPS) { - const ClassFileStream* const cfs = _stream; - u2 index = 0; // index in the array with long/double occupying two slots - u4 i1 = *u1_index; - u4 i2 = *u2_index + 1; - for(int i = 0; i < array_length; i++) { - const u1 tag = u1_array[i1++] = cfs->get_u1(CHECK); - index++; - if (tag == ITEM_Long || tag == ITEM_Double) { - index++; - } else if (tag == ITEM_Object) { - const u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK); - guarantee_property(valid_klass_reference_at(class_index), - "Bad class index %u in StackMap in class file %s", - class_index, CHECK); - } else if (tag == ITEM_Uninitialized) { - const u2 offset = u2_array[i2++] = cfs->get_u2(CHECK); - guarantee_property( - offset < code_length, - "Bad uninitialized type offset %u in StackMap in class file %s", - offset, CHECK); - } else { - guarantee_property( - tag <= (u1)ITEM_Uninitialized, - "Unknown variable type %u in StackMap in class file %s", - tag, CHECK); - } - } - u2_array[*u2_index] = index; - *u1_index = i1; - *u2_index = i2; -} - static const u1* parse_stackmap_table(const ClassFileStream* const cfs, u4 code_attribute_length, bool need_verify, diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/classfile/classFileParser.hpp --- a/src/hotspot/share/classfile/classFileParser.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/classfile/classFileParser.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -68,8 +68,7 @@ // enum Publicity { INTERNAL, - BROADCAST, - NOF_PUBLICITY_LEVELS + BROADCAST }; enum { LegalClass, LegalField, LegalMethod }; // used to verify unqualified names @@ -270,14 +269,6 @@ u4 method_attribute_length, TRAPS); - void parse_type_array(u2 array_length, - u4 code_length, - u4* const u1_index, - u4* const u2_index, - u1* const u1_array, - u2* const u2_array, - TRAPS); - // Classfile attribute parsing u2 parse_generic_signature_attribute(const ClassFileStream* const cfs, TRAPS); void parse_classfile_sourcefile_attribute(const ClassFileStream* const cfs, TRAPS); @@ -524,7 +515,6 @@ int itable_size() const { return _itable_size; } u2 this_class_index() const { return _this_class_index; } - u2 super_class_index() const { return _super_class_index; } bool is_unsafe_anonymous() const { return _unsafe_anonymous_host != NULL; } bool is_interface() const { return _access_flags.is_interface(); } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/classfile/classFileStream.cpp --- a/src/hotspot/share/classfile/classFileStream.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/classfile/classFileStream.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -30,7 +30,6 @@ #include "memory/resourceArea.hpp" const bool ClassFileStream::verify = true; -const bool ClassFileStream::no_verification = false; void ClassFileStream::truncated_file_error(TRAPS) const { THROW_MSG(vmSymbols::java_lang_ClassFormatError(), "Truncated class file"); @@ -73,69 +72,6 @@ need_verify()); } -u1 ClassFileStream::get_u1(TRAPS) const { - if (_need_verify) { - guarantee_more(1, CHECK_0); - } else { - assert(1 <= _buffer_end - _current, "buffer overflow"); - } - return *_current++; -} - -u2 ClassFileStream::get_u2(TRAPS) const { - if (_need_verify) { - guarantee_more(2, CHECK_0); - } else { - assert(2 <= _buffer_end - _current, "buffer overflow"); - } - const u1* tmp = _current; - _current += 2; - return Bytes::get_Java_u2((address)tmp); -} - -u4 ClassFileStream::get_u4(TRAPS) const { - if (_need_verify) { - guarantee_more(4, CHECK_0); - } else { - assert(4 <= _buffer_end - _current, "buffer overflow"); - } - const u1* tmp = _current; - _current += 4; - return Bytes::get_Java_u4((address)tmp); -} - -u8 ClassFileStream::get_u8(TRAPS) const { - if (_need_verify) { - guarantee_more(8, CHECK_0); - } else { - assert(8 <= _buffer_end - _current, "buffer overflow"); - } - const u1* tmp = _current; - _current += 8; - return Bytes::get_Java_u8((address)tmp); -} - -void ClassFileStream::skip_u1(int length, TRAPS) const { - if (_need_verify) { - guarantee_more(length, CHECK); - } - _current += length; -} - -void ClassFileStream::skip_u2(int length, TRAPS) const { - if (_need_verify) { - guarantee_more(length * 2, CHECK); - } - _current += length * 2; -} - -void ClassFileStream::skip_u4(int length, TRAPS) const { - if (_need_verify) { - guarantee_more(length * 4, CHECK); - } - _current += length * 4; -} - uint64_t ClassFileStream::compute_fingerprint() const { int classfile_size = length(); int classfile_crc = ClassLoader::crc32(0, (const char*)buffer(), length()); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/classfile/classFileStream.hpp --- a/src/hotspot/share/classfile/classFileStream.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/classfile/classFileStream.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -52,7 +52,6 @@ const char* const clone_source() const; public: - static const bool no_verification; static const bool verify; ClassFileStream(const u1* buffer, @@ -92,21 +91,34 @@ } // Read u1 from stream - u1 get_u1(TRAPS) const; u1 get_u1_fast() const { return *_current++; } + u1 get_u1(TRAPS) const { + if (_need_verify) { + guarantee_more(1, CHECK_0); + } else { + assert(1 <= _buffer_end - _current, "buffer overflow"); + } + return get_u1_fast(); + } // Read u2 from stream - u2 get_u2(TRAPS) const; u2 get_u2_fast() const { u2 res = Bytes::get_Java_u2((address)_current); _current += 2; return res; } + u2 get_u2(TRAPS) const { + if (_need_verify) { + guarantee_more(2, CHECK_0); + } else { + assert(2 <= _buffer_end - _current, "buffer overflow"); + } + return get_u2_fast(); + } // Read u4 from stream - u4 get_u4(TRAPS) const; u4 get_u4_fast() const { u4 res = Bytes::get_Java_u4((address)_current); _current += 4; @@ -114,25 +126,27 @@ } // Read u8 from stream - u8 get_u8(TRAPS) const; u8 get_u8_fast() const { u8 res = Bytes::get_Java_u8((address)_current); _current += 8; return res; } - // Skip length u1 or u2 elements from stream - void skip_u1(int length, TRAPS) const; + // Skip length elements from stream + void skip_u1(int length, TRAPS) const { + if (_need_verify) { + guarantee_more(length, CHECK); + } + skip_u1_fast(length); + } void skip_u1_fast(int length) const { _current += length; } - void skip_u2(int length, TRAPS) const; void skip_u2_fast(int length) const { _current += 2 * length; } - void skip_u4(int length, TRAPS) const; void skip_u4_fast(int length) const { _current += 4 * length; } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/classfile/javaClasses.cpp --- a/src/hotspot/share/classfile/javaClasses.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/classfile/javaClasses.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -834,8 +834,8 @@ if (module.is_null()) { // During startup, the module may be NULL only if java.base has not been defined yet. // Put the class on the fixup_module_list to patch later when the java.lang.Module - // for java.base is known. - assert(!Universe::is_module_initialized(), "Incorrect java.lang.Module pre module system initialization"); + // for java.base is known. But note that since we captured the NULL module another + // thread may have completed that initialization. bool javabase_was_defined = false; { diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/code/compressedStream.cpp --- a/src/hotspot/share/code/compressedStream.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/code/compressedStream.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -26,15 +26,6 @@ #include "code/compressedStream.hpp" #include "utilities/ostream.hpp" -// 32-bit one-to-one sign encoding taken from Pack200 -// converts leading sign bits into leading zeroes with trailing sign bit -inline juint CompressedStream::encode_sign(jint value) { - return (value << 1) ^ (value >> 31); -} -inline jint CompressedStream::decode_sign(juint value) { - return (value >> 1) ^ -(jint)(value & 1); -} - // 32-bit self-inverse encoding of float bits // converts trailing zeroes (common in floats) to leading zeroes inline juint CompressedStream::reverse_int(juint i) { @@ -46,7 +37,6 @@ return i; } - jint CompressedReadStream::read_signed_int() { return decode_sign(read_int()); } @@ -90,11 +80,6 @@ _size = _size * 2; } -void CompressedWriteStream::write_signed_int(jint value) { - // this encoding, called SIGNED5, is taken from Pack200 - write_int(encode_sign(value)); -} - void CompressedWriteStream::write_float(jfloat value) { juint f = jint_cast(value); juint rf = reverse_int(f); @@ -117,136 +102,3 @@ write_signed_int(low(value)); write_signed_int(high(value)); } - - -/// The remaining details - -#ifndef PRODUCT -// set this to trigger unit test -void test_compressed_stream(int trace); -bool test_compressed_stream_enabled = false; -#endif - -void CompressedWriteStream::write_int_mb(jint value) { - debug_only(int pos1 = position()); - juint sum = value; - for (int i = 0; ; ) { - if (sum < L || i == MAX_i) { - // remainder is either a "low code" or the 5th byte - assert(sum == (u_char)sum, "valid byte"); - write((u_char)sum); - break; - } - sum -= L; - int b_i = L + (sum % H); // this is a "high code" - sum >>= lg_H; // extracted 6 bits - write(b_i); ++i; - } - -#ifndef PRODUCT - if (test_compressed_stream_enabled) { // hack to enable this stress test - test_compressed_stream_enabled = false; - test_compressed_stream(0); - } -#endif -} - - -#ifndef PRODUCT -/// a unit test (can be run by hand from a debugger) - -// Avoid a VS2005 compiler stack overflow w/ fastdebug build. -// The following pragma optimize turns off optimization ONLY -// for this block (a matching directive turns it back on later). -// These directives can be removed once the MS VS.NET 2005 -// compiler stack overflow is fixed. -#if defined(_MSC_VER) && _MSC_VER >=1400 && !defined(_WIN64) -#pragma optimize("", off) -#pragma warning(disable: 4748) -#endif - -// generator for an "interesting" set of critical values -enum { stretch_limit = (1<<16) * (64-16+1) }; -static jlong stretch(jint x, int bits) { - // put x[high 4] into place - jlong h = (jlong)((x >> (16-4))) << (bits - 4); - // put x[low 12] into place, sign extended - jlong l = ((jlong)x << (64-12)) >> (64-12); - // move l upwards, maybe - l <<= (x >> 16); - return h ^ l; -} - -PRAGMA_DIAG_PUSH -PRAGMA_FORMAT_IGNORED // Someone needs to deal with this. -void test_compressed_stream(int trace) { - CompressedWriteStream bytes(stretch_limit * 100); - jint n; - int step = 0, fails = 0; -#define CHECKXY(x, y, fmt) { \ - ++step; \ - int xlen = (pos = decode.position()) - lastpos; lastpos = pos; \ - if (trace > 0 && (step % trace) == 0) { \ - tty->print_cr("step %d, n=%08x: value=" fmt " (len=%d)", \ - step, n, x, xlen); } \ - if (x != y) { \ - tty->print_cr("step %d, n=%d: " fmt " != " fmt, step, n, x, y); \ - fails++; \ - } } - for (n = 0; n < (1<<8); n++) { - jbyte x = (jbyte)n; - bytes.write_byte(x); ++step; - } - for (n = 0; n < stretch_limit; n++) { - jint x = (jint)stretch(n, 32); - bytes.write_int(x); ++step; - bytes.write_signed_int(x); ++step; - bytes.write_float(jfloat_cast(x)); ++step; - } - for (n = 0; n < stretch_limit; n++) { - jlong x = stretch(n, 64); - bytes.write_long(x); ++step; - bytes.write_double(jdouble_cast(x)); ++step; - } - int length = bytes.position(); - if (trace != 0) - tty->print_cr("set up test of %d stream values, size %d", step, length); - step = 0; - // now decode it all - CompressedReadStream decode(bytes.buffer()); - int pos, lastpos = decode.position(); - for (n = 0; n < (1<<8); n++) { - jbyte x = (jbyte)n; - jbyte y = decode.read_byte(); - CHECKXY(x, y, "%db"); - } - for (n = 0; n < stretch_limit; n++) { - jint x = (jint)stretch(n, 32); - jint y1 = decode.read_int(); - CHECKXY(x, y1, "%du"); - jint y2 = decode.read_signed_int(); - CHECKXY(x, y2, "%di"); - jint y3 = jint_cast(decode.read_float()); - CHECKXY(x, y3, "%df"); - } - for (n = 0; n < stretch_limit; n++) { - jlong x = stretch(n, 64); - jlong y1 = decode.read_long(); - CHECKXY(x, y1, INT64_FORMAT "l"); - jlong y2 = jlong_cast(decode.read_double()); - CHECKXY(x, y2, INT64_FORMAT "d"); - } - int length2 = decode.position(); - if (trace != 0) - tty->print_cr("finished test of %d stream values, size %d", step, length2); - guarantee(length == length2, "bad length"); - guarantee(fails == 0, "test failures"); -} -PRAGMA_DIAG_POP - -#if defined(_MSC_VER) &&_MSC_VER >=1400 && !defined(_WIN64) -#pragma warning(default: 4748) -#pragma optimize("", on) -#endif - -#endif // PRODUCT diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/code/compressedStream.hpp --- a/src/hotspot/share/code/compressedStream.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/code/compressedStream.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -43,11 +43,11 @@ MAX_i = 4 // bytes are numbered in (0..4), max 5 bytes }; - // these inlines are defined only in compressedStream.cpp - static inline juint encode_sign(jint value); // for Pack200 SIGNED5 - static inline jint decode_sign(juint value); // for Pack200 SIGNED5 - static inline juint reverse_int(juint bits); // to trim trailing float 0's - + // 32-bit one-to-one sign encoding taken from Pack200 + // converts leading sign bits into leading zeroes with trailing sign bit + static juint encode_sign(jint value) { return (value << 1) ^ (value >> 31); } + static jint decode_sign(juint value) { return (value >> 1) ^ -(jint)(value & 1); } + static juint reverse_int(juint i); // to trim trailing float 0's public: CompressedStream(u_char* buffer, int position = 0) { _buffer = buffer; @@ -134,7 +134,22 @@ } void grow(); - void write_int_mb(jint value); // UNSIGNED5 coding, 1-5 byte cases + // UNSIGNED5 coding, 1-5 byte cases + void write_int_mb(jint value) { + juint sum = value; + for (int i = 0; ; ) { + if (sum < L || i == MAX_i) { + // remainder is either a "low code" or the 5th byte + assert(sum == (u_char)sum, "valid byte"); + write((u_char)sum); + break; + } + sum -= L; + int b_i = L + (sum % H); // this is a "high code" + sum >>= lg_H; // extracted 6 bits + write(b_i); ++i; + } + } protected: int _size; @@ -151,7 +166,7 @@ void write_int(jint value) { if ((juint)value < L && !full()) store((u_char)value); else write_int_mb(value); } - void write_signed_int(jint value); // write_int(encode_sign(value)) + void write_signed_int(jint value) { write_int(encode_sign(value)); } void write_float(jfloat value); // write_int(reverse_int(jint_cast(v))) void write_double(jdouble value); // write_int(reverse_int()) void write_long(jlong value); // write_signed_int() diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shared/c2/barrierSetC2.hpp --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -51,7 +51,7 @@ // This denotes that the access reads state. const DecoratorSet C2_READ_ACCESS = DECORATOR_LAST << 8; // A nearby allocation? -const DecoratorSet C2_TIGHLY_COUPLED_ALLOC = DECORATOR_LAST << 9; +const DecoratorSet C2_TIGHTLY_COUPLED_ALLOC = DECORATOR_LAST << 9; // Loads and stores from an arraycopy being optimized const DecoratorSet C2_ARRAY_COPY = DECORATOR_LAST << 10; diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp --- a/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shared/c2/modRefBarrierSetC2.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -40,9 +40,9 @@ bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; bool in_heap = (decorators & IN_HEAP) != 0; bool use_precise = is_array || anonymous; - bool tighly_coupled_alloc = (decorators & C2_TIGHLY_COUPLED_ALLOC) != 0; + bool tightly_coupled_alloc = (decorators & C2_TIGHTLY_COUPLED_ALLOC) != 0; - if (!access.is_oop() || tighly_coupled_alloc || (!in_heap && !anonymous)) { + if (!access.is_oop() || tightly_coupled_alloc || (!in_heap && !anonymous)) { return BarrierSetC2::store_at_resolved(access, val); } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shared/genCollectedHeap.cpp --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -679,7 +679,9 @@ // Track memory usage and detect low memory after GC finishes MemoryService::track_memory_usage(); - gc_epilogue(complete); + // Need to tell the epilogue code we are done with Full GC, regardless what was + // the initial value for "complete" flag. + gc_epilogue(true); BiasedLocking::restore_marks(); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -657,7 +657,7 @@ static_cast(val.type()), NULL /* pre_val */, access.type()); } else { assert(access.is_opt_access(), "only for optimization passes"); - assert(((decorators & C2_TIGHLY_COUPLED_ALLOC) != 0 || !ShenandoahSATBBarrier) && (decorators & C2_ARRAY_COPY) != 0, "unexpected caller of this code"); + assert(((decorators & C2_TIGHTLY_COUPLED_ALLOC) != 0 || !ShenandoahSATBBarrier) && (decorators & C2_ARRAY_COPY) != 0, "unexpected caller of this code"); C2OptAccess& opt_access = static_cast(access); PhaseGVN& gvn = opt_access.gvn(); MergeMemNode* mm = opt_access.mem(); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -86,25 +86,40 @@ void ShenandoahAssertToSpaceClosure::do_oop(oop* p) { do_oop_work(p); } #endif -class ShenandoahPretouchTask : public AbstractGangTask { +class ShenandoahPretouchHeapTask : public AbstractGangTask { private: ShenandoahRegionIterator _regions; - const size_t _bitmap_size; const size_t _page_size; - char* _bitmap_base; public: - ShenandoahPretouchTask(char* bitmap_base, size_t bitmap_size, size_t page_size) : - AbstractGangTask("Shenandoah PreTouch"), - _bitmap_size(bitmap_size), - _page_size(page_size), - _bitmap_base(bitmap_base) { - } + ShenandoahPretouchHeapTask(size_t page_size) : + AbstractGangTask("Shenandoah Pretouch Heap"), + _page_size(page_size) {} virtual void work(uint worker_id) { ShenandoahHeapRegion* r = _regions.next(); while (r != NULL) { os::pretouch_memory(r->bottom(), r->end(), _page_size); - + r = _regions.next(); + } + } +}; + +class ShenandoahPretouchBitmapTask : public AbstractGangTask { +private: + ShenandoahRegionIterator _regions; + char* _bitmap_base; + const size_t _bitmap_size; + const size_t _page_size; +public: + ShenandoahPretouchBitmapTask(char* bitmap_base, size_t bitmap_size, size_t page_size) : + AbstractGangTask("Shenandoah Pretouch Bitmap"), + _bitmap_base(bitmap_base), + _bitmap_size(bitmap_size), + _page_size(page_size) {} + + virtual void work(uint worker_id) { + ShenandoahHeapRegion* r = _regions.next(); + while (r != NULL) { size_t start = r->region_number() * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); size_t end = (r->region_number() + 1) * ShenandoahHeapRegion::region_size_bytes() / MarkBitMap::heap_map_factor(); assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size); @@ -121,73 +136,60 @@ initialize_heuristics(); + // + // Figure out heap sizing + // + size_t init_byte_size = collector_policy()->initial_heap_byte_size(); - size_t max_byte_size = collector_policy()->max_heap_byte_size(); + size_t max_byte_size = collector_policy()->max_heap_byte_size(); size_t heap_alignment = collector_policy()->heap_alignment(); + size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes(); + if (ShenandoahAlwaysPreTouch) { // Enabled pre-touch means the entire heap is committed right away. init_byte_size = max_byte_size; } - Universe::check_alignment(max_byte_size, - ShenandoahHeapRegion::region_size_bytes(), - "shenandoah heap"); - Universe::check_alignment(init_byte_size, - ShenandoahHeapRegion::region_size_bytes(), - "shenandoah heap"); - - ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, - heap_alignment); - initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*) (heap_rs.base() + heap_rs.size())); - - ReservedSpace pgc_rs = heap_rs.first_part(max_byte_size); + Universe::check_alignment(max_byte_size, reg_size_bytes, "Shenandoah heap"); + Universe::check_alignment(init_byte_size, reg_size_bytes, "Shenandoah heap"); _num_regions = ShenandoahHeapRegion::region_count(); - size_t num_committed_regions = init_byte_size / ShenandoahHeapRegion::region_size_bytes(); + size_t num_committed_regions = init_byte_size / reg_size_bytes; num_committed_regions = MIN2(num_committed_regions, _num_regions); assert(num_committed_regions <= _num_regions, "sanity"); - _initial_size = num_committed_regions * ShenandoahHeapRegion::region_size_bytes(); + _initial_size = num_committed_regions * reg_size_bytes; _committed = _initial_size; - log_info(gc, heap)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s", - byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size)); - if (!os::commit_memory(pgc_rs.base(), _initial_size, false)) { - vm_exit_out_of_memory(_initial_size, OOM_MMAP_ERROR, "Shenandoah failed to initialize heap"); - } - - size_t reg_size_words = ShenandoahHeapRegion::region_size_words(); - size_t reg_size_bytes = ShenandoahHeapRegion::region_size_bytes(); - - _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); - _free_set = new ShenandoahFreeSet(this, _num_regions); - - _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)pgc_rs.base()); - - if (ShenandoahPacing) { - _pacer = new ShenandoahPacer(this); - _pacer->setup_for_idle(); - } else { - _pacer = NULL; - } + size_t heap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + + // + // Reserve and commit memory for heap + // + + ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, heap_alignment); + initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*) (heap_rs.base() + heap_rs.size())); + _heap_region = MemRegion((HeapWord*)heap_rs.base(), heap_rs.size() / HeapWordSize); + _heap_region_special = heap_rs.special(); assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, - "misaligned heap: " PTR_FORMAT, p2i(base())); - - // The call below uses stuff (the SATB* things) that are in G1, but probably - // belong into a shared location. - ShenandoahBarrierSet::satb_mark_queue_set().initialize(this, - SATB_Q_CBL_mon, - 20 /* G1SATBProcessCompletedThreshold */, - 60 /* G1SATBBufferEnqueueingThresholdPercent */); - - // Reserve space for prev and next bitmap. - size_t bitmap_page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + "Misaligned heap: " PTR_FORMAT, p2i(base())); + + ReservedSpace sh_rs = heap_rs.first_part(max_byte_size); + if (!_heap_region_special) { + os::commit_memory_or_exit(sh_rs.base(), _initial_size, heap_alignment, false, + "Cannot commit heap memory"); + } + + // + // Reserve and commit memory for bitmap(s) + // + _bitmap_size = MarkBitMap::compute_size(heap_rs.size()); _bitmap_size = align_up(_bitmap_size, bitmap_page_size); - _heap_region = MemRegion((HeapWord*) heap_rs.base(), heap_rs.size() / HeapWordSize); size_t bitmap_bytes_per_region = reg_size_bytes / MarkBitMap::heap_map_factor(); @@ -212,38 +214,57 @@ "Bitmap slices should be page-granular: bps = " SIZE_FORMAT ", page size = " SIZE_FORMAT, _bitmap_bytes_per_slice, bitmap_page_size); - ReservedSpace bitmap0(_bitmap_size, bitmap_page_size); - MemTracker::record_virtual_memory_type(bitmap0.base(), mtGC); - _bitmap_region = MemRegion((HeapWord*) bitmap0.base(), bitmap0.size() / HeapWordSize); + ReservedSpace bitmap(_bitmap_size, bitmap_page_size); + MemTracker::record_virtual_memory_type(bitmap.base(), mtGC); + _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize); + _bitmap_region_special = bitmap.special(); size_t bitmap_init_commit = _bitmap_bytes_per_slice * align_up(num_committed_regions, _bitmap_regions_per_slice) / _bitmap_regions_per_slice; bitmap_init_commit = MIN2(_bitmap_size, bitmap_init_commit); - os::commit_memory_or_exit((char *) (_bitmap_region.start()), bitmap_init_commit, false, - "couldn't allocate initial bitmap"); - - size_t page_size = UseLargePages ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); + if (!_bitmap_region_special) { + os::commit_memory_or_exit((char *) _bitmap_region.start(), bitmap_init_commit, bitmap_page_size, false, + "Cannot commit bitmap memory"); + } + + _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); if (ShenandoahVerify) { - ReservedSpace verify_bitmap(_bitmap_size, page_size); - os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), false, - "couldn't allocate verification bitmap"); + ReservedSpace verify_bitmap(_bitmap_size, bitmap_page_size); + if (!verify_bitmap.special()) { + os::commit_memory_or_exit(verify_bitmap.base(), verify_bitmap.size(), bitmap_page_size, false, + "Cannot commit verification bitmap memory"); + } MemTracker::record_virtual_memory_type(verify_bitmap.base(), mtGC); MemRegion verify_bitmap_region = MemRegion((HeapWord *) verify_bitmap.base(), verify_bitmap.size() / HeapWordSize); _verification_bit_map.initialize(_heap_region, verify_bitmap_region); _verifier = new ShenandoahVerifier(this, &_verification_bit_map); } - _marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap_region, _num_regions); + // Reserve aux bitmap for use in object_iterate(). We don't commit it here. + ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size); + MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC); + _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize); + _aux_bitmap_region_special = aux_bitmap.special(); + _aux_bit_map.initialize(_heap_region, _aux_bitmap_region); + + // + // Create regions and region sets + // + + _regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _num_regions, mtGC); + _free_set = new ShenandoahFreeSet(this, _num_regions); + _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)sh_rs.base()); { ShenandoahHeapLocker locker(lock()); + + size_t size_words = ShenandoahHeapRegion::region_size_words(); + for (size_t i = 0; i < _num_regions; i++) { - ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, - (HeapWord*) pgc_rs.base() + reg_size_words * i, - reg_size_words, - i, - i < num_committed_regions); + HeapWord* start = (HeapWord*)sh_rs.base() + size_words * i; + bool is_committed = i < num_committed_regions; + ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, start, size_words, i, is_committed); _marking_context->initialize_top_at_mark_start(r); _regions[i] = r; @@ -257,46 +278,43 @@ } if (ShenandoahAlwaysPreTouch) { - assert (!AlwaysPreTouch, "Should have been overridden"); + assert(!AlwaysPreTouch, "Should have been overridden"); // For NUMA, it is important to pre-touch the storage under bitmaps with worker threads, // before initialize() below zeroes it with initializing thread. For any given region, // we touch the region and the corresponding bitmaps from the same thread. ShenandoahPushWorkerScope scope(workers(), _max_workers, false); - log_info(gc, heap)("Parallel pretouch " SIZE_FORMAT " regions with " SIZE_FORMAT " byte pages", - _num_regions, page_size); - ShenandoahPretouchTask cl(bitmap0.base(), _bitmap_size, page_size); - _workers->run_task(&cl); + size_t pretouch_heap_page_size = heap_page_size; + size_t pretouch_bitmap_page_size = bitmap_page_size; + +#ifdef LINUX + // UseTransparentHugePages would madvise that backing memory can be coalesced into huge + // pages. But, the kernel needs to know that every small page is used, in order to coalesce + // them into huge one. Therefore, we need to pretouch with smaller pages. + if (UseTransparentHugePages) { + pretouch_heap_page_size = (size_t)os::vm_page_size(); + pretouch_bitmap_page_size = (size_t)os::vm_page_size(); + } +#endif + + // OS memory managers may want to coalesce back-to-back pages. Make their jobs + // simpler by pre-touching continuous spaces (heap and bitmap) separately. + + log_info(gc, init)("Pretouch bitmap: " SIZE_FORMAT " regions, " SIZE_FORMAT " bytes page", + _num_regions, pretouch_bitmap_page_size); + ShenandoahPretouchBitmapTask bcl(bitmap.base(), _bitmap_size, pretouch_bitmap_page_size); + _workers->run_task(&bcl); + + log_info(gc, init)("Pretouch heap: " SIZE_FORMAT " regions, " SIZE_FORMAT " bytes page", + _num_regions, pretouch_heap_page_size); + ShenandoahPretouchHeapTask hcl(pretouch_heap_page_size); + _workers->run_task(&hcl); } - // Reserve aux bitmap for use in object_iterate(). We don't commit it here. - ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size); - MemTracker::record_virtual_memory_type(aux_bitmap.base(), mtGC); - _aux_bitmap_region = MemRegion((HeapWord*) aux_bitmap.base(), aux_bitmap.size() / HeapWordSize); - _aux_bit_map.initialize(_heap_region, _aux_bitmap_region); - - _traversal_gc = heuristics()->can_do_traversal_gc() ? - new ShenandoahTraversalGC(this, _num_regions) : - NULL; - - _monitoring_support = new ShenandoahMonitoringSupport(this); - - _phase_timings = new ShenandoahPhaseTimings(); - - if (ShenandoahAllocationTrace) { - _alloc_tracker = new ShenandoahAllocTracker(); - } - - ShenandoahStringDedup::initialize(); - - _control_thread = new ShenandoahControlThread(); - - ShenandoahCodeRoots::initialize(); - - log_info(gc, init)("Safepointing mechanism: %s", - SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" : - (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown")); + // + // Initialize the rest of GC subsystems + // _liveness_cache = NEW_C_HEAP_ARRAY(jushort*, _max_workers, mtGC); for (uint worker = 0; worker < _max_workers; worker++) { @@ -304,6 +322,42 @@ Copy::fill_to_bytes(_liveness_cache[worker], _num_regions * sizeof(jushort)); } + // The call below uses stuff (the SATB* things) that are in G1, but probably + // belong into a shared location. + ShenandoahBarrierSet::satb_mark_queue_set().initialize(this, + SATB_Q_CBL_mon, + 20 /* G1SATBProcessCompletedThreshold */, + 60 /* G1SATBBufferEnqueueingThresholdPercent */); + + _monitoring_support = new ShenandoahMonitoringSupport(this); + _phase_timings = new ShenandoahPhaseTimings(); + ShenandoahStringDedup::initialize(); + ShenandoahCodeRoots::initialize(); + + if (ShenandoahAllocationTrace) { + _alloc_tracker = new ShenandoahAllocTracker(); + } + + if (ShenandoahPacing) { + _pacer = new ShenandoahPacer(this); + _pacer->setup_for_idle(); + } else { + _pacer = NULL; + } + + _traversal_gc = heuristics()->can_do_traversal_gc() ? + new ShenandoahTraversalGC(this, _num_regions) : + NULL; + + _control_thread = new ShenandoahControlThread(); + + log_info(gc, init)("Initialize Shenandoah heap with initial size " SIZE_FORMAT "%s", + byte_size_in_proper_unit(_initial_size), proper_unit_for_byte_size(_initial_size)); + + log_info(gc, init)("Safepointing mechanism: %s", + SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" : + (SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown")); + return JNI_OK; } @@ -361,6 +415,7 @@ _max_workers(MAX2(ConcGCThreads, ParallelGCThreads)), _workers(NULL), _safepoint_workers(NULL), + _heap_region_special(false), _num_regions(0), _regions(NULL), _update_refs_iterator(this), @@ -383,6 +438,12 @@ _soft_ref_policy(), _ref_processor(NULL), _marking_context(NULL), + _bitmap_size(0), + _bitmap_regions_per_slice(0), + _bitmap_bytes_per_slice(0), + _bitmap_region_special(false), + _aux_bitmap_region_special(false), + _liveness_cache(NULL), _collection_set(NULL) { log_info(gc, init)("GC threads: " UINT32_FORMAT " parallel, " UINT32_FORMAT " concurrent", ParallelGCThreads, ConcGCThreads); @@ -1267,7 +1328,7 @@ */ void ShenandoahHeap::object_iterate(ObjectClosure* cl) { assert(SafepointSynchronize::is_at_safepoint(), "safe iteration is only available during safepoints"); - if (!os::commit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size(), false)) { + if (!_aux_bitmap_region_special && !os::commit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size(), false)) { log_warning(gc)("Could not commit native memory for auxiliary marking bitmap for heap iteration"); return; } @@ -1294,7 +1355,7 @@ assert(oop_stack.is_empty(), "should be empty"); - if (!os::uncommit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size())) { + if (!_aux_bitmap_region_special && !os::uncommit_memory((char*)_aux_bitmap_region.start(), _aux_bitmap_region.byte_size())) { log_warning(gc)("Could not uncommit native memory for auxiliary marking bitmap for heap iteration"); } } @@ -2221,6 +2282,11 @@ bool ShenandoahHeap::commit_bitmap_slice(ShenandoahHeapRegion* r) { assert_heaplock_owned_by_current_thread(); + // Bitmaps in special regions do not need commits + if (_bitmap_region_special) { + return true; + } + if (is_bitmap_slice_committed(r, true)) { // Some other region from the group is already committed, meaning the bitmap // slice is already committed, we exit right away. @@ -2240,6 +2306,11 @@ bool ShenandoahHeap::uncommit_bitmap_slice(ShenandoahHeapRegion *r) { assert_heaplock_owned_by_current_thread(); + // Bitmaps in special regions do not need uncommits + if (_bitmap_region_special) { + return true; + } + if (is_bitmap_slice_committed(r, true)) { // Some other region from the group is still committed, meaning the bitmap // slice is should stay committed, exit right away. @@ -2768,6 +2839,7 @@ jushort* ShenandoahHeap::get_liveness_cache(uint worker_id) { #ifdef ASSERT + assert(_liveness_cache != NULL, "sanity"); assert(worker_id < _max_workers, "sanity"); for (uint i = 0; i < num_regions(); i++) { assert(_liveness_cache[worker_id][i] == 0, "liveness cache should be empty"); @@ -2778,6 +2850,7 @@ void ShenandoahHeap::flush_liveness_cache(uint worker_id) { assert(worker_id < _max_workers, "sanity"); + assert(_liveness_cache != NULL, "sanity"); jushort* ld = _liveness_cache[worker_id]; for (uint i = 0; i < num_regions(); i++) { ShenandoahHeapRegion* r = get_region(i); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -242,12 +242,14 @@ // private: MemRegion _heap_region; + bool _heap_region_special; size_t _num_regions; ShenandoahHeapRegion** _regions; ShenandoahRegionIterator _update_refs_iterator; public: inline size_t num_regions() const { return _num_regions; } + inline bool is_heap_region_special() { return _heap_region_special; } inline ShenandoahHeapRegion* const heap_region_containing(const void* addr) const; inline size_t heap_region_index_containing(const void* addr) const; @@ -486,7 +488,7 @@ ShenandoahFreeSet* free_set() const { return _free_set; } ShenandoahConcurrentMark* concurrent_mark() { return _scm; } ShenandoahTraversalGC* traversal_gc() { return _traversal_gc; } - ShenandoahPacer* pacer() const { return _pacer; } + ShenandoahPacer* pacer() const { return _pacer; } ShenandoahPhaseTimings* phase_timings() const { return _phase_timings; } ShenandoahAllocTracker* alloc_tracker() const { return _alloc_tracker; } @@ -649,6 +651,9 @@ size_t _bitmap_regions_per_slice; size_t _bitmap_bytes_per_slice; + bool _bitmap_region_special; + bool _aux_bitmap_region_special; + // Used for buffering per-region liveness data. // Needed since ShenandoahHeapRegion uses atomics to update liveness. // diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -56,7 +56,6 @@ ShenandoahHeapRegion::ShenandoahHeapRegion(ShenandoahHeap* heap, HeapWord* start, size_t size_words, size_t index, bool committed) : _heap(heap), - _pacer(ShenandoahPacing ? heap->pacer() : NULL), _reserved(MemRegion(start, size_words)), _region_number(index), _new_top(NULL), @@ -660,7 +659,7 @@ } void ShenandoahHeapRegion::do_commit() { - if (!os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) { + if (!_heap->is_heap_region_special() && !os::commit_memory((char *) _reserved.start(), _reserved.byte_size(), false)) { report_java_out_of_memory("Unable to commit region"); } if (!_heap->commit_bitmap_slice(this)) { @@ -670,7 +669,7 @@ } void ShenandoahHeapRegion::do_uncommit() { - if (!os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) { + if (!_heap->is_heap_region_special() && !os::uncommit_memory((char *) _reserved.start(), _reserved.byte_size())) { report_java_out_of_memory("Unable to uncommit region"); } if (!_heap->uncommit_bitmap_slice(this)) { diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -227,7 +227,6 @@ // Never updated fields ShenandoahHeap* _heap; - ShenandoahPacer* _pacer; MemRegion _reserved; size_t _region_number; diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -94,7 +94,7 @@ inline void ShenandoahHeapRegion::increase_live_data_gc_words(size_t s) { internal_increase_live_data(s); if (ShenandoahPacing) { - _pacer->report_mark(s); + _heap->pacer()->report_mark(s); } } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/oops/method.cpp --- a/src/hotspot/share/oops/method.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/oops/method.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -1684,35 +1684,11 @@ while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp(), st); } - -// Simple compression of line number tables. We use a regular compressed stream, except that we compress deltas -// between (bci,line) pairs since they are smaller. If (bci delta, line delta) fits in (5-bit unsigned, 3-bit unsigned) -// we save it as one byte, otherwise we write a 0xFF escape character and use regular compression. 0x0 is used -// as end-of-stream terminator. - -void CompressedLineNumberWriteStream::write_pair_regular(int bci_delta, int line_delta) { - // bci and line number does not compress into single byte. - // Write out escape character and use regular compression for bci and line number. - write_byte((jubyte)0xFF); - write_signed_int(bci_delta); - write_signed_int(line_delta); -} - -// See comment in method.hpp which explains why this exists. -#if defined(_M_AMD64) && _MSC_VER >= 1400 -#pragma optimize("", off) -void CompressedLineNumberWriteStream::write_pair(int bci, int line) { - write_pair_inline(bci, line); -} -#pragma optimize("", on) -#endif - CompressedLineNumberReadStream::CompressedLineNumberReadStream(u_char* buffer) : CompressedReadStream(buffer) { _bci = 0; _line = 0; }; - bool CompressedLineNumberReadStream::read_pair() { jubyte next = read_byte(); // Check for terminator diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/oops/method.hpp --- a/src/hotspot/share/oops/method.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/oops/method.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -1022,36 +1022,12 @@ // Write (bci, line number) pair to stream void write_pair_regular(int bci_delta, int line_delta); - inline void write_pair_inline(int bci, int line) { - int bci_delta = bci - _bci; - int line_delta = line - _line; - _bci = bci; - _line = line; - // Skip (0,0) deltas - they do not add information and conflict with terminator. - if (bci_delta == 0 && line_delta == 0) return; - // Check if bci is 5-bit and line number 3-bit unsigned. - if (((bci_delta & ~0x1F) == 0) && ((line_delta & ~0x7) == 0)) { - // Compress into single byte. - jubyte value = ((jubyte) bci_delta << 3) | (jubyte) line_delta; - // Check that value doesn't match escape character. - if (value != 0xFF) { - write_byte(value); - return; - } - } - write_pair_regular(bci_delta, line_delta); - } + // If (bci delta, line delta) fits in (5-bit unsigned, 3-bit unsigned) + // we save it as one byte, otherwise we write a 0xFF escape character + // and use regular compression. 0x0 is used as end-of-stream terminator. + void write_pair_inline(int bci, int line); -// Windows AMD64 + Apr 2005 PSDK with /O2 generates bad code for write_pair. -// Disabling optimization doesn't work for methods in header files -// so we force it to call through the non-optimized version in the .cpp. -// It's gross, but it's the only way we can ensure that all callers are -// fixed. _MSC_VER is defined by the windows compiler -#if defined(_M_AMD64) && _MSC_VER >= 1400 void write_pair(int bci, int line); -#else - void write_pair(int bci, int line) { write_pair_inline(bci, line); } -#endif // Write end-of-stream marker void write_terminator() { write_byte(0); } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/oops/method.inline.hpp --- a/src/hotspot/share/oops/method.inline.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/oops/method.inline.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -48,6 +48,39 @@ return OrderAccess::load_acquire(&_code); } +// Write (bci, line number) pair to stream +inline void CompressedLineNumberWriteStream::write_pair_regular(int bci_delta, int line_delta) { + // bci and line number does not compress into single byte. + // Write out escape character and use regular compression for bci and line number. + write_byte((jubyte)0xFF); + write_signed_int(bci_delta); + write_signed_int(line_delta); +} + +inline void CompressedLineNumberWriteStream::write_pair_inline(int bci, int line) { + int bci_delta = bci - _bci; + int line_delta = line - _line; + _bci = bci; + _line = line; + // Skip (0,0) deltas - they do not add information and conflict with terminator. + if (bci_delta == 0 && line_delta == 0) return; + // Check if bci is 5-bit and line number 3-bit unsigned. + if (((bci_delta & ~0x1F) == 0) && ((line_delta & ~0x7) == 0)) { + // Compress into single byte. + jubyte value = ((jubyte) bci_delta << 3) | (jubyte) line_delta; + // Check that value doesn't match escape character. + if (value != 0xFF) { + write_byte(value); + return; + } + } + write_pair_regular(bci_delta, line_delta); +} + +inline void CompressedLineNumberWriteStream::write_pair(int bci, int line) { + write_pair_inline(bci, line); +} + inline bool Method::has_compiled_code() const { return code() != NULL; } #endif // SHARE_OOPS_METHOD_INLINE_HPP diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/opto/arraycopynode.cpp --- a/src/hotspot/share/opto/arraycopynode.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/opto/arraycopynode.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, 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 @@ -160,7 +160,7 @@ void ArrayCopyNode::store(BarrierSetC2* bs, PhaseGVN *phase, Node*& ctl, MergeMemNode* mem, Node* adr, const TypePtr* adr_type, Node* val, const Type *type, BasicType bt) { DecoratorSet decorators = C2_WRITE_ACCESS | IN_HEAP | C2_ARRAY_COPY; if (is_alloc_tightly_coupled()) { - decorators |= C2_TIGHLY_COUPLED_ALLOC; + decorators |= C2_TIGHTLY_COUPLED_ALLOC; } C2AccessValuePtr addr(adr, adr_type); C2AccessValue value(val, type); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/opto/arraycopynode.hpp --- a/src/hotspot/share/opto/arraycopynode.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/opto/arraycopynode.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -47,7 +47,7 @@ static const char* _kind_names[CopyOfRange+1]; #endif // Is the alloc obtained with - // AllocateArrayNode::Ideal_array_allocation() tighly coupled + // AllocateArrayNode::Ideal_array_allocation() tightly coupled // (arraycopy follows immediately the allocation)? // We cache the result of LibraryCallKit::tightly_coupled_allocation // here because it's much easier to find whether there's a tightly diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/opto/library_call.cpp --- a/src/hotspot/share/opto/library_call.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/opto/library_call.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -4461,7 +4461,7 @@ return true; } -// If we have a tighly coupled allocation, the arraycopy may take care +// If we have a tightly coupled allocation, the arraycopy may take care // of the array initialization. If one of the guards we insert between // the allocation and the arraycopy causes a deoptimization, an // unitialized array will escape the compiled method. To prevent that diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/runtime/globals.hpp --- a/src/hotspot/share/runtime/globals.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/runtime/globals.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -367,7 +367,7 @@ "Print out every time compilation is longer than " \ "a given threshold") \ \ - develop(bool, SafepointALot, false, \ + diagnostic(bool, SafepointALot, false, \ "Generate a lot of safepoints. This works with " \ "GuaranteedSafepointInterval") \ \ diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/runtime/handshake.cpp --- a/src/hotspot/share/runtime/handshake.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/runtime/handshake.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -288,13 +288,14 @@ assert(Thread::current() == thread, "should call from thread"); assert(!thread->is_terminated(), "should not be a terminated thread"); - CautiouslyPreserveExceptionMark pem(thread); ThreadInVMForHandshake tivm(thread); if (!_semaphore.trywait()) { _semaphore.wait_with_safepoint_check(thread); } HandshakeOperation* op = OrderAccess::load_acquire(&_operation); if (op != NULL) { + HandleMark hm(thread); + CautiouslyPreserveExceptionMark pem(thread); // Disarm before execute the operation clear_handshake(thread); op->do_handshake(thread); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/runtime/os.hpp --- a/src/hotspot/share/runtime/os.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/runtime/os.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -463,6 +463,9 @@ static void pd_start_thread(Thread* thread); static void start_thread(Thread* thread); + // Returns true if successful. + static bool signal_thread(Thread* thread, int sig, const char* reason); + static void free_thread(OSThread* osthread); // thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit @@ -637,6 +640,7 @@ static void print_environment_variables(outputStream* st, const char** env_list); static void print_context(outputStream* st, const void* context); static void print_register_info(outputStream* st, const void* context); + static bool signal_sent_by_kill(const void* siginfo); static void print_siginfo(outputStream* st, const void* siginfo); static void print_signal_handlers(outputStream* st, char* buf, size_t buflen); static void print_date_and_time(outputStream* st, char* buf, size_t buflen); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/runtime/relocator.cpp --- a/src/hotspot/share/runtime/relocator.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/runtime/relocator.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -28,6 +28,7 @@ #include "memory/metadataFactory.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.hpp" +#include "oops/method.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/relocator.hpp" diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/runtime/safepoint.cpp --- a/src/hotspot/share/runtime/safepoint.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/runtime/safepoint.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -902,6 +902,16 @@ // To debug the long safepoint, specify both AbortVMOnSafepointTimeout & // ShowMessageBoxOnError. if (AbortVMOnSafepointTimeout) { + // Send the blocking thread a signal to terminate and write an error file. + for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) { + if (cur_thread->safepoint_state()->is_running()) { + if (!os::signal_thread(cur_thread, SIGILL, "blocking a safepoint")) { + break; // Could not send signal. Report fatal error. + } + // Give cur_thread a chance to report the error and terminate the VM. + os::sleep(Thread::current(), 3000, false); + } + } fatal("Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.", SafepointTimeoutDelay, VMThread::vm_operation()->name()); } diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/utilities/globalDefinitions_gcc.hpp --- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp Mon Mar 11 14:05:27 2019 +0530 @@ -269,6 +269,9 @@ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382 and // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53017 // -#define ATTRIBUTE_ALIGNED(x) __attribute__((aligned(x+0))) +// GCC versions older than 4.6.4 would fail even with "+0", and needs additional +// cast to typeof(x) to work around the similar bug. +// +#define ATTRIBUTE_ALIGNED(x) __attribute__((aligned((typeof(x))x+0))) #endif // SHARE_UTILITIES_GLOBALDEFINITIONS_GCC_HPP diff -r 48f2dc62ba77 -r 86ed45a9dedb src/hotspot/share/utilities/vmError.cpp --- a/src/hotspot/share/utilities/vmError.cpp Fri Mar 08 10:02:45 2019 +0530 +++ b/src/hotspot/share/utilities/vmError.cpp Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, 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 @@ -522,6 +522,9 @@ st->print("%s", buf); st->print(" (0x%x)", _id); // signal number st->print(" at pc=" PTR_FORMAT, p2i(_pc)); + if (_siginfo != NULL && os::signal_sent_by_kill(_siginfo)) { + st->print(" (sent by kill)"); + } } else { if (should_report_bug(_id)) { st->print("Internal Error"); diff -r 48f2dc62ba77 -r 86ed45a9dedb src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java --- a/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java Fri Mar 08 10:02:45 2019 +0530 +++ b/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java Mon Mar 11 14:05:27 2019 +0530 @@ -19,7 +19,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * * or visit www.oracle.com if you need additional information or have any * questions. */ diff -r 48f2dc62ba77 -r 86ed45a9dedb src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Mar 08 10:02:45 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Mar 11 14:05:27 2019 +0530 @@ -1174,7 +1174,7 @@ protected void read(Symbol sym, int attrLen) { ClassSymbol c = (ClassSymbol) sym; Name n = readName(nextChar()); - c.sourcefile = new SourceFileObject(n, c.flatname); + c.sourcefile = new SourceFileObject(n); // If the class is a toplevel class, originating from a Java source file, // but the class name does not match the file name, then it is // an auxiliary class. @@ -2950,11 +2950,9 @@ /** The file's name. */ private final Name name; - private final Name flatname; - public SourceFileObject(Name name, Name flatname) { + public SourceFileObject(Name name) { this.name = name; - this.flatname = flatname; } @Override @DefinedBy(Api.COMPILER) diff -r 48f2dc62ba77 -r 86ed45a9dedb src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java --- a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java Fri Mar 08 10:02:45 2019 +0530 +++ b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 diff -r 48f2dc62ba77 -r 86ed45a9dedb test/hotspot/jtreg/TEST.groups --- a/test/hotspot/jtreg/TEST.groups Fri Mar 08 10:02:45 2019 +0530 +++ b/test/hotspot/jtreg/TEST.groups Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2019, 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 @@ -265,6 +265,7 @@ -runtime/7158988/FieldMonitor.java \ -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \ -runtime/CommandLine/PrintGCApplicationConcurrentTime.java \ + -runtime/CompressedOops/UseCompressedOops.java \ -runtime/ConstantPool/IntfMethod.java \ -runtime/ErrorHandling/CreateCoredumpOnCrash.java \ -runtime/ErrorHandling/ErrorHandler.java \ @@ -346,6 +347,7 @@ runtime/ \ serviceability/ \ -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \ + -runtime/CompressedOops/UseCompressedOops.java \ -runtime/Thread/TestThreadDumpMonitorContention.java \ -runtime/containers/ \ -:tier1_runtime \ diff -r 48f2dc62ba77 -r 86ed45a9dedb test/hotspot/jtreg/compiler/runtime/safepoints/TestRegisterRestoring.java --- a/test/hotspot/jtreg/compiler/runtime/safepoints/TestRegisterRestoring.java Fri Mar 08 10:02:45 2019 +0530 +++ b/test/hotspot/jtreg/compiler/runtime/safepoints/TestRegisterRestoring.java Mon Mar 11 14:05:27 2019 +0530 @@ -26,8 +26,8 @@ * @bug 8148490 * @summary Test correct saving and restoring of vector registers at safepoints. * - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:-TieredCompilation - * -XX:+SafepointALot + * @run main/othervm -Xbatch -XX:-TieredCompilation + * -XX:+UnlockDiagnosticVMOptions -XX:+SafepointALot * -XX:CompileCommand=exclude,compiler.runtime.safepoints.TestRegisterRestoring::main * compiler.runtime.safepoints.TestRegisterRestoring */ diff -r 48f2dc62ba77 -r 86ed45a9dedb test/hotspot/jtreg/runtime/CompressedOops/UseCompressedOops.java --- a/test/hotspot/jtreg/runtime/CompressedOops/UseCompressedOops.java Fri Mar 08 10:02:45 2019 +0530 +++ b/test/hotspot/jtreg/runtime/CompressedOops/UseCompressedOops.java Mon Mar 11 14:05:27 2019 +0530 @@ -30,7 +30,7 @@ * java.management * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. UseCompressedOops + * @run main/othervm/timeout=480 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. UseCompressedOops */ import java.util.ArrayList; import java.util.Collections; diff -r 48f2dc62ba77 -r 86ed45a9dedb test/hotspot/jtreg/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java Mon Mar 11 14:05:27 2019 +0530 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2019, SAP SE. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.*; +import jdk.test.lib.process.*; + +/* + * @test TestAbortVMOnSafepointTimeout + * @summary Check if VM can kill thread which doesn't reach safepoint. + * @bug 8219584 + * @requires vm.compiler2.enabled + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + */ + +public class TestAbortVMOnSafepointTimeout { + + public static void main(String[] args) throws Exception { + if (args.length > 0) { + int result = test_loop(3); + System.out.println("This message would occur after some time with result " + result); + return; + } + + testWith(500, 500); + } + + static int test_loop(int x) { + int sum = 0; + if (x != 0) { + // Long running loop without safepoint. + for (int y = 1; y < Integer.MAX_VALUE; ++y) { + if (y % x == 0) ++sum; + } + } + return sum; + } + + public static void testWith(int sfpt_interval, int timeout_delay) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+SafepointTimeout", + "-XX:+SafepointALot", + "-XX:+AbortVMOnSafepointTimeout", + "-XX:SafepointTimeoutDelay=" + timeout_delay, + "-XX:GuaranteedSafepointInterval=" + sfpt_interval, + "-XX:-TieredCompilation", + "-XX:-UseCountedLoopSafepoints", + "-XX:LoopStripMiningIter=0", + "-XX:LoopUnrollLimit=0", + "-XX:CompileCommand=compileonly,TestAbortVMOnSafepointTimeout::test_loop", + "-Xcomp", + "-XX:-CreateCoredumpOnCrash", + "-Xms64m", + "TestAbortVMOnSafepointTimeout", + "runTestLoop" + ); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + if (Platform.isWindows()) { + output.shouldMatch("Safepoint sync time longer than"); + } else { + output.shouldMatch("SIGILL"); + if (Platform.isLinux()) { + output.shouldMatch("(sent by kill)"); + } + output.shouldMatch("TestAbortVMOnSafepointTimeout.test_loop"); + } + output.shouldNotHaveExitValue(0); + } +} diff -r 48f2dc62ba77 -r 86ed45a9dedb test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest --- a/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest Fri Mar 08 10:02:45 2019 +0530 +++ b/test/hotspot/jtreg/runtime/containers/docker/Dockerfile-BasicTest Mon Mar 11 14:05:27 2019 +0530 @@ -1,4 +1,4 @@ -FROM oraclelinux:7.2 +FROM oraclelinux:7.6 MAINTAINER mikhailo.seledtsov@oracle.com COPY /jdk /jdk diff -r 48f2dc62ba77 -r 86ed45a9dedb test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest --- a/test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest Fri Mar 08 10:02:45 2019 +0530 +++ b/test/jdk/jdk/internal/platform/docker/Dockerfile-BasicTest Mon Mar 11 14:05:27 2019 +0530 @@ -1,4 +1,4 @@ -FROM oraclelinux:7.2 +FROM oraclelinux:7.6 MAINTAINER mikhailo.seledtsov@oracle.com COPY /jdk /jdk diff -r 48f2dc62ba77 -r 86ed45a9dedb test/micro/org/openjdk/bench/java/lang/StringIndexOf.java --- a/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java Fri Mar 08 10:02:45 2019 +0530 +++ b/test/micro/org/openjdk/bench/java/lang/StringIndexOf.java Mon Mar 11 14:05:27 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, 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,6 +46,12 @@ private String shortSub1; private String data2; private String shortSub2; + private String string16Short; + private String string16Medium; + private String string16Long; + private char searchChar; + private char searchChar16; + private String searchString16; @Setup public void setup() { @@ -58,9 +64,122 @@ shortSub1 = "1"; data2 = "00001001010100a10110101010010101110101001110110101010010101010010000010111010101010101010a100010010101110111010101101010100010010a100a0010101111111000010101010010101000010101010010101010101110a10010101010101010101010101010"; shortSub2 = "a"; + searchChar = 's'; + + string16Short = "scar\u01fe1"; + string16Medium = "capaapapapasdkajdlkajskldjaslkjdlkasjdsalksca1r\u01fescar"; + string16Long = "2937489745890797905764956790452976742965790437698498409583479067ngdcapaapapapasdkajdlkajskldjaslkjdlkasjdsalkja1sscar\u01fescar"; + searchChar16 = 0x1fe; + searchString16 = "\u01fe"; + } + + + /** IndexOf Micros Chars */ + @Benchmark + public int searchCharLongSuccess() { + return dataStringBig.indexOf(searchChar); + } + + @Benchmark + public int searchCharMediumSuccess() { + return searchStringBig.indexOf(searchChar); + } + + @Benchmark + public int searchCharShortSuccess() { + return searchString.indexOf(searchChar); + } + + @Benchmark + public int searchChar16LongSuccess() { + return string16Long.indexOf(searchChar16); + } + + @Benchmark + public int searchChar16MediumSuccess() { + return string16Medium.indexOf(searchChar16); + } + + @Benchmark + public int searchChar16ShortSuccess() { + return string16Short.indexOf(searchChar16); + } + + @Benchmark + public int searchChar16LongWithOffsetSuccess() { + return string16Long.indexOf(searchChar16, 3); + } + + @Benchmark + public int searchChar16MediumWithOffsetSuccess() { + return string16Medium.indexOf(searchChar16, 3); + } + + @Benchmark + public int searchChar16ShortWithOffsetSuccess() { + return string16Short.indexOf(searchChar16, 2); } /** IndexOf Micros Strings */ + @Benchmark + public int searchString16LongLatinSuccess() { + return string16Long.indexOf(shortSub1); + } + + @Benchmark + public int searchString16MediumLatinSuccess() { + return string16Medium.indexOf(shortSub1); + } + + @Benchmark + public int searchString16ShortLatinSuccess() { + return string16Long.indexOf(shortSub2); + } + + @Benchmark + public int searchString16LongWithOffsetLatinSuccess() { + return string16Long.indexOf(shortSub1, 3); + } + + @Benchmark + public int searchString16MediumWithOffsetLatinSuccess() { + return string16Medium.indexOf(shortSub1, 3); + } + + @Benchmark + public int searchString16ShortWithOffsetLatinSuccess() { + return string16Short.indexOf(shortSub2, 1); + } + + @Benchmark + public int searchString16LongWithOffsetSuccess() { + return string16Long.indexOf(searchString16, 3); + } + + @Benchmark + public int searchString16MediumWithOffsetSuccess() { + return string16Medium.indexOf(searchString16, 3); + } + + @Benchmark + public int searchString16ShortWithOffsetSuccess() { + return string16Short.indexOf(searchString16, 2); + } + + @Benchmark + public int searchString16LongSuccess() { + return string16Long.indexOf(searchString16); + } + + @Benchmark + public int searchString16MediumSuccess() { + return string16Medium.indexOf(searchString16); + } + + @Benchmark + public int searchString16ShortSuccess() { + return string16Short.indexOf(searchString16); + } /** * Benchmarks String.indexOf with a rather small String to search and a rather small String to search for. The