Mercurial > hg > icedtea8-forest > hotspot
changeset 10765:9cc00eb32cbd icedtea-3.17.0pre02
Merge jdk8u272-b04
line wrap: on
line diff
--- a/.hgtags Fri Aug 28 07:38:21 2020 +0100 +++ b/.hgtags Sat Oct 24 01:11:49 2020 +0100 @@ -1395,7 +1395,16 @@ 545fe7caa2fb4a6dc4b4f9bba9556e30886ca1f1 jdk8u262-b03 3a3803a0c789c4d09fd53e54760e7bb7d704ca6e jdk8u262-b04 f7691a80458c365b5dd754b1e117818144ed30f1 jdk8u262-b05 +f7691a80458c365b5dd754b1e117818144ed30f1 jdk8u272-b00 de6565b66f9458fb97eb66483e48f159b3f39d36 jdk8u262-b06 d20a5f399218f58f82f4f4503d24957ce7e48e60 jdk8u262-b07 d2c2cd90513e48822648ff16016aa76577eb7ab1 jdk8u262-b08 cf6e3496e19a2957f7d8b28bd0a033cefbf6509f jdk8u262-b09 +1c6e1f187fdc571e5fb7eaf9ed0180ce6fe0a4a4 jdk8u262-b10 +1c6e1f187fdc571e5fb7eaf9ed0180ce6fe0a4a4 jdk8u262-ga +1c6e1f187fdc571e5fb7eaf9ed0180ce6fe0a4a4 jdk8u265-b00 +3bd5ac4488a39330ad5452b89ed98afac584ce59 jdk8u265-b01 +3bd5ac4488a39330ad5452b89ed98afac584ce59 jdk8u265-ga +85c9d74850ed3a6c99dd97c85d25ffb29afc0a28 jdk8u272-b01 +414c1dcfc3f3620b73cc7faf23f9a3ffde83b240 jdk8u272-b02 +e649f213636810823e761473ac871ce55a5235f7 jdk8u272-b03
--- a/THIRD_PARTY_README Fri Aug 28 07:38:21 2020 +0100 +++ b/THIRD_PARTY_README Sat Oct 24 01:11:49 2020 +0100 @@ -3028,8 +3028,7 @@ Apache Commons Math 3.2 Apache Derby 10.11.1.2 Apache Jakarta BCEL 5.1 - Apache Jakarta Regexp 1.4 - Apache Santuario XML Security for Java 1.5.4 + Apache Santuario XML Security for Java 2.1.1 Apache Xalan-Java 2.7.2 Apache Xerces Java 2.10.0 Apache XML Resolver 1.1
--- a/src/share/vm/c1/c1_GraphBuilder.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1705,6 +1705,23 @@ Value replacement = !needs_patching ? _memory->load(load) : load; if (replacement != load) { assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked"); + // Writing an (integer) value to a boolean, byte, char or short field includes an implicit narrowing + // conversion. Emit an explicit conversion here to get the correct field value after the write. + BasicType bt = field->type()->basic_type(); + switch (bt) { + case T_BOOLEAN: + case T_BYTE: + replacement = append(new Convert(Bytecodes::_i2b, replacement, as_ValueType(bt))); + break; + case T_CHAR: + replacement = append(new Convert(Bytecodes::_i2c, replacement, as_ValueType(bt))); + break; + case T_SHORT: + replacement = append(new Convert(Bytecodes::_i2s, replacement, as_ValueType(bt))); + break; + default: + break; + } push(type, replacement); } else { push(type, append(load)); @@ -2376,7 +2393,7 @@ if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) { assert(instruction->exception_state() == NULL || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState - || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()), + || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->should_retain_local_variables()), "exception_state should be of exception kind"); return new XHandlers(); } @@ -2467,7 +2484,7 @@ // This scope and all callees do not handle exceptions, so the local // variables of this scope are not needed. However, the scope itself is // required for a correct exception stack trace -> clear out the locals. - if (_compilation->env()->jvmti_can_access_local_variables()) { + if (_compilation->env()->should_retain_local_variables()) { cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); } else { cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci()); @@ -3353,7 +3370,7 @@ ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) { ValueStack* s = copy_state_exhandling_with_bci(bci); if (s == NULL) { - if (_compilation->env()->jvmti_can_access_local_variables()) { + if (_compilation->env()->should_retain_local_variables()) { s = state()->copy(ValueStack::ExceptionState, bci); } else { s = state()->copy(ValueStack::EmptyExceptionState, bci);
--- a/src/share/vm/c1/c1_Instruction.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/c1/c1_Instruction.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -76,7 +76,7 @@ void Instruction::update_exception_state(ValueStack* state) { if (state != NULL && (state->kind() == ValueStack::EmptyExceptionState || state->kind() == ValueStack::ExceptionState)) { - assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->jvmti_can_access_local_variables(), "unexpected state kind"); + assert(state->kind() == ValueStack::EmptyExceptionState || Compilation::current()->env()->should_retain_local_variables(), "unexpected state kind"); _exception_state = state; } else { _exception_state = NULL;
--- a/src/share/vm/c1/c1_ValueStack.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/c1/c1_ValueStack.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -52,7 +52,7 @@ , _stack() , _locks(copy_from->locks_size()) { - assert(kind != EmptyExceptionState || !Compilation::current()->env()->jvmti_can_access_local_variables(), "need locals"); + assert(kind != EmptyExceptionState || !Compilation::current()->env()->should_retain_local_variables(), "need locals"); if (kind != EmptyExceptionState) { // only allocate space if we need to copy the locals-array _locals = Values(copy_from->locals_size());
--- a/src/share/vm/c1/c1_ValueStack.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/c1/c1_ValueStack.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -75,7 +75,7 @@ void set_caller_state(ValueStack* s) { assert(kind() == EmptyExceptionState || - (Compilation::current()->env()->jvmti_can_access_local_variables() && kind() == ExceptionState), + (Compilation::current()->env()->should_retain_local_variables() && kind() == ExceptionState), "only EmptyExceptionStates can be modified"); _caller_state = s; }
--- a/src/share/vm/ci/ciEnv.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/ci/ciEnv.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -139,6 +139,11 @@ _ClassCastException_instance = NULL; _the_null_string = NULL; _the_min_jint_string = NULL; + + _jvmti_can_hotswap_or_post_breakpoint = false; + _jvmti_can_access_local_variables = false; + _jvmti_can_post_on_exceptions = false; + _jvmti_can_pop_frame = false; } ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) { @@ -189,6 +194,11 @@ _ClassCastException_instance = NULL; _the_null_string = NULL; _the_min_jint_string = NULL; + + _jvmti_can_hotswap_or_post_breakpoint = false; + _jvmti_can_access_local_variables = false; + _jvmti_can_post_on_exceptions = false; + _jvmti_can_pop_frame = false; } ciEnv::~ciEnv() { @@ -208,6 +218,31 @@ _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); + _jvmti_can_pop_frame = JvmtiExport::can_pop_frame(); +} + +bool ciEnv::should_retain_local_variables() const { + return _jvmti_can_access_local_variables || _jvmti_can_pop_frame; +} + +bool ciEnv::jvmti_state_changed() const { + if (!_jvmti_can_access_local_variables && + JvmtiExport::can_access_local_variables()) { + return true; + } + if (!_jvmti_can_hotswap_or_post_breakpoint && + JvmtiExport::can_hotswap_or_post_breakpoint()) { + return true; + } + if (!_jvmti_can_post_on_exceptions && + JvmtiExport::can_post_on_exceptions()) { + return true; + } + if (!_jvmti_can_pop_frame && + JvmtiExport::can_pop_frame()) { + return true; + } + return false; } // ------------------------------------------------------------------ @@ -953,13 +988,7 @@ No_Safepoint_Verifier nsv; // Change in Jvmti state may invalidate compilation. - if (!failing() && - ( (!jvmti_can_hotswap_or_post_breakpoint() && - JvmtiExport::can_hotswap_or_post_breakpoint()) || - (!jvmti_can_access_local_variables() && - JvmtiExport::can_access_local_variables()) || - (!jvmti_can_post_on_exceptions() && - JvmtiExport::can_post_on_exceptions()) )) { + if (!failing() && jvmti_state_changed()) { record_failure("Jvmti state change invalidated dependencies"); }
--- a/src/share/vm/ci/ciEnv.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/ci/ciEnv.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -69,6 +69,7 @@ bool _jvmti_can_hotswap_or_post_breakpoint; bool _jvmti_can_access_local_variables; bool _jvmti_can_post_on_exceptions; + bool _jvmti_can_pop_frame; // Cache DTrace flags bool _dtrace_extended_probes; @@ -336,8 +337,9 @@ // Cache Jvmti state void cache_jvmti_state(); + bool jvmti_state_changed() const; + bool should_retain_local_variables() const; bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; } - bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; } bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions; } // Cache DTrace flags
--- a/src/share/vm/ci/ciMethod.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/ci/ciMethod.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -415,7 +415,7 @@ // information. MethodLivenessResult ciMethod::liveness_at_bci(int bci) { MethodLivenessResult result = raw_liveness_at_bci(bci); - if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) { + if (CURRENT_ENV->should_retain_local_variables() || DeoptimizeALot || CompileTheWorld) { // Keep all locals live for the user's edification and amusement. result.at_put_range(0, result.size(), true); }
--- a/src/share/vm/classfile/classFileParser.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/classFileParser.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -3717,6 +3717,16 @@ info->has_nonstatic_fields = has_nonstatic_fields; } +static bool relax_format_check_for(ClassLoaderData* loader_data) { + bool trusted = (loader_data->is_the_null_class_loader_data() || + SystemDictionary::is_ext_class_loader(loader_data->class_loader())); + bool need_verify = + // verifyAll + (BytecodeVerificationLocal && BytecodeVerificationRemote) || + // verifyRemote + (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted); + return !need_verify; +} instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, ClassLoaderData* loader_data, @@ -3863,7 +3873,7 @@ // Check if verification needs to be relaxed for this class file // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376) - _relax_verify = Verifier::relax_verify_for(class_loader()); + _relax_verify = relax_format_check_for(_loader_data); // Constant pool constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
--- a/src/share/vm/classfile/javaClasses.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/javaClasses.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1235,6 +1235,16 @@ } +// Return Symbol for detailed_message or NULL +Symbol* java_lang_Throwable::detail_message(oop throwable) { + PRESERVE_EXCEPTION_MARK; // Keep original exception + oop detailed_message = java_lang_Throwable::message(throwable); + if (detailed_message != NULL) { + return java_lang_String::as_symbol(detailed_message, THREAD); + } + return NULL; +} + void java_lang_Throwable::set_message(oop throwable, oop value) { throwable->obj_field_put(detailMessage_offset, value); }
--- a/src/share/vm/classfile/javaClasses.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/javaClasses.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -518,6 +518,7 @@ static oop message(oop throwable); static oop message(Handle throwable); static void set_message(oop throwable, oop value); + static Symbol* detail_message(oop throwable); static void print_stack_element(outputStream *st, Handle mirror, int method, int version, int bci, int cpref); static void print_stack_element(outputStream *st, methodHandle method, int bci);
--- a/src/share/vm/classfile/resolutionErrors.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/resolutionErrors.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -32,12 +32,13 @@ // add new entry to the table void ResolutionErrorTable::add_entry(int index, unsigned int hash, - constantPoolHandle pool, int cp_index, Symbol* error) + constantPoolHandle pool, int cp_index, + Symbol* error, Symbol* message) { assert_locked_or_safepoint(SystemDictionary_lock); assert(!pool.is_null() && error != NULL, "adding NULL obj"); - ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error); + ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error, message); add_entry(index, entry); } @@ -58,19 +59,26 @@ } void ResolutionErrorEntry::set_error(Symbol* e) { - assert(e == NULL || _error == NULL, "cannot reset error"); + assert(e != NULL, "must set a value"); _error = e; - if (_error != NULL) _error->increment_refcount(); + _error->increment_refcount(); +} + +void ResolutionErrorEntry::set_message(Symbol* c) { + assert(c != NULL, "must set a value"); + _message = c; + _message->increment_refcount(); } // create new error entry ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, - int cp_index, Symbol* error) + int cp_index, Symbol* error, + Symbol* message) { ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool); entry->set_cp_index(cp_index); - NOT_PRODUCT(entry->set_error(NULL);) entry->set_error(error); + entry->set_message(message); return entry; } @@ -79,6 +87,7 @@ // decrement error refcount assert(entry->error() != NULL, "error should be set"); entry->error()->decrement_refcount(); + entry->message()->decrement_refcount(); Hashtable<ConstantPool*, mtClass>::free_entry(entry); }
--- a/src/share/vm/classfile/resolutionErrors.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/resolutionErrors.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -38,7 +38,8 @@ public: ResolutionErrorTable(int table_size); - ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error); + ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, + Symbol* error, Symbol* message); void free_entry(ResolutionErrorEntry *entry); ResolutionErrorEntry* bucket(int i) { @@ -55,7 +56,7 @@ } void add_entry(int index, unsigned int hash, - constantPoolHandle pool, int which, Symbol* error); + constantPoolHandle pool, int which, Symbol* error, Symbol* message); // find error given the constant pool and constant pool index @@ -79,10 +80,10 @@ private: int _cp_index; Symbol* _error; + Symbol* _message; public: - ConstantPool* pool() const { return (ConstantPool*)literal(); } - ConstantPool** pool_addr() { return (ConstantPool**)literal_addr(); } + ConstantPool* pool() const { return literal(); } int cp_index() const { return _cp_index; } void set_cp_index(int cp_index) { _cp_index = cp_index; } @@ -90,6 +91,9 @@ Symbol* error() const { return _error; } void set_error(Symbol* e); + Symbol* message() const { return _message; } + void set_message(Symbol* c); + ResolutionErrorEntry* next() const { return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next(); }
--- a/src/share/vm/classfile/systemDictionary.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/systemDictionary.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -185,12 +185,14 @@ if (HAS_PENDING_EXCEPTION || klass == NULL) { KlassHandle k_h(THREAD, klass); // can return a null klass - klass = handle_resolution_exception(class_name, class_loader, protection_domain, throw_error, k_h, THREAD); + klass = handle_resolution_exception(class_name, throw_error, k_h, THREAD); } return klass; } -Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS) { +Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, + bool throw_error, + KlassHandle klass_h, TRAPS) { if (HAS_PENDING_EXCEPTION) { // If we have a pending exception we forward it to the caller, unless throw_error is true, // in which case we have to check whether the pending exception is a ClassNotFoundException, @@ -398,7 +400,7 @@ } if (HAS_PENDING_EXCEPTION || superk_h() == NULL) { // can null superk - superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, class_loader, protection_domain, true, superk_h, THREAD)); + superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, true, superk_h, THREAD)); } return superk_h(); @@ -2246,12 +2248,13 @@ // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed. -void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) { +void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, + Symbol* error, Symbol* message) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { MutexLocker ml(SystemDictionary_lock, Thread::current()); - resolution_errors()->add_entry(index, hash, pool, which, error); + resolution_errors()->add_entry(index, hash, pool, which, error, message); } } @@ -2261,13 +2264,19 @@ } // Lookup resolution error table. Returns error if found, otherwise NULL. -Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) { +Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which, + Symbol** message) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { MutexLocker ml(SystemDictionary_lock, Thread::current()); ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); - return (entry != NULL) ? entry->error() : (Symbol*)NULL; + if (entry != NULL) { + *message = entry->message(); + return entry->error(); + } else { + return NULL; + } } }
--- a/src/share/vm/classfile/systemDictionary.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -241,7 +241,7 @@ static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS); protected: // handle error translation for resolve_or_null results - static Klass* handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS); + static Klass* handle_resolution_exception(Symbol* class_name, bool throw_error, KlassHandle klass_h, TRAPS); public: @@ -549,9 +549,11 @@ // Record the error when the first attempt to resolve a reference from a constant // pool entry to a class fails. - static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error); + static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error, + Symbol* message); static void delete_resolution_error(ConstantPool* pool); - static Symbol* find_resolution_error(constantPoolHandle pool, int which); + static Symbol* find_resolution_error(constantPoolHandle pool, int which, + Symbol** message); protected:
--- a/src/share/vm/classfile/verifier.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/verifier.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -101,7 +101,7 @@ BytecodeVerificationLocal : BytecodeVerificationRemote; } -bool Verifier::relax_verify_for(oop loader) { +bool Verifier::relax_access_for(oop loader) { bool trusted = java_lang_ClassLoader::is_trusted_loader(loader); bool need_verify = // verifyAll
--- a/src/share/vm/classfile/verifier.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/classfile/verifier.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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 @@ -57,8 +57,8 @@ // -Xverify:all/none override this value static bool should_verify_for(oop class_loader, bool should_verify_class); - // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2. - static bool relax_verify_for(oop class_loader); + // Relax certain access checks to enable some broken 1.1 apps to run on 1.2. + static bool relax_access_for(oop class_loader); private: static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, 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 @@ -994,6 +994,10 @@ return res; } } else { + // The barrier is required to prevent reordering of the free chunk check + // and the klass read. + OrderAccess::loadload(); + // must read from what 'p' points to in each loop. Klass* k = ((volatile oopDesc*)p)->klass_or_null(); if (k != NULL) { @@ -1049,6 +1053,10 @@ return res; } } else { + // The barrier is required to prevent reordering of the free chunk check + // and the klass read. + OrderAccess::loadload(); + // must read from what 'p' points to in each loop. Klass* k = ((volatile oopDesc*)p)->klass_or_null(); // We trust the size of any object that has a non-NULL @@ -1111,6 +1119,11 @@ // assert(CollectedHeap::use_parallel_gc_threads() || _bt.block_start(p) == p, // "Should be a block boundary"); if (FreeChunk::indicatesFreeChunk(p)) return false; + + // The barrier is required to prevent reordering of the free chunk check + // and the klass read. + OrderAccess::loadload(); + Klass* k = oop(p)->klass_or_null(); if (k != NULL) { // Ignore mark word because it may have been used to
--- a/src/share/vm/interpreter/interpreterRuntime.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -450,9 +450,18 @@ // tracing if (TraceExceptions) { - ttyLocker ttyl; ResourceMark rm(thread); - tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", h_exception->print_value_string(), (address)h_exception()); + Symbol* message = java_lang_Throwable::detail_message(h_exception()); + ttyLocker ttyl; // Lock after getting the detail message + if (message != NULL) { + tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")", + h_exception->print_value_string(), message->as_C_string(), + (address)h_exception()); + } else { + tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", + h_exception->print_value_string(), + (address)h_exception()); + } tty->print_cr(" thrown in interpreter method <%s>", h_method->print_value_string()); tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, thread); }
--- a/src/share/vm/jfr/jni/jfrJavaSupport.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/jni/jfrJavaSupport.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -574,10 +574,6 @@ return _cause; } -// XXX -//const char* const JDK_JFR_MODULE_NAME = "jdk.jfr"; -//const char* const JDK_JFR_PACKAGE_NAME = "jdk/jfr"; - jlong JfrJavaSupport::jfr_thread_id(jobject target_thread) { // ThreadsListHandle tlh; // XXX is it correct and safe?
--- a/src/share/vm/jfr/metadata/metadata.xml Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/metadata/metadata.xml Sat Oct 24 01:11:49 2020 +0100 @@ -725,19 +725,6 @@ <Field type="ulong" contentType="address" name="topAddress" label="Top Address" description="Ending address of the module" /> </Event> - <!-- XXX - <Event name="ModuleRequire" category="Java Virtual Machine, Runtime, Modules" label="Module Require" thread="false" period="everyChunk" - description="A directed edge representing a dependency"> - <Field type="Module" name="source" label="Source Module" /> - <Field type="Module" name="requiredModule" label="Required Module" /> - </Event> - - <Event name="ModuleExport" category="Java Virtual Machine, Runtime, Modules" label="Module Export" thread="false" period="everyChunk"> - <Field type="Package" name="exportedPackage" label="Exported Package" /> - <Field type="Module" name="targetModule" label="Target Module" - description="Module to which the package is qualifiedly exported. If null or N/A, the package is unqualifiedly exported" /> - </Event> - --> <Event name="CompilerStatistics" category="Java Virtual Machine, Compiler" label="Compiler Statistics" thread="false" period="everyChunk" startTime="false"> <Field type="int" name="compileCount" label="Compiled Methods" /> <Field type="int" name="bailoutCount" label="Bailouts" /> @@ -1032,18 +1019,8 @@ <Field type="string" name="cause" label="Cause" /> </Type> - <!-- - <Type name="Module" label="Module"> - <Field type="Symbol" name="name" label="Name" /> - <Field type="Symbol" name="version" label="Version" /> - <Field type="Symbol" name="location" label="Location" /> - <Field type="ClassLoader" name="classLoader" label="Class Loader" /> - </Type> - --> - <Type name="Package" label="Package"> <Field type="Symbol" name="name" label="Name" /> - <!-- <Field type="Module" name="module" label="Module" /> --> <Field type="boolean" name="exported" label="Exported" /> </Type> @@ -1107,7 +1084,6 @@ <Relation name="CompileId" /> <Relation name="SweepId"/> - <XmlType name="Package" parameterType="const PackageEntry*" fieldType="const PackageEntry*"/> <XmlType name="Class" javaType="java.lang.Class" parameterType="const Klass*" fieldType="const Klass*"/> <XmlType name="ClassLoader" parameterType="const ClassLoaderData*" fieldType="const ClassLoaderData*"/> <XmlType name="Method" parameterType="const Method*" fieldType="const Method*"/>
--- a/src/share/vm/jfr/periodic/jfrThreadCPULoadEvent.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/periodic/jfrThreadCPULoadEvent.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -86,15 +86,14 @@ // Avoid reporting percentages above the theoretical max if (user_time + system_time > wallclock_time) { jlong excess = user_time + system_time - wallclock_time; + cur_cpu_time -= excess; if (user_time > excess) { user_time -= excess; cur_user_time -= excess; - cur_cpu_time -= excess; } else { - cur_cpu_time -= excess; excess -= user_time; + cur_user_time -= user_time; user_time = 0; - cur_user_time = 0; system_time -= excess; } }
--- a/src/share/vm/jfr/periodic/sampling/jfrCallTrace.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/periodic/sampling/jfrCallTrace.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -27,6 +27,7 @@ #include "code/nmethod.hpp" #include "code/pcDesc.hpp" #include "jfr/periodic/sampling/jfrCallTrace.hpp" +#include "jfr/utilities/jfrTypes.hpp" #include "oops/method.hpp" #include "runtime/javaCalls.hpp" #include "runtime/frame.inline.hpp" @@ -37,7 +38,7 @@ assert(top_frame.cb() != NULL, "invariant"); RegisterMap map(_thread, false); frame candidate = top_frame; - for (int i = 0; i < MaxJavaStackTraceDepth * 2; ++i) { + for (u4 i = 0; i < MAX_STACK_DEPTH * 2; ++i) { if (candidate.is_entry_frame()) { JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(_thread); if (jcw == NULL || jcw->is_first_frame()) {
--- a/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -494,8 +494,8 @@ last_native_ms = last_java_ms; } _sample.signal(); - jlong java_interval = _interval_java == 0 ? max_jlong : MAX2<jlong>(_interval_java, 10); - jlong native_interval = _interval_native == 0 ? max_jlong : MAX2<jlong>(_interval_native, 10); + jlong java_interval = _interval_java == 0 ? max_jlong : MAX2<jlong>(_interval_java, 1); + jlong native_interval = _interval_native == 0 ? max_jlong : MAX2<jlong>(_interval_native, 1); jlong now_ms = get_monotonic_ms();
--- a/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -44,13 +44,13 @@ } } -static void write_checkpoint_header(u1* pos, jlong size, jlong time, bool flushpoint, juint type_count) { +static void write_checkpoint_header(u1* pos, int64_t size, jlong time, bool flushpoint, u4 type_count) { assert(pos != NULL, "invariant"); JfrBigEndianWriter be_writer(pos, sizeof(JfrCheckpointEntry)); be_writer.write(size); be_writer.write(time); be_writer.write(JfrTicks::now().value() - time); - be_writer.write(flushpoint ? (juint)1 : (juint)0); + be_writer.write(flushpoint ? (u4)1 : (u4)0); be_writer.write(type_count); assert(be_writer.is_valid(), "invariant"); } @@ -71,7 +71,7 @@ assert(this->is_valid(), "invariant"); assert(count() > 0, "invariant"); assert(this->used_size() > sizeof(JfrCheckpointEntry), "invariant"); - const jlong size = this->current_offset(); + const int64_t size = this->current_offset(); assert(size + this->start_pos() == this->current_pos(), "invariant"); write_checkpoint_header(const_cast<u1*>(this->start_pos()), size, _time, is_flushpoint(), count()); release(); @@ -85,11 +85,11 @@ return _flushpoint; } -juint JfrCheckpointWriter::count() const { +u4 JfrCheckpointWriter::count() const { return _count; } -void JfrCheckpointWriter::set_count(juint count) { +void JfrCheckpointWriter::set_count(u4 count) { _count = count; } @@ -111,7 +111,7 @@ } void JfrCheckpointWriter::write_key(u8 key) { - write<u8>(key); + write(key); } void JfrCheckpointWriter::increment() { @@ -119,10 +119,10 @@ } void JfrCheckpointWriter::write_count(u4 nof_entries) { - write<u4>((u4)nof_entries); + write(nof_entries); } -void JfrCheckpointWriter::write_count(u4 nof_entries, jlong offset) { +void JfrCheckpointWriter::write_count(u4 nof_entries, int64_t offset) { write_padded_at_offset(nof_entries, offset); }
--- a/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -49,21 +49,21 @@ typedef EventWriterHost<BigEndianEncoder, CompressedIntegerEncoder, JfrTransactionalCheckpointWriter> JfrCheckpointWriterBase; struct JfrCheckpointContext { - jlong offset; - juint count; + int64_t offset; + u4 count; }; class JfrCheckpointWriter : public JfrCheckpointWriterBase { friend class JfrSerializerRegistration; private: JfrTicks _time; - jlong _offset; - juint _count; + int64_t _offset; + u4 _count; bool _flushpoint; bool _header; - juint count() const; - void set_count(juint count); + u4 count() const; + void set_count(u4 count); void increment(); void set_flushpoint(bool flushpoint); bool is_flushpoint() const; @@ -75,7 +75,7 @@ ~JfrCheckpointWriter(); void write_type(JfrTypeId type_id); void write_count(u4 nof_entries); - void write_count(u4 nof_entries, jlong offset); + void write_count(u4 nof_entries, int64_t offset); void write_key(u8 key); const JfrCheckpointContext context() const; void set_context(const JfrCheckpointContext ctx);
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -64,7 +64,7 @@ private: JfrCheckpointWriter& _writer; JfrCheckpointContext _ctx; - const intptr_t _count_position; + const int64_t _count_position; Thread* const _curthread; u4 _count;
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.hpp" -// XXX #include "classfile/packageEntry.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "jfr/jfr.hpp" @@ -55,7 +54,6 @@ #define CREATE_PACKAGE_ID(pkg_id) (((u8)((checkpoint_id << 24) | pkg_id))) typedef const Klass* KlassPtr; -// XXX typedef const PackageEntry* PkgPtr; typedef const ClassLoaderData* CldPtr; typedef const Method* MethodPtr; typedef const Symbol* SymbolPtr; @@ -87,11 +85,6 @@ static void tag_leakp_klass_artifacts(KlassPtr k, bool class_unload) { assert(k != NULL, "invariant"); - // XXX - // PkgPtr pkg = k->package(); - // if (pkg != NULL) { - // tag_leakp_artifact(pkg, class_unload); - // } CldPtr cld = k->class_loader_data(); assert(cld != NULL, "invariant"); if (!cld->is_anonymous()) { @@ -295,7 +288,6 @@ UniquePredicate<traceid, _compare_traceid_> _unique_predicate; int klass_symbols(KlassPtr klass); -// XXX int package_symbols(PkgPtr pkg); int class_loader_symbols(CldPtr cld); int method_symbols(KlassPtr klass); @@ -315,11 +307,6 @@ int count = 0; if (_predicate(klass)) { count += klass_symbols(klass); - // XXX - // PkgPtr pkg = klass->package(); - // if (pkg != NULL) { - // count += package_symbols(pkg); - // } CldPtr cld = klass->class_loader_data(); assert(cld != NULL, "invariant"); if (!cld->is_anonymous()) { @@ -349,52 +336,6 @@ return _unique_predicate(entry->id()) ? write__artifact__symbol__entry__(this->_writer, entry) : 0; } -// XXX -// template <template <typename> class Predicate> -// int KlassSymbolWriterImpl<Predicate>::package_symbols(PkgPtr pkg) { -// assert(pkg != NULL, "invariant"); -// SymbolPtr pkg_name = pkg->name(); -// assert(pkg_name != NULL, "invariant"); -// SymbolEntryPtr package_symbol = this->_artifacts->map_symbol(pkg_name); -// assert(package_symbol != NULL, "invariant"); -// return _unique_predicate(package_symbol->id()) ? -// write__artifact__symbol__entry__(this->_writer, package_symbol) : 0; -// } - -// XXX -// template <template <typename> class Predicate> -// int KlassSymbolWriterImpl<Predicate>::module_symbols(ModPtr module) { -// assert(module != NULL, "invariant"); -// assert(module->is_named(), "invariant"); -// int count = 0; -// SymbolPtr sym = module->name(); -// SymbolEntryPtr entry = NULL; -// if (sym != NULL) { -// entry = this->_artifacts->map_symbol(sym); -// assert(entry != NULL, "invariant"); -// if (_unique_predicate(entry->id())) { -// count += write__artifact__symbol__entry__(this->_writer, entry); -// } -// } -// sym = module->version(); -// if (sym != NULL) { -// entry = this->_artifacts->map_symbol(sym); -// assert(entry != NULL, "invariant"); -// if (_unique_predicate(entry->id())) { -// count += write__artifact__symbol__entry__(this->_writer, entry); -// } -// } -// sym = module->location(); -// if (sym != NULL) { -// entry = this->_artifacts->map_symbol(sym); -// assert(entry != NULL, "invariant"); -// if (_unique_predicate(entry->id())) { -// count += write__artifact__symbol__entry__(this->_writer, entry); -// } -// } -// return count; -// } - template <template <typename> class Predicate> int KlassSymbolWriterImpl<Predicate>::class_loader_symbols(CldPtr cld) { assert(cld != NULL, "invariant"); @@ -712,30 +653,6 @@ ClassLoaderDataGraph::classes_do(&do_klass); } -// XXX -// void JfrTypeSet::do_unloaded_package(PackageEntry* entry) { -// assert(entry != NULL, "invariant"); -// assert(_subsystem_callback != NULL, "invariant"); -// if (ANY_USED_THIS_EPOCH(entry)) { // includes leakp subset -// _subsystem_callback->do_artifact(entry); -// } -// } - -// void JfrTypeSet::do_package(PackageEntry* entry) { -// assert(_subsystem_callback != NULL, "invariant"); -// if (ANY_USED_PREV_EPOCH(entry)) { // includes leakp subset -// _subsystem_callback->do_artifact(entry); -// } -// } - -// void JfrTypeSet::do_packages() { -// if (_class_unload) { -// ClassLoaderDataGraph::packages_unloading_do(&do_unloaded_package); -// return; -// } -// ClassLoaderDataGraph::packages_do(&do_package); -// } - void JfrTypeSet::do_unloaded_class_loader_data(ClassLoaderData* cld) { assert(_subsystem_callback != NULL, "invariant"); if (ANY_USED_THIS_EPOCH(cld)) { // includes leakp subset
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -33,8 +33,6 @@ class JfrCheckpointWriter; class Klass; -// XXX class PackageEntry; - class JfrTypeSet : AllStatic { friend class CLDCallback; friend class JfrTypeManager; @@ -48,11 +46,6 @@ static void do_unloaded_klass(Klass* k); static void do_klasses(); - // XXX - // static void do_package(PackageEntry* entry); - // static void do_unloaded_package(PackageEntry* entry); - // static void do_packages(); - static void do_class_loader_data(ClassLoaderData* cld); static void do_unloaded_class_loader_data(ClassLoaderData* cld); static void do_class_loaders();
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetWriter.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -35,7 +35,7 @@ WriterImpl _impl; JfrCheckpointWriter* _writer; JfrCheckpointContext _ctx; - jlong _count_offset; + int64_t _count_offset; int _count; bool _skip_header; public:
--- a/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -61,12 +61,6 @@ #endif } -// XXX -// static traceid next_package_id() { -// static volatile traceid package_id_counter = 1; -// return atomic_inc(&package_id_counter) << TRACE_ID_SHIFT; -// } - static traceid next_class_loader_data_id() { static volatile traceid cld_id_counter = 1; return atomic_inc(&cld_id_counter) << TRACE_ID_SHIFT; @@ -104,12 +98,6 @@ } } -// XXX -// void JfrTraceId::assign(const PackageEntry* package) { -// assert(package != NULL, "invariant"); -// package->set_trace_id(next_package_id()); -// } - void JfrTraceId::assign(const ClassLoaderData* cld) { assert(cld != NULL, "invariant"); if (cld->is_anonymous()) {
--- a/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -32,7 +32,6 @@ class ClassLoaderData; class Klass; class Method; -// XXX class PackageEntry; class Thread; /* @@ -54,7 +53,6 @@ * * Klass (includes Method) * ClassLoaderData - * XXX PackageEntry * * These classes have been extended to include a _traceid field (64-bits). * @@ -78,7 +76,6 @@ class JfrTraceId : public AllStatic { public: static void assign(const Klass* klass); - // XXX static void assign(const PackageEntry* package); static void assign(const ClassLoaderData* cld); static traceid assign_thread_id(); @@ -90,7 +87,6 @@ static traceid use(const Klass* klass, bool leakp = false); static traceid use(jclass jc, bool leakp = false); static traceid use(const Method* method, bool leakp = false); - // XXX static traceid use(const PackageEntry* package, bool leakp = false); static traceid use(const ClassLoaderData* cld, bool leakp = false); static void remove(const Klass* klass);
--- a/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -82,12 +82,6 @@ return (METHOD_ID(klass, method)); } -// XXX -//inline traceid JfrTraceId::use(const PackageEntry* package, bool leakp /* false */) { -// assert(package != NULL, "invariant"); -// return set_used_and_get_shifted(package, leakp); -//} - inline traceid JfrTraceId::use(const ClassLoaderData* cld, bool leakp /* false */) { assert(cld != NULL, "invariant"); return cld->is_anonymous() ? 0 : set_used_and_get_shifted(cld, leakp);
--- a/src/share/vm/jfr/recorder/repository/jfrChunkState.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkState.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -52,19 +52,19 @@ set_previous_checkpoint_offset(0); } -void JfrChunkState::set_previous_checkpoint_offset(jlong offset) { +void JfrChunkState::set_previous_checkpoint_offset(int64_t offset) { _previous_checkpoint_offset = offset; } -jlong JfrChunkState::previous_checkpoint_offset() const { +int64_t JfrChunkState::previous_checkpoint_offset() const { return _previous_checkpoint_offset; } -jlong JfrChunkState::previous_start_ticks() const { +int64_t JfrChunkState::previous_start_ticks() const { return _previous_start_ticks; } -jlong JfrChunkState::previous_start_nanos() const { +int64_t JfrChunkState::previous_start_nanos() const { return _previous_start_nanos; } @@ -91,7 +91,7 @@ save_current_and_update_start_ticks(); } -jlong JfrChunkState::last_chunk_duration() const { +int64_t JfrChunkState::last_chunk_duration() const { return _start_nanos - _previous_start_nanos; }
--- a/src/share/vm/jfr/recorder/repository/jfrChunkState.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkState.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -25,7 +25,6 @@ #ifndef SHARE_VM_JFR_RECORDER_REPOSITORY_JFRRCHUNKSTATE_HPP #define SHARE_VM_JFR_RECORDER_REPOSITORY_JFRRCHUNKSTATE_HPP -#include "jni.h" #include "jfr/utilities/jfrAllocation.hpp" #include "jfr/utilities/jfrTypes.hpp" @@ -33,11 +32,11 @@ friend class JfrChunkWriter; private: char* _path; - jlong _start_ticks; - jlong _start_nanos; - jlong _previous_start_ticks; - jlong _previous_start_nanos; - jlong _previous_checkpoint_offset; + int64_t _start_ticks; + int64_t _start_nanos; + int64_t _previous_start_ticks; + int64_t _previous_start_nanos; + int64_t _previous_checkpoint_offset; void update_start_ticks(); void update_start_nanos(); @@ -47,11 +46,11 @@ JfrChunkState(); ~JfrChunkState(); void reset(); - jlong previous_checkpoint_offset() const; - void set_previous_checkpoint_offset(jlong offset); - jlong previous_start_ticks() const; - jlong previous_start_nanos() const; - jlong last_chunk_duration() const; + int64_t previous_checkpoint_offset() const; + void set_previous_checkpoint_offset(int64_t offset); + int64_t previous_start_ticks() const; + int64_t previous_start_nanos() const; + int64_t last_chunk_duration() const; void update_time_to_now(); void set_path(const char* path); const char* path() const;
--- a/src/share/vm/jfr/recorder/repository/jfrChunkWriter.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkWriter.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -32,9 +32,8 @@ #include "runtime/os.hpp" #include "runtime/os.hpp" -const u2 JFR_VERSION_MAJOR = 2; -const u2 JFR_VERSION_MINOR = 0; - +static const u2 JFR_VERSION_MAJOR = 2; +static const u2 JFR_VERSION_MINOR = 0; static const size_t MAGIC_LEN = 4; static const size_t FILEHEADER_SLOT_SIZE = 8; static const size_t CHUNK_SIZE_OFFSET = 8; @@ -79,14 +78,14 @@ return is_open; } -size_t JfrChunkWriter::close(intptr_t metadata_offset) { +size_t JfrChunkWriter::close(int64_t metadata_offset) { write_header(metadata_offset); this->flush(); this->close_fd(); - return size_written(); + return (size_t)size_written(); } -void JfrChunkWriter::write_header(intptr_t metadata_offset) { +void JfrChunkWriter::write_header(int64_t metadata_offset) { assert(this->is_valid(), "invariant"); // Chunk size this->write_be_at_offset((jlong)size_written(), CHUNK_SIZE_OFFSET); @@ -106,15 +105,15 @@ _chunkstate->set_path(chunk_path); } -intptr_t JfrChunkWriter::size_written() const { +int64_t JfrChunkWriter::size_written() const { return this->is_valid() ? this->current_offset() : 0; } -intptr_t JfrChunkWriter::previous_checkpoint_offset() const { +int64_t JfrChunkWriter::previous_checkpoint_offset() const { return _chunkstate->previous_checkpoint_offset(); } -void JfrChunkWriter::set_previous_checkpoint_offset(intptr_t offset) { +void JfrChunkWriter::set_previous_checkpoint_offset(int64_t offset) { _chunkstate->set_previous_checkpoint_offset(offset); }
--- a/src/share/vm/jfr/recorder/repository/jfrChunkWriter.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrChunkWriter.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -41,16 +41,16 @@ JfrChunkState* _chunkstate; bool open(); - size_t close(intptr_t metadata_offset); - void write_header(intptr_t metadata_offset); + size_t close(int64_t metadata_offset); + void write_header(int64_t metadata_offset); void set_chunk_path(const char* chunk_path); public: JfrChunkWriter(); bool initialize(); - intptr_t size_written() const; - intptr_t previous_checkpoint_offset() const; - void set_previous_checkpoint_offset(intptr_t offset); + int64_t size_written() const; + int64_t previous_checkpoint_offset() const; + void set_previous_checkpoint_offset(int64_t offset); void time_stamp_chunk_now(); };
--- a/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -70,10 +70,9 @@ Threads_lock->unlock(); } - // XXX (Module_lock -> PackageTable_lock) - if (PackageTable_lock->owned_by_self()) { - PackageTable_lock->unlock(); - } + if (PackageTable_lock->owned_by_self()) { + PackageTable_lock->unlock(); + } if (Heap_lock->owned_by_self()) { Heap_lock->unlock();
--- a/src/share/vm/jfr/recorder/repository/jfrRepository.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrRepository.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -147,10 +147,10 @@ iso8601_to_date_time(buffer); } -static jlong file_size(fio_fd fd) { +static int64_t file_size(fio_fd fd) { assert(fd != invalid_fd, "invariant"); - const jlong current_offset = os::current_file_offset(fd); - const jlong size = os::lseek(fd, 0, SEEK_END); + const int64_t current_offset = os::current_file_offset(fd); + const int64_t size = os::lseek(fd, 0, SEEK_END); os::seek_to_file_offset(fd, current_offset); return size; } @@ -218,7 +218,7 @@ if (invalid_fd == entry_fd) { return NULL; } - const jlong entry_size = file_size(entry_fd); + const int64_t entry_size = file_size(entry_fd); os::close(entry_fd); if (0 == entry_size) { return NULL; @@ -260,6 +260,7 @@ } } #endif + bool RepositoryIterator::has_next() const { return (_files != NULL && _iterator < _files->length()); } @@ -275,21 +276,26 @@ if (file_copy_block == NULL) { return; } - jlong bytes_written_total = 0; + int64_t bytes_written_total = 0; while (iterator.has_next()) { fio_fd current_fd = invalid_fd; const char* const fqn = iterator.next(); if (fqn != NULL) { current_fd = open_existing(fqn); if (current_fd != invalid_fd) { - const jlong current_filesize = file_size(current_fd); + const int64_t current_filesize = file_size(current_fd); assert(current_filesize > 0, "invariant"); - jlong bytes_read = 0; - jlong bytes_written = 0; + int64_t bytes_read = 0; + int64_t bytes_written = 0; while (bytes_read < current_filesize) { - bytes_read += (jlong)os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); - assert(bytes_read - bytes_written <= (jlong)size_of_file_copy_block, "invariant"); - bytes_written += (jlong)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); + const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read); + if (-1 == read_result) { + if (LogJFR) tty->print_cr("Unable to recover JFR data"); + break; + } + bytes_read += (int64_t)read_result; + assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant"); + bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written); assert(bytes_read == bytes_written, "invariant"); } os::close(current_fd); @@ -468,6 +474,6 @@ return _chunkwriter->open(); } -size_t JfrRepository::close_chunk(jlong metadata_offset) { +size_t JfrRepository::close_chunk(int64_t metadata_offset) { return _chunkwriter->close(metadata_offset); }
--- a/src/share/vm/jfr/recorder/repository/jfrRepository.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/repository/jfrRepository.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -55,7 +55,7 @@ bool set_path(const char* path); void set_chunk_path(const char* path); bool open_chunk(bool vm_error = false); - size_t close_chunk(jlong metadata_offset); + size_t close_chunk(int64_t metadata_offset); void on_vm_error(); static void notify_on_new_chunk_path(); static JfrChunkWriter& chunkwriter();
--- a/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/service/jfrOptionSet.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -27,6 +27,7 @@ #include "jfr/recorder/service/jfrMemorySizer.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/utilities/jfrAllocation.hpp" +#include "jfr/utilities/jfrTypes.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" @@ -105,10 +106,6 @@ return _stack_depth; } -static const u4 STACK_DEPTH_DEFAULT = 64; -static const u4 MIN_STACK_DEPTH = 1; -static const u4 MAX_STACK_DEPTH = 2048; - void JfrOptionSet::set_stackdepth(u4 depth) { if (depth < MIN_STACK_DEPTH) { _stack_depth = MIN_STACK_DEPTH;
--- a/src/share/vm/jfr/recorder/service/jfrRecorderService.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/service/jfrRecorderService.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -131,18 +131,18 @@ bool not_acquired() const { return !_acquired; } }; -static intptr_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { - const intptr_t prev_cp_offset = cw.previous_checkpoint_offset(); - const intptr_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); +static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { + const int64_t prev_cp_offset = cw.previous_checkpoint_offset(); + const int64_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); cw.reserve(sizeof(u4)); cw.write<u8>(EVENT_CHECKPOINT); cw.write(JfrTicks::now()); - cw.write<jlong>((jlong)0); - cw.write<jlong>((jlong)prev_cp_relative_offset); // write previous checkpoint offset delta + cw.write((int64_t)0); + cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta cw.write<bool>(false); // flushpoint - cw.write<u4>((u4)1); // nof types in this checkpoint - cw.write<u8>(type_id); - const intptr_t number_of_elements_offset = cw.current_offset(); + cw.write((u4)1); // nof types in this checkpoint + cw.write(type_id); + const int64_t number_of_elements_offset = cw.current_offset(); cw.reserve(sizeof(u4)); return number_of_elements_offset; } @@ -162,8 +162,8 @@ } bool process() { // current_cp_offset is also offset for the event size header field - const intptr_t current_cp_offset = _cw.current_offset(); - const intptr_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id); + const int64_t current_cp_offset = _cw.current_offset(); + const int64_t num_elements_offset = write_checkpoint_event_prologue(_cw, _type_id); // invocation _content_functor.process(); const u4 number_of_elements = (u4)_content_functor.processed(); @@ -476,9 +476,9 @@ JfrMetadataEvent::lock(); } -static jlong write_metadata_event(JfrChunkWriter& chunkwriter) { +static int64_t write_metadata_event(JfrChunkWriter& chunkwriter) { assert(chunkwriter.is_valid(), "invariant"); - const jlong metadata_offset = chunkwriter.current_offset(); + const int64_t metadata_offset = chunkwriter.current_offset(); JfrMetadataEvent::write(chunkwriter, metadata_offset); return metadata_offset; }
--- a/src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -69,8 +69,8 @@ } // handle general case - int loop_count = 0; - int loop_max = MaxJavaStackTraceDepth * 2; + u4 loop_count = 0; + u4 loop_max = MAX_STACK_DEPTH * 2; do { loop_count++; // By the time we get here we should never see unsafe but better safe then segv'd
--- a/src/share/vm/jfr/utilities/jfrTypes.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/utilities/jfrTypes.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -33,6 +33,9 @@ typedef int fio_fd; const int invalid_fd = -1; const jlong invalid_offset = -1; +const u4 STACK_DEPTH_DEFAULT = 64; +const u4 MIN_STACK_DEPTH = 1; +const u4 MAX_STACK_DEPTH = 2048; enum EventStartTime { UNTIMED,
--- a/src/share/vm/jfr/writers/jfrEventWriterHost.inline.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrEventWriterHost.inline.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -49,7 +49,7 @@ inline intptr_t EventWriterHost<BE, IE, WriterPolicyImpl>::end_write(void) { assert(this->is_acquired(), "state corruption, calling end with writer with non-acquired state!"); - return this->is_valid() ? this->used_offset() : 0; + return this->is_valid() ? (intptr_t)this->used_offset() : 0; } template <typename BE, typename IE, typename WriterPolicyImpl>
--- a/src/share/vm/jfr/writers/jfrPosition.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrPosition.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -48,8 +48,8 @@ public: size_t available_size() const; - intptr_t used_offset() const; - intptr_t current_offset() const; + int64_t used_offset() const; + int64_t current_offset() const; size_t used_size() const; void reset(); };
--- a/src/share/vm/jfr/writers/jfrPosition.inline.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrPosition.inline.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -80,12 +80,12 @@ } template <typename AP> -inline intptr_t Position<AP>::used_offset() const { +inline int64_t Position<AP>::used_offset() const { return _current_pos - _start_pos; } template <typename AP> -inline intptr_t Position<AP>::current_offset() const { +inline int64_t Position<AP>::current_offset() const { return this->used_offset(); }
--- a/src/share/vm/jfr/writers/jfrStreamWriterHost.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrStreamWriterHost.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -33,9 +33,9 @@ public: typedef typename Adapter::StorageType StorageType; private: - intptr_t _stream_pos; + int64_t _stream_pos; fio_fd _fd; - intptr_t current_stream_position() const; + int64_t current_stream_position() const; protected: StreamWriterHost(StorageType* storage, Thread* thread); @@ -47,8 +47,8 @@ bool has_valid_fd() const; public: - intptr_t current_offset() const; - void seek(intptr_t offset); + int64_t current_offset() const; + void seek(int64_t offset); void flush(); void write_unbuffered(const void* src, size_t len); bool is_valid() const;
--- a/src/share/vm/jfr/writers/jfrStreamWriterHost.inline.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrStreamWriterHost.inline.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -44,7 +44,7 @@ } template <typename Adapter, typename AP> -inline intptr_t StreamWriterHost<Adapter, AP>::current_stream_position() const { +inline int64_t StreamWriterHost<Adapter, AP>::current_stream_position() const { return this->used_offset() + _stream_pos; } @@ -73,7 +73,7 @@ inline void StreamWriterHost<Adapter, AP>::flush(size_t size) { assert(size > 0, "invariant"); assert(this->is_valid(), "invariant"); - _stream_pos += os::write(_fd, this->start_pos(), (int)size); + _stream_pos += os::write(_fd, this->start_pos(), (unsigned int)size); StorageHost<Adapter, AP>::reset(); assert(0 == this->used_offset(), "invariant"); } @@ -84,12 +84,12 @@ } template <typename Adapter, typename AP> -inline intptr_t StreamWriterHost<Adapter, AP>::current_offset() const { +inline int64_t StreamWriterHost<Adapter, AP>::current_offset() const { return current_stream_position(); } template <typename Adapter, typename AP> -void StreamWriterHost<Adapter, AP>::seek(intptr_t offset) { +void StreamWriterHost<Adapter, AP>::seek(int64_t offset) { this->flush(); assert(0 == this->used_offset(), "can only seek from beginning"); _stream_pos = os::seek_to_file_offset(_fd, offset); @@ -110,7 +110,7 @@ this->flush(); assert(0 == this->used_offset(), "can only seek from beginning"); while (len > 0) { - const int n = MIN2<int>((int)len, INT_MAX); + const unsigned int n = MIN2((unsigned int)len, (unsigned int)INT_MAX); _stream_pos += os::write(_fd, buf, n); len -= n; }
--- a/src/share/vm/jfr/writers/jfrWriterHost.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrWriterHost.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -32,7 +32,6 @@ class ClassLoaderData; class Klass; class Method; -// XXX class PackageEntry; class Symbol; class Thread; @@ -80,7 +79,6 @@ void write(const ClassLoaderData* cld); void write(const Klass* klass); void write(const Method* method); -// XXX void write(const PackageEntry* package); void write(const Symbol* symbol); void write(const Ticks& time); void write(const Tickspan& time); @@ -89,12 +87,12 @@ void bytes(const void* buf, size_t len); void write_utf8_u2_len(const char* value); template <typename T> - void write_padded_at_offset(T value, intptr_t offset); + void write_padded_at_offset(T value, int64_t offset); template <typename T> - void write_at_offset(T value, intptr_t offset); + void write_at_offset(T value, int64_t offset); template <typename T> - void write_be_at_offset(T value, intptr_t offset); - intptr_t reserve(size_t size); + void write_be_at_offset(T value, int64_t offset); + int64_t reserve(size_t size); }; #endif // SHARE_VM_JFR_WRITERS_JFRWRITERHOST_HPP
--- a/src/share/vm/jfr/writers/jfrWriterHost.inline.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/jfr/writers/jfrWriterHost.inline.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -33,7 +33,6 @@ #include "memory/resourceArea.hpp" #include "oops/oop.hpp" #include "oops/symbol.hpp" -//#include "oops/typeArrayOop.inline.hpp" - XXX inline bool compressed_integers() { static const bool comp_integers = JfrOptionSet::compressed_integers(); @@ -259,12 +258,6 @@ tag_write(this, method); } -// XXX -// template <typename BE, typename IE, typename WriterPolicyImpl> -// void WriterHost<BE, IE, WriterPolicyImpl>::write(const PackageEntry* package) { -// tag_write(this, package); -// } - template <typename BE, typename IE, typename WriterPolicyImpl> void WriterHost<BE, IE, WriterPolicyImpl>::write(const Symbol* symbol) { ResourceMark rm; @@ -313,9 +306,9 @@ } template <typename BE, typename IE, typename WriterPolicyImpl> -inline intptr_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) { +inline int64_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) { if (ensure_size(size) != NULL) { - intptr_t reserved_offset = this->current_offset(); + const int64_t reserved_offset = this->current_offset(); this->set_current_pos(size); return reserved_offset; } @@ -325,9 +318,9 @@ template <typename BE, typename IE, typename WriterPolicyImpl> template <typename T> -inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, intptr_t offset) { +inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, int64_t offset) { if (this->is_valid()) { - const intptr_t current = this->current_offset(); + const int64_t current = this->current_offset(); this->seek(offset); write_padded(value); this->seek(current); // restore @@ -336,9 +329,9 @@ template <typename BE, typename IE, typename WriterPolicyImpl> template <typename T> -inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, intptr_t offset) { +inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, int64_t offset) { if (this->is_valid()) { - const intptr_t current = this->current_offset(); + const int64_t current = this->current_offset(); this->seek(offset); write(value); this->seek(current); // restore @@ -347,9 +340,9 @@ template <typename BE, typename IE, typename WriterPolicyImpl> template <typename T> -inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, intptr_t offset) { +inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, int64_t offset) { if (this->is_valid()) { - const intptr_t current = this->current_offset(); + const int64_t current = this->current_offset(); this->seek(offset); be_write(value); this->seek(current); // restore
--- a/src/share/vm/memory/threadLocalAllocBuffer.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, 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 @@ -88,7 +88,8 @@ // The result can be larger than 1.0 due to direct to old allocations. // These allocations should ideally not be counted but since it is not possible // to filter them out here we just cap the fraction to be at most 1.0. - double alloc_frac = MIN2(1.0, (double) allocated_since_last_gc / used); + // Keep alloc_frac as float and not double to avoid the double to float conversion + float alloc_frac = MIN2(1.0f, allocated_since_last_gc / (float) used); _allocation_fraction.sample(alloc_frac); } global_stats()->update_allocating_threads(); @@ -205,7 +206,8 @@ // this thread is redone in startup_initialization below. if (Universe::heap() != NULL) { size_t capacity = Universe::heap()->tlab_capacity(myThread()) / HeapWordSize; - double alloc_frac = desired_size() * target_refills() / (double) capacity; + // Keep alloc_frac as float and not double to avoid the double to float conversion + float alloc_frac = desired_size() * target_refills() / (float) capacity; _allocation_fraction.sample(alloc_frac); }
--- a/src/share/vm/oops/constantPool.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/oops/constantPool.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -235,14 +235,14 @@ // The original attempt to resolve this constant pool entry failed so find the - // original error and throw it again (JVMS 5.4.3). + // class of the original error and throw another error of the same class (JVMS 5.4.3). + // If there is a detail message, pass that detail message to the error constructor. + // The JVMS does not strictly require us to duplicate the same detail message, + // or any internal exception fields such as cause or stacktrace. But since the + // detail message is often a class name or other literal string, we will repeat it if + // we can find it in the symbol table. if (in_error) { - Symbol* error = SystemDictionary::find_resolution_error(this_oop, which); - guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); - ResourceMark rm; - // exception text will be the class name - const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); - THROW_MSG_0(error, className); + throw_resolution_error(this_oop, which, CHECK_0); } if (do_resolve) { @@ -262,11 +262,6 @@ // Failed to resolve class. We must record the errors so that subsequent attempts // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). if (HAS_PENDING_EXCEPTION) { - ResourceMark rm; - Symbol* error = PENDING_EXCEPTION->klass()->name(); - - bool throw_orig_error = false; - { MonitorLockerEx ml(this_oop->lock()); // some other thread has beaten us and has resolved the class. @@ -276,32 +271,9 @@ return entry.get_klass(); } - if (!PENDING_EXCEPTION-> - is_a(SystemDictionary::LinkageError_klass())) { - // Just throw the exception and don't prevent these classes from - // being loaded due to virtual machine errors like StackOverflow - // and OutOfMemoryError, etc, or if the thread was hit by stop() - // Needs clarification to section 5.4.3 of the VM spec (see 6308271) - } - else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) { - SystemDictionary::add_resolution_error(this_oop, which, error); - this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); - } else { - // some other thread has put the class in error state. - error = SystemDictionary::find_resolution_error(this_oop, which); - assert(error != NULL, "checking"); - throw_orig_error = true; - } - } // unlocked - - if (throw_orig_error) { - CLEAR_PENDING_EXCEPTION; - ResourceMark rm; - const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); - THROW_MSG_0(error, className); - } - - return 0; + // The tag could have changed to in-error before the lock but we have to + // handle that here for the class case. + save_and_throw_exception(this_oop, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0); } if (TraceClassResolution && !k()->oop_is_array()) { @@ -597,16 +569,51 @@ return true; } -// If resolution for MethodHandle or MethodType fails, save the exception +Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) { + // Dig out the detailed message to reuse if possible + Symbol* message = java_lang_Throwable::detail_message(pending_exception); + if (message != NULL) { + return message; + } + + // Return specific message for the tag + switch (tag.value()) { + case JVM_CONSTANT_UnresolvedClass: + // return the class name in the error message + message = this_oop->unresolved_klass_at(which); + break; + case JVM_CONSTANT_MethodHandle: + // return the method handle name in the error message + message = this_oop->method_handle_name_ref_at(which); + break; + case JVM_CONSTANT_MethodType: + // return the method type signature in the error message + message = this_oop->method_type_signature_at(which); + break; + default: + ShouldNotReachHere(); + } + + return message; +} + +void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) { + Symbol* message = NULL; + Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message); + assert(error != NULL && message != NULL, "checking"); + CLEAR_PENDING_EXCEPTION; + ResourceMark rm; + THROW_MSG(error, message->as_C_string()); +} + +// If resolution for Class, MethodHandle or MethodType fails, save the exception // in the resolution error table, so that the same exception is thrown again. void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, - int tag, TRAPS) { - ResourceMark rm; + constantTag tag, TRAPS) { + assert(this_oop->lock()->is_locked(), "constant pool lock should be held"); Symbol* error = PENDING_EXCEPTION->klass()->name(); - MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. - int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? - JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; + int error_tag = tag.error_value(); if (!PENDING_EXCEPTION-> is_a(SystemDictionary::LinkageError_klass())) { @@ -614,20 +621,21 @@ // being loaded due to virtual machine errors like StackOverflow // and OutOfMemoryError, etc, or if the thread was hit by stop() // Needs clarification to section 5.4.3 of the VM spec (see 6308271) - } else if (this_oop->tag_at(which).value() != error_tag) { - SystemDictionary::add_resolution_error(this_oop, which, error); + Symbol* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION); + SystemDictionary::add_resolution_error(this_oop, which, error, message); this_oop->tag_at_put(which, error_tag); } else { - // some other thread has put the class in error state. - error = SystemDictionary::find_resolution_error(this_oop, which); - assert(error != NULL, "checking"); - CLEAR_PENDING_EXCEPTION; - THROW_MSG(error, ""); + // some other thread put this in error state + throw_resolution_error(this_oop, which, CHECK); } + + // This exits with some pending exception + assert(HAS_PENDING_EXCEPTION, "should not be cleared"); } + // Called to resolve constants in the constant pool and return an oop. // Some constant pool entries cache their resolved oop. This is also // called to create oops from constants to use in arguments for invokedynamic @@ -655,9 +663,9 @@ jvalue prim_value; // temp used only in a few cases below - int tag_value = this_oop->tag_at(index).value(); + constantTag tag = this_oop->tag_at(index); - switch (tag_value) { + switch (tag.value()) { case JVM_CONSTANT_UnresolvedClass: case JVM_CONSTANT_UnresolvedClassInError: @@ -682,10 +690,7 @@ case JVM_CONSTANT_MethodHandleInError: case JVM_CONSTANT_MethodTypeInError: { - Symbol* error = SystemDictionary::find_resolution_error(this_oop, index); - guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); - ResourceMark rm; - THROW_MSG_0(error, ""); + throw_resolution_error(this_oop, index, CHECK_NULL); break; } @@ -709,7 +714,8 @@ THREAD); result_oop = value(); if (HAS_PENDING_EXCEPTION) { - save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. + save_and_throw_exception(this_oop, index, tag, CHECK_NULL); } break; } @@ -725,7 +731,8 @@ Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); result_oop = value(); if (HAS_PENDING_EXCEPTION) { - save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. + save_and_throw_exception(this_oop, index, tag, CHECK_NULL); } break; } @@ -756,7 +763,7 @@ default: DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", - this_oop(), index, cache_index, tag_value) ); + this_oop(), index, cache_index, tag.value())); assert(false, "unexpected constant tag"); break; }
--- a/src/share/vm/oops/constantPool.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/oops/constantPool.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -826,9 +826,13 @@ static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS); static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS); - static void save_and_throw_exception(constantPoolHandle this_oop, int which, int tag_value, TRAPS); static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS); + // Exception handling + static void throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS); + static Symbol* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception); + static void save_and_throw_exception(constantPoolHandle this_oop, int which, constantTag tag, TRAPS); + public: // Merging ConstantPool* support: bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
--- a/src/share/vm/opto/c2compiler.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/c2compiler.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -111,7 +111,7 @@ assert(is_initialized(), "Compiler thread must be initialized"); bool subsume_loads = SubsumeLoads; - bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); + bool do_escape_analysis = DoEscapeAnalysis && !env->should_retain_local_variables(); bool eliminate_boxing = EliminateAutoBox; while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions.
--- a/src/share/vm/opto/callnode.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/callnode.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1180,6 +1180,14 @@ return (TypeFunc::Parms == idx); } +void SafePointNode::disconnect_from_root(PhaseIterGVN *igvn) { + assert(Opcode() == Op_SafePoint, "only value for safepoint in loops"); + int nb = igvn->C->root()->find_prec_edge(this); + if (nb != -1) { + igvn->C->root()->rm_prec(nb); + } +} + //============== SafePointScalarObjectNode ============== SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
--- a/src/share/vm/opto/callnode.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/callnode.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -459,6 +459,8 @@ return !_replaced_nodes.is_empty(); } + void disconnect_from_root(PhaseIterGVN *igvn); + // Standard Node stuff virtual int Opcode() const; virtual bool pinned() const { return true; }
--- a/src/share/vm/opto/compile.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/compile.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -2077,6 +2077,23 @@ } +// Remove edges from "root" to each SafePoint at a backward branch. +// They were inserted during parsing (see add_safepoint()) to make +// infinite loops without calls or exceptions visible to root, i.e., +// useful. +void Compile::remove_root_to_sfpts_edges() { + Node *r = root(); + if (r != NULL) { + for (uint i = r->req(); i < r->len(); ++i) { + Node *n = r->in(i); + if (n != NULL && n->is_SafePoint()) { + r->rm_prec(i); + --i; + } + } + } +} + //------------------------------Optimize--------------------------------------- // Given a graph, optimize it. void Compile::Optimize() { @@ -2132,6 +2149,10 @@ if (failing()) return; } + // Now that all inlining is over, cut edge from root to loop + // safepoints + remove_root_to_sfpts_edges(); + // Remove the speculative part of types and clean up the graph from // the extra CastPP nodes whose only purpose is to carry them. Do // that early so that optimizations are not disrupted by the extra @@ -3025,8 +3046,10 @@ break; } } - assert(proj != NULL, "must be found"); - p->subsume_by(proj, this); + assert(proj != NULL || p->_con == TypeFunc::I_O, "io may be dropped at an infinite loop"); + if (proj != NULL) { + p->subsume_by(proj, this); + } } } break;
--- a/src/share/vm/opto/compile.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/compile.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -959,6 +959,7 @@ void inline_incrementally(PhaseIterGVN& igvn); void inline_string_calls(bool parse_time); void inline_boxing_calls(PhaseIterGVN& igvn); + void remove_root_to_sfpts_edges(); // Matching, CFG layout, allocation, code generation PhaseCFG* cfg() { return _cfg; }
--- a/src/share/vm/opto/escape.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/escape.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -2062,6 +2062,9 @@ return NULL; } PointsToNode* ptn = ptnode_adr(idx); + if (ptn == NULL) { + return NULL; + } if (ptn->is_JavaObject()) { return ptn->as_JavaObject(); }
--- a/src/share/vm/opto/gcm.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/gcm.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -250,6 +250,7 @@ int is_visited = visited.test_set(in->_idx); if (!has_block(in)) { if (is_visited) { + assert(false, "graph should be schedulable"); return false; } // Save parent node and next input's index. @@ -1064,6 +1065,7 @@ if (LCA == NULL) { // Bailout without retry + assert(false, "graph should be schedulable"); C->record_method_not_compilable("late schedule failed: LCA == NULL"); return least; } @@ -1218,6 +1220,7 @@ C->record_failure(C2Compiler::retry_no_subsuming_loads()); } else { // Bailout without retry when (early->_dom_depth > LCA->_dom_depth) + assert(false, "graph should be schedulable"); C->record_method_not_compilable("late schedule failed: incorrect graph"); } return;
--- a/src/share/vm/opto/graphKit.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/graphKit.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -864,7 +864,7 @@ } } - if (env()->jvmti_can_access_local_variables()) { + if (env()->should_retain_local_variables()) { // At any safepoint, this method can get breakpointed, which would // then require an immediate deoptimization. can_prune_locals = false; // do not prune locals
--- a/src/share/vm/opto/lcm.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/lcm.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -963,6 +963,8 @@ // If this is the first failure, the sentinel string will "stick" // to the Compile object, and the C2Compiler will see it and retry. C->record_failure(C2Compiler::retry_no_subsuming_loads()); + } else { + assert(false, "graph should be schedulable"); } // assert( phi_cnt == end_idx(), "did not schedule all" ); return false;
--- a/src/share/vm/opto/loopTransform.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/loopTransform.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1223,20 +1223,14 @@ Node *opaq = NULL; if (adjust_min_trip) { // If not maximally unrolling, need adjustment // Search for zero-trip guard. - assert( loop_head->is_main_loop(), "" ); - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); - Node *iff = ctrl->in(0); - assert( iff->Opcode() == Op_If, "" ); - Node *bol = iff->in(1); - assert( bol->Opcode() == Op_Bool, "" ); - Node *cmp = bol->in(1); - assert( cmp->Opcode() == Op_CmpI, "" ); - opaq = cmp->in(2); - // Occasionally it's possible for a zero-trip guard Opaque1 node to be - // optimized away and then another round of loop opts attempted. - // We can not optimize this particular loop in that case. - if (opaq->Opcode() != Op_Opaque1) - return; // Cannot find zero-trip guard! Bail out! + + // Check the shape of the graph at the loop entry. If an inappropriate + // graph shape is encountered, the compiler bails out loop unrolling; + // compilation of the method will still succeed. + if (!is_canonical_main_loop_entry(loop_head)) { + return; + } + opaq = ctrl->in(0)->in(1)->in(1)->in(2); // Zero-trip test uses an 'opaque' node which is not shared. assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); } @@ -1806,7 +1800,6 @@ #endif assert(RangeCheckElimination, ""); CountedLoopNode *cl = loop->_head->as_CountedLoop(); - assert(cl->is_main_loop(), ""); // protect against stride not being a constant if (!cl->stride_is_con()) @@ -1818,20 +1811,17 @@ // to not ever trip end tests Node *main_limit = cl->limit(); + // Check graph shape. Cannot optimize a loop if zero-trip + // Opaque1 node is optimized away and then another round + // of loop opts attempted. + if (!is_canonical_main_loop_entry(cl)) { + return; + } + // Need to find the main-loop zero-trip guard Node *ctrl = cl->in(LoopNode::EntryControl); - assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); Node *iffm = ctrl->in(0); - assert(iffm->Opcode() == Op_If, ""); - Node *bolzm = iffm->in(1); - assert(bolzm->Opcode() == Op_Bool, ""); - Node *cmpzm = bolzm->in(1); - assert(cmpzm->is_Cmp(), ""); - Node *opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) - return; + Node *opqzm = iffm->in(1)->in(1)->in(2); assert(opqzm->in(1) == main_limit, "do not understand situation"); // Find the pre-loop limit; we will expand it's iterations to
--- a/src/share/vm/opto/loopnode.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/loopnode.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -3282,6 +3282,41 @@ return LCA; } +// Check the shape of the graph at the loop entry. In some cases, +// the shape of the graph does not match the shape outlined below. +// That is caused by the Opaque1 node "protecting" the shape of +// the graph being removed by, for example, the IGVN performed +// in PhaseIdealLoop::build_and_optimize(). +// +// After the Opaque1 node has been removed, optimizations (e.g., split-if, +// loop unswitching, and IGVN, or a combination of them) can freely change +// the graph's shape. As a result, the graph shape outlined below cannot +// be guaranteed anymore. +bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { + assert(cl->is_main_loop(), "check should be applied to main loops"); + Node* ctrl = cl->in(LoopNode::EntryControl); + if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { + return false; + } + Node* iffm = ctrl->in(0); + if (iffm == NULL || !iffm->is_If()) { + return false; + } + Node* bolzm = iffm->in(1); + if (bolzm == NULL || !bolzm->is_Bool()) { + return false; + } + Node* cmpzm = bolzm->in(1); + if (cmpzm == NULL || !cmpzm->is_Cmp()) { + return false; + } + Node* opqzm = cmpzm->in(2); + if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { + return false; + } + return true; +} + //------------------------------get_late_ctrl---------------------------------- // Compute latest legal control. Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
--- a/src/share/vm/opto/loopnode.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/loopnode.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -619,6 +619,9 @@ bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); public: + + static bool is_canonical_main_loop_entry(CountedLoopNode* cl); + bool has_node( Node* n ) const { guarantee(n != NULL, "No Node."); return _nodes[n->_idx] != NULL;
--- a/src/share/vm/opto/node.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/node.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -937,6 +937,17 @@ return (Node*) this; } +// Find out of current node that matches opcode. +Node* Node::find_out_with(int opcode) { + for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { + Node* use = fast_out(i); + if (use->Opcode() == opcode) { + return use; + } + } + return NULL; +} + //---------------------------uncast_helper------------------------------------- Node* Node::uncast_helper(const Node* p) { #ifdef ASSERT @@ -1318,6 +1329,9 @@ while (nstack.size() > 0) { dead = nstack.pop(); + if (dead->Opcode() == Op_SafePoint) { + dead->as_SafePoint()->disconnect_from_root(igvn); + } if (dead->outcnt() > 0) { // Keep dead node on stack until all uses are processed. nstack.push(dead);
--- a/src/share/vm/opto/node.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/node.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -454,6 +454,9 @@ return (this->uncast() == n->uncast()); } + // Find out of current node that matches opcode. + Node* find_out_with(int opcode); + private: static Node* uncast_helper(const Node* n);
--- a/src/share/vm/opto/phaseX.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/phaseX.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -419,20 +419,6 @@ // Disconnect 'useless' nodes that are adjacent to useful nodes C->remove_useless_nodes(_useful); - - // Remove edges from "root" to each SafePoint at a backward branch. - // They were inserted during parsing (see add_safepoint()) to make infinite - // loops without calls or exceptions visible to root, i.e., useful. - Node *root = C->root(); - if( root != NULL ) { - for( uint i = root->req(); i < root->len(); ++i ) { - Node *n = root->in(i); - if( n != NULL && n->is_SafePoint() ) { - root->rm_prec(i); - --i; - } - } - } } //============================================================================= @@ -1258,6 +1244,9 @@ while (_stack.is_nonempty()) { dead = _stack.node(); + if (dead->Opcode() == Op_SafePoint) { + dead->as_SafePoint()->disconnect_from_root(this); + } uint progress_state = _stack.index(); assert(dead != C->root(), "killing root, eh?"); assert(!dead->is_top(), "add check for top when pushing"); @@ -1352,6 +1341,9 @@ //------------------------------subsume_node----------------------------------- // Remove users from node 'old' and add them to node 'nn'. void PhaseIterGVN::subsume_node( Node *old, Node *nn ) { + if (old->Opcode() == Op_SafePoint) { + old->as_SafePoint()->disconnect_from_root(this); + } assert( old != hash_find(old), "should already been removed" ); assert( old != C->top(), "cannot subsume top node"); // Copy debug or profile information to the new version: @@ -1653,8 +1645,11 @@ if (m->is_Call()) { for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) { Node* p = m->fast_out(i2); // Propagate changes to uses - if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1) { - worklist.push(p->unique_out()); + if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control) { + Node* catch_node = p->find_out_with(Op_Catch); + if (catch_node != NULL) { + worklist.push(catch_node); + } } } }
--- a/src/share/vm/opto/superword.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/opto/superword.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -2209,21 +2209,13 @@ //----------------------------get_pre_loop_end--------------------------- // Find pre loop end from main loop. Returns null if none. CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { - Node* ctrl = cl->in(LoopNode::EntryControl); - if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; - Node* iffm = ctrl->in(0); - if (!iffm->is_If()) return NULL; - Node* bolzm = iffm->in(1); - if (!bolzm->is_Bool()) return NULL; - Node* cmpzm = bolzm->in(1); - if (!cmpzm->is_Cmp()) return NULL; - Node* opqzm = cmpzm->in(2); - // Can not optimize a loop if zero-trip Opaque1 node is optimized - // away and then another round of loop opts attempted. - if (opqzm->Opcode() != Op_Opaque1) { + // The loop cannot be optimized if the graph shape at + // the loop entry is inappropriate. + if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { return NULL; } - Node* p_f = iffm->in(0); + + Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); if (!p_f->is_IfFalse()) return NULL; if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();
--- a/src/share/vm/runtime/java.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/runtime/java.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -138,7 +138,7 @@ return JDK_Version(m); } - static JDK_Version jdk_update(uint8_t major, uint8_t update_number) { + static JDK_Version jdk_update(uint8_t major, uint16_t update_number) { return JDK_Version(major, 0, 0, update_number); }
--- a/src/share/vm/runtime/os.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/runtime/os.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -876,10 +876,9 @@ } 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 - // before printf. We lost some precision, but who cares? + // NOTE: a crash using printf("%f",...) on Linux was historically noted here. int eltime = (int)t; // elapsed time in seconds + int eltimeFraction = (int) ((t - eltime) * 1000000); // print elapsed time in a human-readable format: int eldays = eltime / secs_per_day; @@ -889,7 +888,7 @@ int elmins = (eltime - day_secs - hour_secs) / secs_per_min; int minute_secs = elmins * secs_per_min; int elsecs = (eltime - day_secs - hour_secs - minute_secs); - st->print_cr("elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs); + st->print_cr("elapsed time: %d.%06d seconds (%dd %dh %dm %ds)", eltime, eltimeFraction, eldays, elhours, elmins, elsecs); } // moved from debug.cpp (used to be find()) but still called from there
--- a/src/share/vm/runtime/reflection.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/runtime/reflection.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -506,7 +506,7 @@ (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION && accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) { return classloader_only && - Verifier::relax_verify_for(accessor_ik->class_loader()) && + Verifier::relax_access_for(accessor_ik->class_loader()) && accessor_ik->protection_domain() == accessee_ik->protection_domain() && accessor_ik->class_loader() == accessee_ik->class_loader(); } else {
--- a/src/share/vm/runtime/vm_version.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/runtime/vm_version.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -231,10 +231,26 @@ #define HOTSPOT_BUILD_COMPILER "MS VC++ 12.0 (VS2013)" #elif _MSC_VER == 1900 #define HOTSPOT_BUILD_COMPILER "MS VC++ 14.0 (VS2015)" + #elif _MSC_VER == 1911 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.3 (VS2017)" #elif _MSC_VER == 1912 #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.5 (VS2017)" #elif _MSC_VER == 1913 #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.6 (VS2017)" + #elif _MSC_VER == 1914 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.7 (VS2017)" + #elif _MSC_VER == 1915 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.8 (VS2017)" + #elif _MSC_VER == 1916 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 15.9 (VS2017)" + #elif _MSC_VER == 1920 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.0 (VS2019)" + #elif _MSC_VER == 1921 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.1 (VS2019)" + #elif _MSC_VER == 1922 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.2 (VS2019)" + #elif _MSC_VER == 1923 + #define HOTSPOT_BUILD_COMPILER "MS VC++ 16.3 (VS2019)" #else #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER) #endif
--- a/src/share/vm/services/jmm.h Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/services/jmm.h Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, 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 @@ -143,7 +143,8 @@ JMM_VMGLOBAL_TYPE_UNKNOWN = 0, JMM_VMGLOBAL_TYPE_JBOOLEAN = 1, JMM_VMGLOBAL_TYPE_JSTRING = 2, - JMM_VMGLOBAL_TYPE_JLONG = 3 + JMM_VMGLOBAL_TYPE_JLONG = 3, + JMM_VMGLOBAL_TYPE_JDOUBLE = 4 } jmmVMGlobalType; typedef enum {
--- a/src/share/vm/services/management.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/services/management.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -1578,6 +1578,9 @@ } else if (flag->is_uint64_t()) { global->value.j = (jlong)flag->get_uint64_t(); global->type = JMM_VMGLOBAL_TYPE_JLONG; + } else if (flag->is_double()) { + global->value.d = (jdouble)flag->get_double(); + global->type = JMM_VMGLOBAL_TYPE_JDOUBLE; } else if (flag->is_ccstr()) { Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false); global->value.l = (jobject)JNIHandles::make_local(env, str());
--- a/src/share/vm/utilities/constantTag.cpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/utilities/constantTag.cpp Sat Oct 24 01:11:49 2020 +0100 @@ -76,6 +76,20 @@ } +jbyte constantTag::error_value() const { + switch (_tag) { + case JVM_CONSTANT_UnresolvedClass: + return JVM_CONSTANT_UnresolvedClassInError; + case JVM_CONSTANT_MethodHandle: + return JVM_CONSTANT_MethodHandleInError; + case JVM_CONSTANT_MethodType: + return JVM_CONSTANT_MethodTypeInError; + default: + ShouldNotReachHere(); + return JVM_CONSTANT_Invalid; + } +} + const char* constantTag::internal_name() const { switch (_tag) { case JVM_CONSTANT_Invalid :
--- a/src/share/vm/utilities/constantTag.hpp Fri Aug 28 07:38:21 2020 +0100 +++ b/src/share/vm/utilities/constantTag.hpp Sat Oct 24 01:11:49 2020 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -109,6 +109,7 @@ } jbyte value() const { return _tag; } + jbyte error_value() const; jbyte non_error_value() const; BasicType basic_type() const; // if used with ldc, what kind of value gets pushed?
--- a/test/compiler/7177917/Test7177917.java Fri Aug 28 07:38:21 2020 +0100 +++ b/test/compiler/7177917/Test7177917.java Sat Oct 24 01:11:49 2020 +0100 @@ -22,8 +22,12 @@ * */ -/* - * Micro-benchmark for Math.pow() and Math.exp() +/** + * @test + * @bug 7177917 + * @summary Micro-benchmark for Math.pow() and Math.exp() + * + * @run main Test7177917 */ import java.util.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/conversions/Conversion.jasm Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 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 + * 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. + */ + +package compiler/conversions; + +public class Conversion + version 52:0 +{ + Field booleanFld:Z; + Field byteFld:B; + Field charFld:C; + Field shortFld:S; + Field intFld:I; + + public Method "<init>":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; + } + + public Method testBooleanConst:"()I" + stack 5 locals 1 + { + aload_0; + ldc_w int 2; // 2^1 (maximum boolean value is 1) + putfield Field booleanFld:"Z"; + aload_0; + getfield Field booleanFld:"Z"; + ireturn; + } + + public Method testBoolean:"(I)I" + stack 5 locals 2 + { + aload_0; + iload_1; + putfield Field booleanFld:"Z"; + aload_0; + getfield Field booleanFld:"Z"; + ireturn; + } + + public Method testByteConst:"()I" + stack 5 locals 1 + { + aload_0; + ldc_w int 256; // 2^8 (maximum byte value is 2^7-1) + putfield Field byteFld:"B"; + aload_0; + getfield Field byteFld:"B"; + ireturn; + } + + public Method testByte:"(I)I" + stack 5 locals 2 + { + aload_0; + iload_1; + putfield Field byteFld:"B"; + aload_0; + getfield Field byteFld:"B"; + ireturn; + } + + public Method testCharConst:"()I" + stack 5 locals 1 + { + aload_0; + ldc_w int 131072; // 2^17 (maximum char value is 2^16-1) + putfield Field charFld:"C"; + aload_0; + getfield Field charFld:"C"; + ireturn; + } + + public Method testChar:"(I)I" + stack 5 locals 2 + { + aload_0; + iload_1; + putfield Field charFld:"C"; + aload_0; + getfield Field charFld:"C"; + ireturn; + } + + public Method testShortConst:"()I" + stack 5 locals 1 + { + aload_0; + ldc_w int 65536; // 2^16 (maximum short value is 2^15-1) + putfield Field shortFld:"S"; + aload_0; + getfield Field shortFld:"S"; + ireturn; + } + + public Method testShort:"(I)I" + stack 5 locals 2 + { + aload_0; + iload_1; + putfield Field shortFld:"S"; + aload_0; + getfield Field shortFld:"S"; + ireturn; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/conversions/TestPrimitiveConversions.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 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 + * 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. + */ + +package compiler.conversions; + +import com.oracle.java.testlibrary.Asserts; + +/* + * @test + * @bug 8234617 + * @summary Test implicit narrowing conversion of primivite values at putfield. + * @library /testlibrary + * @compile Conversion.jasm + * @run main/othervm -Xbatch -XX:CompileCommand=dontinline,compiler.conversions.Conversion::* + * compiler.conversions.TestPrimitiveConversions + */ +public class TestPrimitiveConversions { + + public static void main(String[] args) { + Conversion conv = new Conversion(); + for (int i = 0; i < 100_000; ++i) { + int res = conv.testBooleanConst(); + Asserts.assertEquals(res, 0); + res = conv.testBoolean(2); // 2^1 (maximum boolean value is 1) + Asserts.assertEquals(res, 0); + res = conv.testByteConst(); + Asserts.assertEquals(res, 0); + res = conv.testByte(256); // 2^8 (maximum byte value is 2^7-1) + Asserts.assertEquals(res, 0); + res = conv.testCharConst(); + Asserts.assertEquals(res, 0); + res = conv.testChar(131072); // 2^17 (maximum char value is 2^16-1) + Asserts.assertEquals(res, 0); + res = conv.testShortConst(); + Asserts.assertEquals(res, 0); + res = conv.testShort(65536); // 2^16 (maximum short value is 2^15-1) + Asserts.assertEquals(res, 0); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/inlining/StringConcatInfiniteLoop.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. 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. + */ + +/* + * @test 8214862 + * @summary Multiple passes of PhaseRemoveUseless causes infinite loop to be optimized out + * + * @run main/othervm -XX:-TieredCompilation -Xcomp -XX:CompileOnly=StringConcatInfiniteLoop::test -XX:CompileCommand=dontinline,*StringBuilder::* StringConcatInfiniteLoop + * + */ + +public class StringConcatInfiniteLoop { + public static void main(String[] args) { + StringBuilder sb = new StringBuilder(); + test(sb, "foo", "bar", true); + } + + private static void test(Object v, String s1, String s2, boolean flag) { + if (flag) { + return; + } + int i = 0; + for (; i < 10; i++); + if (i == 10) { + v = null; + } + StringBuilder sb = new StringBuilder(s1); + sb.append(s2); + while (v == null); + } + + private static class A { + } +}
--- a/test/compiler/tiered/NonTieredLevelsTest.java Fri Aug 28 07:38:21 2020 +0100 +++ b/test/compiler/tiered/NonTieredLevelsTest.java Sat Oct 24 01:11:49 2020 +0100 @@ -46,8 +46,7 @@ } else if (vmName.endsWith(" Client VM") || vmName.endsWith(" Minimal VM")) { AVAILABLE_COMP_LEVEL = COMP_LEVEL_SIMPLE; - IS_AVAILABLE_COMPLEVEL = x -> x >= COMP_LEVEL_SIMPLE - && x <= COMP_LEVEL_FULL_PROFILE; + IS_AVAILABLE_COMPLEVEL = x -> x == COMP_LEVEL_SIMPLE; } else { throw new RuntimeException("Unknown VM: " + vmName); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/ClassFile/BadHelloWorld.jcod Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016, 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 + * 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. + */ + +/* + * This file fuzzes the class name #15 to have a leading 'L' and ending ';'. + */ + +class BadHelloWorld { + 0xCAFEBABE; + 0; // minor version + 52; // version + [31] { // Constant Pool + ; // first element is empty + Utf8 "BadHelloWorld"; // #1 at 0x0A + class #1; // #2 at 0x1A + Utf8 "java/lang/Object"; // #3 at 0x1D + class #3; // #4 at 0x30 + Utf8 "<init>"; // #5 at 0x33 + Utf8 "()V"; // #6 at 0x3C + NameAndType #5 #6; // #7 at 0x42 + Method #4 #7; // #8 at 0x47 + Utf8 "toString"; // #9 at 0x4C + Utf8 "()Ljava/lang/String;"; // #10 at 0x57 + Utf8 "Hello, world!"; // #11 at 0x6E + String #11; // #12 at 0x7E + Utf8 "main"; // #13 at 0x81 + Utf8 "([Ljava/lang/String;)V"; // #14 at 0x88 + Utf8 "LBadHelloWorld;"; // #15 at 0xA1 + class #15; // #16 at 0xB3 + Method #16 #7; // #17 at 0xB6 + Utf8 "java/lang/System"; // #18 at 0xBB + class #18; // #19 at 0xCE + Utf8 "out"; // #20 at 0xD1 + Utf8 "Ljava/io/PrintStream;"; // #21 at 0xD7 + NameAndType #20 #21; // #22 at 0xEF + Field #19 #22; // #23 at 0xF4 + Utf8 "java/io/PrintStream"; // #24 at 0xF9 + class #24; // #25 at 0x010F + Utf8 "println"; // #26 at 0x0112 + Utf8 "(Ljava/lang/Object;)V"; // #27 at 0x011C + NameAndType #26 #27; // #28 at 0x0134 + Method #25 #28; // #29 at 0x0139 + Utf8 "Code"; // #30 at 0x013E + } // Constant Pool + + 0x0021; // access + #2;// this_cpx + #4;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [3] { // methods + { // Member at 0x0151 + 0x0001; // access + #5; // name_cpx + #6; // sig_cpx + [1] { // Attributes + Attr(#30, 17) { // Code at 0x0159 + 1; // max_stack + 1; // max_locals + Bytes[5]{ + 0x2AB70008B1; + }; + [0] { // Traps + } // end Traps + [0] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x0170 + 0x0001; // access + #9; // name_cpx + #10; // sig_cpx + [1] { // Attributes + Attr(#30, 15) { // Code at 0x0178 + 1; // max_stack + 1; // max_locals + Bytes[3]{ + 0x120CB0; + }; + [0] { // Traps + } // end Traps + [0] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member at 0x018D + 0x0089; // access + #13; // name_cpx + #14; // sig_cpx + [1] { // Attributes + Attr(#30, 28) { // Code at 0x0195 + 2; // max_stack + 2; // max_locals + Bytes[16]{ + 0xBB001059B700114C; + 0xB200172BB6001DB1; + }; + [0] { // Traps + } // end Traps + [0] { // Attributes + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [0] { // Attributes + } // Attributes +} // end class BadHelloWorld
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/ClassFile/FormatCheckingTest.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, 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 + * 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. + */ + +/* + * @test + * @bug 8148854 + * @summary Ensure class name loaded by app class loader is format checked by default + * @library /testlibrary + * @compile BadHelloWorld.jcod + * @run main FormatCheckingTest + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class FormatCheckingTest { + public static void main(String args[]) throws Throwable { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("BadHelloWorld"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("java.lang.ClassFormatError: Illegal class name"); + output.shouldHaveExitValue(1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/ClassResolutionFail/Property.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014, 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 + * 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. + */ + +// Class PropertySuper is not found. + +public class Property extends PropertySuper { +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/ClassResolutionFail/PropertySuper.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014, 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 + * 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. + */ + +// Class PropertySuper should be removed. + +public class PropertySuper { + PropertySuper() { System.out.println("remove me for NoClassDefFoundError"); } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/ClassResolutionFail/TestClassResolutionFail.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, 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 + * 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. + */ + +/* + * @test TestClassResolutionFail + * @bug 8023697 + * @summary This tests that failed class resolution doesn't report different class name in detail message for the first and subsequent times + */ + +import java.io.File; + +public class TestClassResolutionFail { + static String message; + public static void test1() throws RuntimeException { + try { + Property p = new Property(); + } catch (LinkageError e) { + message = e.getMessage(); + } + try { + Property p = new Property(); + } catch (LinkageError e) { + System.out.println(e.getMessage()); + if (!e.getMessage().equals(message)) { + throw new RuntimeException("Wrong message: " + message + " != " + e.getMessage()); + } + } + } + public static void main(java.lang.String[] unused) throws Exception { + // Remove PropertySuper class + String testClasses = System.getProperty("test.classes", "."); + File f = new File(testClasses + File.separator + "PropertySuper.class"); + f.delete(); + test1(); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/CommandLine/TraceExceptionsTest.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, 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 + * 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. + */ + +/* + * @test + * @bug 8048933 + * @summary TraceExceptions output should have the exception message - useful for ClassNotFoundExceptions especially + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.*; + +public class TraceExceptionsTest { + public static void main(String[] args) throws Exception { + + if (!Platform.isDebugBuild()) { + System.out.println("Skip the test on product builds since XX:+TraceExceptions is not available on product builds"); + return; + } + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+TraceExceptions", "NoClassFound"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("<a 'java/lang/ClassNotFoundException': NoClassFound>"); + output.shouldNotContain("<a 'java/lang/ClassNotFoundException'>"); + output.shouldHaveExitValue(1); + } +}
--- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Fri Aug 28 07:38:21 2020 +0100 +++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Sat Oct 24 01:11:49 2020 +0100 @@ -374,14 +374,14 @@ * - exit code * Note: the command line is printed by the ProcessTools */ - private void reportDiagnosticSummary() { - String msg = - " stdout: [" + stdout + "];\n" + - " stderr: [" + stderr + "]\n" + - " exitValue = " + getExitValue() + "\n"; + public void reportDiagnosticSummary() { + String msg = + " stdout: [" + stdout + "];\n" + + " stderr: [" + stderr + "]\n" + + " exitValue = " + getExitValue() + "\n"; - System.err.println(msg); - } + System.err.println(msg); + } /**
--- a/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Fri Aug 28 07:38:21 2020 +0100 +++ b/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Sat Oct 24 01:11:49 2020 +0100 @@ -33,7 +33,7 @@ */ public class DoubleTest { - private static final String FLAG_NAME = null; + private static final String FLAG_NAME = "InitialRAMPercentage"; private static final Double[] TESTS = {0d, -0d, -1d, 1d, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 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 + * 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. + */ + + +/* + * @test + * + * @summary JDB problem running monitor command + * VM Testbase keywords: [jpda, jdb] + * VM Testbase readme: + * DESCRIPTION + * Make sure 'monitor unmonitor 1' does not cause ConcurrentModificationException + * in the debugger. + * The jdb sets up line breakpoint at the debugged application. Then one command + * 'monitor unmonitor 1' is set. After resuming the debuggee stops at the breakpoint. + * The test passes if correct reply for "unmonitor 1" commanda is found in jdb stdout + * stream. + * The test consists of two program: + * monitor002.java - launches jdb and debuggee, writes commands to jdb, reads the jdb output, + * monitor002a.java - the debugged application. + * + * @library /vmTestbase + * /test/lib + * @run driver jdk.test.lib.FileInstaller . . + * @build nsk.jdb.monitor.monitor002.monitor002 + * nsk.jdb.monitor.monitor002.monitor002a + * @run main/othervm PropertyResolvingWrapper nsk.jdb.monitor.monitor002.monitor002 + * -arch=${os.family}-${os.simpleArch} + * -waittime=5 + * -debugee.vmkind=java + * -transport.address=dynamic + * -jdb=${test.jdk}/bin/jdb + * -java.options="${test.vm.opts} ${test.java.opts}" + * -workdir=. + * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}" + */ + +package nsk.jdb.monitor.monitor002; + +import nsk.share.*; +import nsk.share.jdb.*; + +import java.io.*; +import java.util.*; + +public class monitor002 extends JdbTest { + + public static void main (String argv[]) { + System.exit(run(argv, System.out) + JCK_STATUS_BASE); + } + + public static int run(String argv[], PrintStream out) { + debuggeeClass = DEBUGGEE_CLASS; + firstBreak = FIRST_BREAK; + lastBreak = LAST_BREAK; + return new monitor002().runTest(argv, out); + } + + static final String PACKAGE_NAME = "nsk.jdb.monitor.monitor002"; + static final String TEST_CLASS = PACKAGE_NAME + ".monitor002"; + static final String DEBUGGEE_CLASS = TEST_CLASS + "a"; + static final String FIRST_BREAK = DEBUGGEE_CLASS + ".main"; + static final String LAST_BREAK = DEBUGGEE_CLASS + ".lastBreak"; + static final int LINE_NUMBER = 47; + + static final String[] CHECKED_COMMANDS = { + JdbCommand.unmonitor + "1" + }; + + protected void runCases() { + String[] reply; + Paragrep grep; + int count; + Vector v; + String found; + + reply = jdb.receiveReplyFor(JdbCommand.stop_at + DEBUGGEE_CLASS + ":" + LINE_NUMBER); + + for (int i = 0; i < CHECKED_COMMANDS.length; i++) { + reply = jdb.receiveReplyFor(JdbCommand.monitor + CHECKED_COMMANDS[i]); + } + + int repliesCount = CHECKED_COMMANDS.length + 1; + reply = jdb.receiveReplyFor(JdbCommand.cont, true, repliesCount); + + reply = jdb.receiveReplyFor(JdbCommand.monitor); + if (reply.length != 1) { + log.complain("Expected no active monitors after exectuting monitored command: " + CHECKED_COMMANDS[0]); + success = false; + } + + jdb.contToExit(1); + + reply = jdb.getTotalReply(); + + if (!checkCommands(reply)) { + success = false; + } + } + + private boolean checkCommands(String[] reply) { + Paragrep grep; + boolean result = true; + int count; + + grep = new Paragrep(reply); + + if ((count = grep.find("Unmonitoring 1: unmonitor 1")) != 1) { + log.complain("Wrong number of execution of monitored command: " + CHECKED_COMMANDS[0]); + log.complain(" Expected: 1; found: " + count); + result = false; + } + + return result; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/vmTestbase/nsk/jdb/monitor/monitor002/monitor002a.java Sat Oct 24 01:11:49 2020 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 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 + * 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. + */ + +package nsk.jdb.monitor.monitor002; + +import nsk.share.*; +import nsk.share.jpda.*; +import nsk.share.jdb.*; + +import java.io.*; + +// THIS TEST IS LINE NUMBER SENSITIVE + +/* This is debuggee aplication */ +public class monitor002a { + static monitor002a _monitor002a = new monitor002a(); + + public static void main(String args[]) { + System.exit(monitor002.JCK_STATUS_BASE + _monitor002a.runIt(args, System.out)); + } + + static void lastBreak () {} + + public int runIt(String args[], PrintStream out) { + JdbArgumentHandler argumentHandler = new JdbArgumentHandler(args); + Log log = new Log(out, argumentHandler); + int localInt = 0; // monitor002.LINE_NUMBER + localInt++; // dummy breakpoint + log.display("Debuggee PASSED"); + return monitor002.PASSED; + } +}