This commit is contained in:
Jesper Wilhelmsson 2021-01-14 01:29:47 +00:00
commit 51e14f2e2a
48 changed files with 868 additions and 227 deletions

@ -1,6 +1,6 @@
//
// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, 2020, Red Hat, Inc. All rights reserved.
// Copyright (c) 2014, 2021, 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
@ -1916,7 +1916,7 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
__ bind(L_skip_barrier);
}
if (UseSVE > 0 && C->max_vector_size() >= 16) {
if (C->max_vector_size() >= 16) {
__ reinitialize_ptrue();
}
@ -3798,11 +3798,9 @@ encode %{
}
}
if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) {
// Only non uncommon_trap calls need to reinitialize ptrue.
if (uncommon_trap_request() == 0) {
__ reinitialize_ptrue();
}
// Only non uncommon_trap calls need to reinitialize ptrue.
if (Compile::current()->max_vector_size() >= 16 && uncommon_trap_request() == 0) {
__ reinitialize_ptrue();
}
%}
@ -3813,7 +3811,7 @@ encode %{
if (call == NULL) {
ciEnv::current()->record_failure("CodeCache is full");
return;
} else if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) {
} else if (Compile::current()->max_vector_size() >= 16) {
__ reinitialize_ptrue();
}
%}
@ -3851,7 +3849,7 @@ encode %{
__ bind(retaddr);
__ add(sp, sp, 2 * wordSize);
}
if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) {
if (Compile::current()->max_vector_size() >= 16) {
__ reinitialize_ptrue();
}
%}
@ -3864,7 +3862,7 @@ encode %{
enc_class aarch64_enc_ret() %{
C2_MacroAssembler _masm(&cbuf);
#ifdef ASSERT
if (UseSVE > 0 && Compile::current()->max_vector_size() >= 16) {
if (Compile::current()->max_vector_size() >= 16) {
__ verify_ptrue();
}
#endif

@ -1,5 +1,5 @@
// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, Arm Limited. All rights reserved.
// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, 2021, Arm Limited. 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
@ -84,9 +84,11 @@ instruct reinterpretD2X(vecX dst, vecD src)
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8);
match(Set dst (VectorReinterpret src));
ins_cost(INSN_COST);
format %{ " # reinterpret $dst,$src" %}
format %{ " # reinterpret $dst,$src\t# D2X" %}
ins_encode %{
// If register is the same, then move is not needed.
// If registers are the same, no register move is required - the
// upper 64 bits of 'src' are expected to have been initialized
// to zero.
if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) {
__ orr(as_FloatRegister($dst$$reg), __ T8B,
as_FloatRegister($src$$reg),
@ -102,14 +104,13 @@ instruct reinterpretX2D(vecD dst, vecX src)
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16);
match(Set dst (VectorReinterpret src));
ins_cost(INSN_COST);
format %{ " # reinterpret $dst,$src" %}
format %{ " # reinterpret $dst,$src\t# X2D" %}
ins_encode %{
// If register is the same, then move is not needed.
if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) {
__ orr(as_FloatRegister($dst$$reg), __ T8B,
as_FloatRegister($src$$reg),
as_FloatRegister($src$$reg));
}
// Resize the vector from 128-bits to 64-bits. The higher 64-bits of
// the "dst" register must be cleared to zero.
__ orr(as_FloatRegister($dst$$reg), __ T8B,
as_FloatRegister($src$$reg),
as_FloatRegister($src$$reg));
%}
ins_pipe(vlogical64);
%}

@ -1,5 +1,5 @@
// Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, Arm Limited. All rights reserved.
// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2020, 2021, Arm Limited. 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
@ -97,16 +97,18 @@ dnl $1 $2
REINTERPRET(D, 8)
REINTERPRET(X, 16)
dnl
define(`REINTERPRET_X', `
instruct reinterpret$1`'2$2`'(vec$2 dst, vec$1 src)
instruct reinterpretD2X(vecX dst, vecD src)
%{
predicate(n->bottom_type()->is_vect()->length_in_bytes() == $3 &&
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == $4);
predicate(n->bottom_type()->is_vect()->length_in_bytes() == 16 &&
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 8);
match(Set dst (VectorReinterpret src));
ins_cost(INSN_COST);
format %{ " # reinterpret $dst,$src" %}
format %{ " # reinterpret $dst,$src\t# D2X" %}
ins_encode %{
// If register is the same, then move is not needed.
// If registers are the same, no register move is required - the
// upper 64 bits of 'src' are expected to have been initialized
// to zero.
if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) {
__ orr(as_FloatRegister($dst$$reg), __ T8B,
as_FloatRegister($src$$reg),
@ -114,11 +116,24 @@ instruct reinterpret$1`'2$2`'(vec$2 dst, vec$1 src)
}
%}
ins_pipe(vlogical64);
%}')dnl
dnl $1 $2 $3 $4
REINTERPRET_X(D, X, 16, 8)
REINTERPRET_X(X, D, 8, 16)
dnl
%}
instruct reinterpretX2D(vecD dst, vecX src)
%{
predicate(n->bottom_type()->is_vect()->length_in_bytes() == 8 &&
n->in(1)->bottom_type()->is_vect()->length_in_bytes() == 16);
match(Set dst (VectorReinterpret src));
ins_cost(INSN_COST);
format %{ " # reinterpret $dst,$src\t# X2D" %}
ins_encode %{
// Resize the vector from 128-bits to 64-bits. The higher 64-bits of
// the "dst" register must be cleared to zero.
__ orr(as_FloatRegister($dst$$reg), __ T8B,
as_FloatRegister($src$$reg),
as_FloatRegister($src$$reg));
%}
ins_pipe(vlogical64);
%}
// ------------------------------ Vector cast -------------------------------
dnl

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, 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
@ -354,6 +354,10 @@ public:
~ZSaveLiveRegisters() {
// Restore registers
__ pop_fp(_fp_regs, sp);
// External runtime call may clobber ptrue reg
__ reinitialize_ptrue();
__ pop(_gp_regs, sp);
}
};
@ -428,11 +432,6 @@ void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, Z
ZSetupArguments setup_arguments(masm, stub);
__ mov(rscratch1, stub->slow_path());
__ blr(rscratch1);
if (UseSVE > 0) {
// Reinitialize the ptrue predicate register, in case the external runtime
// call clobbers ptrue reg, as we may return to SVE compiled code.
__ reinitialize_ptrue();
}
}
// Stub exit
__ b(*stub->continuation());

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2014, 2021, 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
@ -2663,6 +2663,8 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize)));
}
reinitialize_ptrue();
pop(call_clobbered_registers() - exclude, sp);
}
@ -2699,6 +2701,11 @@ void MacroAssembler::pop_CPU_state(bool restore_vectors, bool use_sve,
ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
as_FloatRegister(i+3), restore_vectors ? T2D : T1D, Address(post(sp, step)));
}
if (restore_vectors) {
reinitialize_ptrue();
}
pop(0x3fffffff, sp); // integer registers except lr & sp
}
@ -5309,7 +5316,9 @@ void MacroAssembler::verify_sve_vector_length() {
void MacroAssembler::verify_ptrue() {
Label verify_ok;
assert(UseSVE > 0, "should only be used for SVE");
if (!UseSVE) {
return;
}
sve_cntp(rscratch1, B, ptrue, ptrue); // get true elements count.
sve_dec(rscratch1, B);
cbz(rscratch1, verify_ok);

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, 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
@ -967,7 +967,9 @@ public:
void verify_sve_vector_length();
void reinitialize_ptrue() {
sve_ptrue(ptrue, B);
if (UseSVE > 0) {
sve_ptrue(ptrue, B);
}
}
void verify_ptrue();

@ -1,6 +1,6 @@
/*
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2014, 2021, 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
@ -2781,12 +2781,6 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
__ membar(Assembler::LoadLoad | Assembler::LoadStore);
if (UseSVE > 0 && save_vectors) {
// Reinitialize the ptrue predicate register, in case the external runtime
// call clobbers ptrue reg, as we may return to SVE compiled code.
__ reinitialize_ptrue();
}
__ ldr(rscratch1, Address(rthread, Thread::pending_exception_offset()));
__ cbz(rscratch1, noException);
@ -3009,6 +3003,9 @@ void OptoRuntime::generate_exception_blob() {
// handle_exception_C is a special VM call which does not require an explicit
// instruction sync afterwards.
// May jump to SVE compiled code
__ reinitialize_ptrue();
// Set an oopmap for the call site. This oopmap will only be used if we
// are unwinding the stack. Hence, all locations will be dead.
// Callee-saved registers will be the same as the frame above (i.e.,

@ -1,6 +1,6 @@
/*
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* Copyright (c) 2014, 2021, 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
@ -490,11 +490,10 @@ class StubGenerator: public StubCodeGenerator {
__ call_VM_leaf(CAST_FROM_FN_PTR(address,
SharedRuntime::exception_handler_for_return_address),
rthread, c_rarg1);
if (UseSVE > 0 ) {
// Reinitialize the ptrue predicate register, in case the external runtime
// call clobbers ptrue reg, as we may return to SVE compiled code.
__ reinitialize_ptrue();
}
// Reinitialize the ptrue predicate register, in case the external runtime
// call clobbers ptrue reg, as we may return to SVE compiled code.
__ reinitialize_ptrue();
// we should not really care that lr is no longer the callee
// address. we saved the value the handler needs in r19 so we can
// just copy it to r3. however, the C2 handler will push its own
@ -5655,11 +5654,9 @@ class StubGenerator: public StubCodeGenerator {
__ reset_last_Java_frame(true);
if (UseSVE > 0) {
// Reinitialize the ptrue predicate register, in case the external runtime
// call clobbers ptrue reg, as we may return to SVE compiled code.
__ reinitialize_ptrue();
}
// Reinitialize the ptrue predicate register, in case the external runtime
// call clobbers ptrue reg, as we may return to SVE compiled code.
__ reinitialize_ptrue();
__ leave();

@ -203,7 +203,12 @@ void ciMethodData::load_data() {
// _extra_data_size = extra_data_limit - extra_data_base
// total_size = _data_size + _extra_data_size
// args_data_limit = data_base + total_size - parameter_data_size
#ifndef ZERO
// Some Zero platforms do not have expected alignment, and do not use
// this code. static_assert would still fire and fail for them.
static_assert(sizeof(_orig) % HeapWordSize == 0, "align");
#endif
Copy::disjoint_words_atomic((HeapWord*) &mdo->_compiler_counters,
(HeapWord*) &_orig,
sizeof(_orig) / HeapWordSize);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
@ -460,19 +460,34 @@ bool ClassListParser::is_matching_cp_entry(constantPoolHandle &pool, int cp_inde
}
return true;
}
void ClassListParser::resolve_indy(Symbol* class_name_symbol, TRAPS) {
ClassListParser::resolve_indy_impl(class_name_symbol, THREAD);
if (HAS_PENDING_EXCEPTION) {
ResourceMark rm(THREAD);
char* ex_msg = (char*)"";
oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
if (message != NULL) {
ex_msg = java_lang_String::as_utf8_string(message);
}
log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s",
class_name_symbol->as_C_string(),
PENDING_EXCEPTION->klass()->external_name(),
ex_msg);
CLEAR_PENDING_EXCEPTION;
}
}
void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) {
Handle class_loader(THREAD, SystemDictionary::java_system_loader());
Handle protection_domain;
Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, THREAD); // FIXME should really be just a lookup
Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); // FIXME should really be just a lookup
if (klass != NULL && klass->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(klass);
if (SystemDictionaryShared::has_class_failed_verification(ik)) {
// don't attempt to resolve indy on classes that has previously failed verification
return;
}
MetaspaceShared::try_link_class(ik, THREAD);
assert(!HAS_PENDING_EXCEPTION, "unexpected exception");
MetaspaceShared::try_link_class(ik, CHECK);
ConstantPool* cp = ik->constants();
ConstantPoolCache* cpcache = cp->cache();
@ -484,36 +499,23 @@ void ClassListParser::resolve_indy(Symbol* class_name_symbol, TRAPS) {
constantPoolHandle pool(THREAD, cp);
if (pool->tag_at(pool_index).is_invoke_dynamic()) {
BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index);
Handle bsm = bootstrap_specifier.resolve_bsm(THREAD);
Handle bsm = bootstrap_specifier.resolve_bsm(CHECK);
if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) {
log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index);
continue;
}
if (is_matching_cp_entry(pool, pool_index, THREAD)) {
bool matched = is_matching_cp_entry(pool, pool_index, CHECK);
if (matched) {
found = true;
CallInfo info;
bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, THREAD);
bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK);
if (!is_done) {
// resolve it
Handle recv;
LinkResolver::resolve_invoke(info, recv, pool, indy_index, Bytecodes::_invokedynamic, THREAD);
LinkResolver::resolve_invoke(info, recv, pool, indy_index, Bytecodes::_invokedynamic, CHECK);
break;
}
cpce->set_dynamic_call(pool, info);
if (HAS_PENDING_EXCEPTION) {
ResourceMark rm(THREAD);
tty->print("resolve_indy for class %s has", class_name_symbol->as_C_string());
oop message = java_lang_Throwable::message(PENDING_EXCEPTION);
if (message != NULL) {
char* ex_msg = java_lang_String::as_utf8_string(message);
tty->print_cr(" exception pending '%s %s'",
PENDING_EXCEPTION->klass()->external_name(), ex_msg);
} else {
tty->print_cr(" exception pending %s ",
PENDING_EXCEPTION->klass()->external_name());
}
exit(1);
}
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
@ -114,6 +114,7 @@ class ClassListParser : public StackObj {
bool is_matching_cp_entry(constantPoolHandle &pool, int cp_index, TRAPS);
void resolve_indy(Symbol* class_name_symbol, TRAPS);
void resolve_indy_impl(Symbol* class_name_symbol, TRAPS);
public:
ClassListParser(const char* file);
~ClassListParser();

@ -306,12 +306,22 @@ AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {
return blob;
}
void* VtableBlob::operator new(size_t s, unsigned size) throw() {
// Handling of allocation failure stops compilation and prints a bunch of
// stuff, which requires unlocking the CodeCache_lock, so that the Compile_lock
// can be locked, and then re-locking the CodeCache_lock. That is not safe in
// this context as we hold the CompiledICLocker. So we just don't handle code
// cache exhaustion here; we leave that for a later allocation that does not
// hold the CompiledICLocker.
return CodeCache::allocate(size, CodeBlobType::NonNMethod, false /* handle_alloc_failure */);
}
VtableBlob::VtableBlob(const char* name, int size) :
BufferBlob(name, size) {
}
VtableBlob* VtableBlob::create(const char* name, int buffer_size) {
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
assert(JavaThread::current()->thread_state() == _thread_in_vm, "called with the wrong state");
VtableBlob* blob = NULL;
unsigned int size = sizeof(VtableBlob);
@ -320,8 +330,21 @@ VtableBlob* VtableBlob::create(const char* name, int buffer_size) {
size += align_up(buffer_size, oopSize);
assert(name != NULL, "must provide a name");
{
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
if (!CodeCache_lock->try_lock()) {
// If we can't take the CodeCache_lock, then this is a bad time to perform the ongoing
// IC transition to megamorphic, for which this stub will be needed. It is better to
// bail out the transition, and wait for a more opportune moment. Not only is it not
// worth waiting for the lock blockingly for the megamorphic transition, it might
// also result in a deadlock to blockingly wait, when concurrent class unloading is
// performed. At this point in time, the CompiledICLocker is taken, so we are not
// allowed to blockingly wait for the CodeCache_lock, as these two locks are otherwise
// consistently taken in the opposite order. Bailing out results in an IC transition to
// the clean state instead, which will cause subsequent calls to retry the transitioning
// eventually.
return NULL;
}
blob = new (size) VtableBlob(name, size);
CodeCache_lock->unlock();
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();

@ -441,6 +441,8 @@ class VtableBlob: public BufferBlob {
private:
VtableBlob(const char*, int);
void* operator new(size_t s, unsigned size) throw();
public:
// Creation
static VtableBlob* create(const char* name, int buffer_size);

@ -483,7 +483,7 @@ CodeBlob* CodeCache::next_blob(CodeHeap* heap, CodeBlob* cb) {
* run the constructor for the CodeBlob subclass he is busy
* instantiating.
*/
CodeBlob* CodeCache::allocate(int size, int code_blob_type, int orig_code_blob_type) {
CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool handle_alloc_failure, int orig_code_blob_type) {
// Possibly wakes up the sweeper thread.
NMethodSweeper::report_allocation(code_blob_type);
assert_locked_or_safepoint(CodeCache_lock);
@ -531,11 +531,13 @@ CodeBlob* CodeCache::allocate(int size, int code_blob_type, int orig_code_blob_t
tty->print_cr("Extension of %s failed. Trying to allocate in %s.",
heap->name(), get_code_heap(type)->name());
}
return allocate(size, type, orig_code_blob_type);
return allocate(size, type, handle_alloc_failure, orig_code_blob_type);
}
}
MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CompileBroker::handle_full_code_cache(orig_code_blob_type);
if (handle_alloc_failure) {
MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CompileBroker::handle_full_code_cache(orig_code_blob_type);
}
return NULL;
}
if (PrintCodeCacheExtension) {

@ -136,7 +136,7 @@ class CodeCache : AllStatic {
static const GrowableArray<CodeHeap*>* nmethod_heaps() { return _nmethod_heaps; }
// Allocation/administration
static CodeBlob* allocate(int size, int code_blob_type, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob
static CodeBlob* allocate(int size, int code_blob_type, bool handle_alloc_failure = true, int orig_code_blob_type = CodeBlobType::All); // allocates a new CodeBlob
static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled
static int alignment_unit(); // guaranteed alignment of all CodeBlobs
static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)

@ -65,13 +65,14 @@ void PretouchTask::work(uint worker_id) {
void PretouchTask::pretouch(const char* task_name, char* start_address, char* end_address,
size_t page_size, WorkGang* pretouch_gang) {
// Chunk size should be at least (unmodified) page size as using multiple threads
// pretouch on a single page can decrease performance.
size_t chunk_size = MAX2(PretouchTask::chunk_size(), page_size);
#ifdef LINUX
// When using THP we need to always pre-touch using small pages as the OS will
// initially always use small pages.
page_size = UseTransparentHugePages ? (size_t)os::vm_page_size() : page_size;
#endif
size_t chunk_size = MAX2(PretouchTask::chunk_size(), page_size);
PretouchTask task(task_name, start_address, end_address, page_size, chunk_size);
size_t total_bytes = pointer_delta(end_address, start_address, sizeof(char));

@ -47,8 +47,9 @@ public:
// Visit all oop*s and apply the given closure.
static void oops_do(OopClosure* closure);
// Parallel version. Uses ergo_workers(), active workers, and
// phase_time's max_threads to determine the number of threads to use.
// Parallel version. Uses ergo_workers() to determine the number of
// threads to use, limited by the total workers and phase_times'
// max_threads.
// IsAlive must be derived from BoolObjectClosure.
// KeepAlive must be derived from OopClosure.
template<typename IsAlive, typename KeepAlive>
@ -57,8 +58,9 @@ public:
KeepAlive* keep_alive,
WeakProcessorPhaseTimes* phase_times);
// Convenience parallel version. Uses ergo_workers() and active workers
// to determine the number of threads to run. Implicitly logs phase times.
// Convenience parallel version. Uses ergo_workers() to determine the
// number of threads to use, limited by the total workers. Implicitly
// logs phase times.
// IsAlive must be derived from BoolObjectClosure.
// KeepAlive must be derived from OopClosure.
template<typename IsAlive, typename KeepAlive>
@ -67,7 +69,10 @@ public:
KeepAlive* keep_alive,
uint indent_log);
// Uses the total number of weak references and ReferencesPerThread to
// determine the number of threads to use, limited by max_workers.
static uint ergo_workers(uint max_workers);
class Task;
private:

@ -133,7 +133,7 @@ void WeakProcessor::weak_oops_do(WorkGang* workers,
WeakProcessorPhaseTimes* phase_times) {
WeakProcessorTimeTracker tt(phase_times);
uint nworkers = ergo_workers(MIN2(workers->active_workers(),
uint nworkers = ergo_workers(MIN2(workers->total_workers(),
phase_times->max_threads()));
GangTask task("Weak Processor", is_alive, keep_alive, phase_times, nworkers);
@ -146,7 +146,7 @@ void WeakProcessor::weak_oops_do(WorkGang* workers,
IsAlive* is_alive,
KeepAlive* keep_alive,
uint indent_log) {
uint nworkers = ergo_workers(workers->active_workers());
uint nworkers = ergo_workers(workers->total_workers());
WeakProcessorPhaseTimes pt(nworkers);
weak_oops_do(workers, is_alive, keep_alive, &pt);
pt.log_print_phases(indent_log);

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
@ -406,15 +406,14 @@ void ConstantPool::remove_unshareable_info() {
_flags |= (_on_stack | _is_shared);
int num_klasses = 0;
for (int index = 1; index < length(); index++) { // Index 0 is unused
if (!DynamicDumpSharedSpaces) {
assert(!tag_at(index).is_unresolved_klass_in_error(), "This must not happen during static dump time");
} else {
if (tag_at(index).is_unresolved_klass_in_error() ||
tag_at(index).is_method_handle_in_error() ||
tag_at(index).is_method_type_in_error() ||
tag_at(index).is_dynamic_constant_in_error()) {
tag_at_put(index, JVM_CONSTANT_UnresolvedClass);
}
if (tag_at(index).is_unresolved_klass_in_error()) {
tag_at_put(index, JVM_CONSTANT_UnresolvedClass);
} else if (tag_at(index).is_method_handle_in_error()) {
tag_at_put(index, JVM_CONSTANT_MethodHandle);
} else if (tag_at(index).is_method_type_in_error()) {
tag_at_put(index, JVM_CONSTANT_MethodType);
} else if (tag_at(index).is_dynamic_constant_in_error()) {
tag_at_put(index, JVM_CONSTANT_Dynamic);
}
if (tag_at(index).is_klass()) {
// This class was resolved as a side effect of executing Java code

@ -1984,7 +1984,11 @@ public:
public:
CompilerCounters() : _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0) {
#ifndef ZERO
// Some Zero platforms do not have expected alignment, and do not use
// this code. static_assert would still fire and fail for them.
static_assert(sizeof(_trap_hist) % HeapWordSize == 0, "align");
#endif
uint size_in_words = sizeof(_trap_hist) / HeapWordSize;
Copy::zero_to_words((HeapWord*) &_trap_hist, size_in_words);
}

@ -1221,26 +1221,6 @@ void PhaseCFG::verify() const {
if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
}
// Verify that memory-writing nodes (such as stores and calls) are placed
// in their original loop L (given by the control input) or in an ancestor
// of L. This is guaranteed by the freq. estimation model for reducible
// CFGs, and by special handling in PhaseCFG::schedule_late() otherwise.
if (n->is_Mach() && n->bottom_type()->has_memory() && n->in(0) != NULL) {
Block* original_block = find_block_for_node(n->in(0));
assert(original_block != NULL, "missing block for memory-writing node");
CFGLoop* original_or_ancestor = original_block->_loop;
assert(block->_loop != NULL && original_or_ancestor != NULL, "no loop");
bool found = false;
do {
if (block->_loop == original_or_ancestor) {
found = true;
break;
}
original_or_ancestor = original_or_ancestor->parent();
} while (original_or_ancestor != NULL);
assert(found, "memory-writing node is not placed in its original loop "
"or an ancestor of it");
}
if (n->needs_anti_dependence_check()) {
verify_anti_dependences(block, n);
}

@ -2045,10 +2045,12 @@ const Type* LoadNode::Value(PhaseGVN* phase) const {
}
}
if (is_instance) {
bool is_vect = (_type->isa_vect() != NULL);
if (is_instance && !is_vect) {
// If we have an instance type and our memory input is the
// programs's initial memory state, there is no matching store,
// so just return a zero of the appropriate type
// so just return a zero of the appropriate type -
// except if it is vectorized - then we have no zero constant.
Node *mem = in(MemNode::Memory);
if (mem->is_Parm() && mem->in(0)->is_Start()) {
assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm");

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2021, 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
@ -1198,7 +1198,11 @@ void VectorMaskCmpNode::dump_spec(outputStream *st) const {
Node* VectorReinterpretNode::Identity(PhaseGVN *phase) {
Node* n = in(1);
if (n->Opcode() == Op_VectorReinterpret) {
if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0) {
// "VectorReinterpret (VectorReinterpret node) ==> node" if:
// 1) Types of 'node' and 'this' are identical
// 2) Truncations are not introduced by the first VectorReinterpret
if (Type::cmp(bottom_type(), n->in(1)->bottom_type()) == 0 &&
length_in_bytes() <= n->bottom_type()->is_vect()->length_in_bytes()) {
return n->in(1);
}
}

@ -793,7 +793,7 @@ public abstract class Buffer {
@Override
public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegmentProxy segment) {
return new HeapByteBuffer(hb, offset, capacity, segment);
return new HeapByteBuffer(hb, -1, 0, capacity, capacity, offset, segment);
}
@Override

@ -203,7 +203,7 @@ class Direct$Type$Buffer$RW$$BO$
{
#if[rw]
super(mark, pos, lim, cap, segment);
address = db.address() + off;
address = ((Buffer)db).address + off;
#if[byte]
cleaner = null;
#end[byte]

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, 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
@ -1169,7 +1169,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* {@code UnsupportedOperationException} to be thrown. There are no
* guarantees on the implementation type or serializability of the returned List.
*
* <p>The returned instance may be <a href="../lang/doc-files/ValueBased.html">value-based</a>.
* <p>The returned instance may be <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
* Callers should make no assumptions about the identity of the returned instances.
* Identity-sensitive operations on these instances (reference equality ({@code ==}),
* identity hash code, and synchronization) are unreliable and should be avoided.

@ -762,8 +762,11 @@ public class BasicButtonUI extends ButtonUI{
}
/**
* Find the new toggle button that focus needs to be
* Find the new toggle/radio button that focus needs to be
* moved to in the group, select the button
* In case of radio button, setPressed and setArmed is called
* on the button model, so that Action set on button is performed
* on selecting the button
*
* @param next, indicate if it's arrow up/left or down/right
*/
@ -785,12 +788,16 @@ public class BasicButtonUI extends ButtonUI{
if (newSelectedBtn != null &&
(newSelectedBtn != activeBtn)) {
ButtonModel btnModel = newSelectedBtn.getModel();
btnModel.setPressed(true);
btnModel.setArmed(true);
if (newSelectedBtn instanceof JRadioButton) {
btnModel.setPressed(true);
btnModel.setArmed(true);
}
newSelectedBtn.requestFocusInWindow();
newSelectedBtn.setSelected(true);
btnModel.setPressed(false);
btnModel.setArmed(false);
if (newSelectedBtn instanceof JRadioButton) {
btnModel.setPressed(false);
btnModel.setArmed(false);
}
}
}
}

@ -112,6 +112,7 @@ public class Resolve {
private final boolean allowLocalVariableTypeInference;
private final boolean allowYieldStatement;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
final boolean dumpMethodReferenceSearchResults;
WriteableScope polymorphicSignatureScope;
@ -151,6 +152,7 @@ public class Resolve {
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
allowModules = Feature.MODULES.allowedInSource(source);
allowRecords = Feature.RECORDS.allowedInSource(source);
dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
}
/** error symbols, which are returned when resolution fails
@ -2777,7 +2779,7 @@ public class Resolve {
// Check that there is already a method symbol for the method
// type and owner
if (types.isSameType(mtype, sym.type) &&
spMethod.owner == sym.owner) {
spMethod.owner == sym.owner) {
return sym;
}
}
@ -3090,6 +3092,9 @@ public class Resolve {
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
site.tsym, boundSearchResolveContext, boundLookupHelper);
ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext);
if (dumpMethodReferenceSearchResults) {
dumpMethodReferenceSearchResults(referenceTree, boundSearchResolveContext, boundSym, true);
}
//step 2 - unbound lookup
Symbol unboundSym = methodNotFound;
@ -3103,6 +3108,9 @@ public class Resolve {
unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
site.tsym, unboundSearchResolveContext, unboundLookupHelper);
unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext);
if (dumpMethodReferenceSearchResults) {
dumpMethodReferenceSearchResults(referenceTree, unboundSearchResolveContext, unboundSym, false);
}
}
//merge results
@ -3126,6 +3134,42 @@ public class Resolve {
return res;
}
private void dumpMethodReferenceSearchResults(JCMemberReference referenceTree,
MethodResolutionContext resolutionContext,
Symbol bestSoFar,
boolean bound) {
ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
int pos = 0;
int mostSpecificPos = -1;
for (Candidate c : resolutionContext.candidates) {
if (resolutionContext.step != c.step || !c.isApplicable()) {
continue;
} else {
JCDiagnostic subDiag = null;
if (c.sym.type.hasTag(FORALL)) {
subDiag = diags.fragment(Fragments.PartialInstSig(c.mtype));
}
String key = subDiag == null ?
"applicable.method.found.2" :
"applicable.method.found.3";
subDiags.append(diags.fragment(key, pos,
c.sym.isStatic() ? Fragments.Static : Fragments.NonStatic, c.sym, subDiag));
if (c.sym == bestSoFar)
mostSpecificPos = pos;
pos++;
}
}
JCDiagnostic main = diags.note(
log.currentSource(),
referenceTree,
"method.ref.search.results.multi",
bound ? Fragments.Bound : Fragments.Unbound,
referenceTree.toString(), mostSpecificPos);
JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
log.report(d);
}
/**
* This class is used to represent a method reference lookup result. It keeps track of two
* things: (i) the symbol found during a method reference lookup and (ii) the static kind
@ -3280,12 +3324,12 @@ public class Resolve {
@Override
ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
if (boundRes.hasKind(StaticKind.STATIC) &&
if (boundRes.isSuccess() && boundRes.sym.isStatic() &&
(!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
//the first search produces a static method and no non-static method is applicable
//during the second search
return boundRes;
} else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
} else if (unboundRes.isSuccess() && !unboundRes.sym.isStatic() &&
(!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
//the second search produces a non-static method and no static method is applicable
//during the first search

@ -741,13 +741,13 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER)
public ClassLoader getClassLoader(Location location) {
checkNotModuleOrientedLocation(location);
Collection<? extends Path> searchPath = getLocationAsPaths(location);
if (searchPath == null)
Iterable<? extends File> path = getLocation(location);
if (path == null)
return null;
ListBuffer<URL> lb = new ListBuffer<>();
for (Path p : searchPath) {
for (File f: path) {
try {
lb.append(p.toUri().toURL());
lb.append(f.toURI().toURL());
} catch (MalformedURLException e) {
throw new AssertionError(e);
}

@ -3073,6 +3073,37 @@ compiler.note.deferred.method.inst=\
compiler.note.verbose.l2m.deduplicate=\
deduplicating lambda implementation method {0}
########################################
# Diagnostics for method reference search
# results used by Resolve (debug only)
########################################
# 0: fragment, 1: string, 2: number
compiler.note.method.ref.search.results.multi=\
{0} search results for {1}, with most specific {2}\n\
applicable candidates:
# 0: number, 1: fragment, 2: symbol
compiler.misc.applicable.method.found.2=\
#{0} applicable method found: {1} {2}
# 0: number, 1: fragment, 2: symbol, 3: message segment
compiler.misc.applicable.method.found.3=\
#{0} applicable method found: {1} {2}\n\
({3})
compiler.misc.static=\
static
compiler.misc.non.static=\
non-static
compiler.misc.bound=\
bound
compiler.misc.unbound=\
unbound
########################################
# Diagnostics for where clause implementation
# used by the RichDiagnosticFormatter.

@ -218,7 +218,7 @@ doclet.help.serial_form.body=\
doclet.help.constants.body=\
The {0} page lists the static final fields and their values.
doclet.help.systemProperties.body=\
The {0) page lists references to system properties.
The {0} page lists references to system properties.
doclet.help.footnote=\
This help file applies to API documentation generated by the standard doclet.
doclet.help.enum.intro=\

@ -84,6 +84,7 @@ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64
# :hotspot_runtime
runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java 8253437 windows-x64
runtime/cds/DeterministicDump.java 8253495 generic-all
runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64
runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all

@ -1,5 +1,5 @@
#
# Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2013, 2021, 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
@ -335,6 +335,7 @@ hotspot_appcds_dynamic = \
-runtime/cds/appcds/LambdaEagerInit.java \
-runtime/cds/appcds/LambdaProxyClasslist.java \
-runtime/cds/appcds/LambdaVerificationFailedDuringDump.java \
-runtime/cds/appcds/LambdaWithOldClass.java \
-runtime/cds/appcds/LongClassListPath.java \
-runtime/cds/appcds/LotsOfClasses.java \
-runtime/cds/appcds/MismatchedPathTriggerMemoryRelease.java \

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021, 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 8258272
* @summary Test that LoadVectorMaskedNodes works when the source array is known to only contain zeros
*
* @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,*::testArrayCopy*
* compiler.arraycopy.TestArrayCopyMaskedWithZeroSrc
*/
package compiler.arraycopy;
import java.util.*;
public class TestArrayCopyMaskedWithZeroSrc {
public static void main(String[] args) {
TestArrayCopyMaskedWithZeroSrc t = new TestArrayCopyMaskedWithZeroSrc();
t.test();
}
void test() {
for (int i = 0; i < 20000; i++) {
testArrayCopy1(3);
}
}
// src is allocated locally - it is known it only contains zeros.
// The copy of will exapnd into LoadVectorMasked on AVX512 machines
// LoadNode::value will try to replace the load from src with a zero constant.
byte [] testArrayCopy1(int partial_len) {
byte [] src = new byte[5];
byte [] dest = Arrays.copyOf(src, partial_len);
return dest;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, 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
@ -44,7 +44,7 @@ public class BadBSM {
TestCommon.list("WrongBSM",
"@lambda-proxy WrongBSM 7"),
"-Xlog:cds+lambda=debug");
out.shouldHaveExitValue(0);
out.shouldContain( "is_supported_invokedynamic check failed for cp_index 7");
out.shouldHaveExitValue(0)
.shouldContain("resolve_indy for class WrongBSM has encountered exception: java.lang.NoSuchMethodError");
}
}

@ -0,0 +1,80 @@
/*
* Copyright (c) 2021, 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 8259275
* @summary VM should not crash during CDS dump and run time when a lambda
* expression references an old version of class.
* @requires vm.cds
* @library /test/lib
* @compile test-classes/OldClass.jasm
* @compile test-classes/LambdaWithOldClassApp.java
* @run driver LambdaWithOldClass
*/
import jdk.test.lib.cds.CDSOptions;
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public class LambdaWithOldClass {
public static void main(String[] args) throws Exception {
String mainClass = "LambdaWithOldClassApp";
String namePrefix = "lambdawitholdclass";
JarBuilder.build(namePrefix, mainClass, "OldClass", "TestInterface");
String appJar = TestCommon.getTestJar(namePrefix + ".jar");
String classList = namePrefix + ".list";
String archiveName = namePrefix + ".jsa";
// dump class list
ProcessBuilder pb = ProcessTools.createTestJvm(
"-XX:DumpLoadedClassList=" + classList,
"-cp", appJar,
mainClass);
OutputAnalyzer output = TestCommon.executeAndLog(pb, namePrefix);
output.shouldHaveExitValue(0);
// create archive with the class list
CDSOptions opts = (new CDSOptions())
.addPrefix("-XX:ExtraSharedClassListFile=" + classList,
"-cp", appJar,
"-Xlog:class+load,cds")
.setArchiveName(archiveName);
CDSTestUtils.createArchiveAndCheck(opts);
// run with archive
CDSOptions runOpts = (new CDSOptions())
.addPrefix("-cp", appJar, "-Xlog:class+load,cds=debug")
.setArchiveName(archiveName)
.setUseVersion(false)
.addSuffix(mainClass);
output = CDSTestUtils.runWithArchive(runOpts);
output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file")
.shouldMatch(".class.load. LambdaWithOldClassApp[$][$]Lambda[$].*/0x.*source:.*LambdaWithOldClassApp")
.shouldHaveExitValue(0);
}
}

@ -0,0 +1,38 @@
/*
* Copyright (c) 2021, 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.
*
*/
interface TestInterface {
public void apply(OldClass c);
}
public class LambdaWithOldClassApp {
public static void main(String args[]) {
doit((c) -> {
System.out.println("c = " + c);
});
}
static void doit(TestInterface i) {
OldClass c = new OldClass();
i.apply(c);
}
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021, 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.
*
*/
super class OldClass
version 49:0
{
Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
} // end Class OldClass

@ -834,6 +834,8 @@ jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java 8228990,8229370
jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic-all
jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-all
jdk/jfr/jmx/streaming/TestRotate.java 8257215 generic-all
jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64
jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64
############################################################################
@ -876,6 +878,7 @@ java/awt/FileDialog/RegexpFilterTest/RegexpFilterTest.html 7187728 macosx-all,li
java/awt/print/PageFormat/Orient.java 8016055 macosx-all
java/awt/TextArea/TextAreaCursorTest/HoveringAndDraggingTest.java 8024986 macosx-all,linux-all
java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macosx-all
java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289 windows-x64
############################################################################

@ -71,6 +71,7 @@ import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import jdk.internal.foreign.HeapMemorySegmentImpl;
@ -635,7 +636,8 @@ public class TestByteBuffer {
}
}
public void testIOOnClosedConfinedSegment() throws IOException {
@Test
public void testIOOnConfinedSegment() throws IOException {
File tmp = File.createTempFile("tmp", "txt");
tmp.deleteOnExit();
try (FileChannel channel = FileChannel.open(tmp.toPath(), StandardOpenOption.WRITE)) {
@ -648,6 +650,40 @@ public class TestByteBuffer {
}
}
@Test(dataProvider="segments")
public void buffersAndArraysFromSlices(Supplier<MemorySegment> segmentSupplier) {
try (MemorySegment segment = segmentSupplier.get()) {
int newSize = 8;
var slice = segment.asSlice(4, newSize);
var bytes = slice.toByteArray();
assertEquals(newSize, bytes.length);
var buffer = slice.asByteBuffer();
// Fails for heap segments, but passes for native segments:
assertEquals(0, buffer.position());
assertEquals(newSize, buffer.limit());
assertEquals(newSize, buffer.capacity());
}
}
@Test(dataProvider="segments")
public void viewsFromSharedSegment(Supplier<MemorySegment> segmentSupplier) {
try (MemorySegment segment = segmentSupplier.get().share()) {
var byteBuffer = segment.asByteBuffer();
byteBuffer.asReadOnlyBuffer();
byteBuffer.slice(0, 8);
}
}
@DataProvider(name = "segments")
public static Object[][] segments() throws Throwable {
return new Object[][] {
{ (Supplier<MemorySegment>) () -> MemorySegment.allocateNative(16) },
{ (Supplier<MemorySegment>) () -> MemorySegment.ofArray(new byte[16]) }
};
}
@DataProvider(name = "bufferOps")
public static Object[][] bufferOps() throws Throwable {
List<Object[]> args = new ArrayList<>();

@ -24,13 +24,15 @@
/*
* @test
* @key headful
* @bug 8249548
* @bug 8249548 8259237
* @summary Test focus traversal in button group containing JToggleButton
* and JRadioButton
* @run main TestButtonGroupFocusTraversal
*/
import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
@ -43,12 +45,16 @@ import java.awt.FlowLayout;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
public class TestButtonGroupFocusTraversal {
private static JFrame frame;
private static JTextField textFieldFirst, textFieldLast;
private static JToggleButton toggleButton1, toggleButton2;
private static JCheckBox checkBox1, checkBox2;
private static boolean toggleButtonActionPerformed;
private static boolean checkboxActionPerformed;
private static JRadioButton radioButton1, radioButton2;
private static Robot robot;
@ -75,6 +81,36 @@ public class TestButtonGroupFocusTraversal {
toggleButton2 = new JToggleButton("2");
radioButton1 = new JRadioButton("1");
radioButton2 = new JRadioButton("2");
checkBox1 = new JCheckBox("1");
checkBox2 = new JCheckBox("2");
toggleButton1.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
toggleButtonActionPerformed = true;
}
});
toggleButton2.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
toggleButtonActionPerformed = true;
}
});
checkBox1.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
checkboxActionPerformed = true;
}
});
checkBox2.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
checkboxActionPerformed = true;
}
});
ButtonGroup toggleGroup = new ButtonGroup();
toggleGroup.add(toggleButton1);
@ -84,8 +120,13 @@ public class TestButtonGroupFocusTraversal {
radioGroup.add(radioButton1);
radioGroup.add(radioButton2);
ButtonGroup checkboxButtonGroup = new ButtonGroup();
checkboxButtonGroup.add(checkBox1);
checkboxButtonGroup.add(checkBox2);
toggleButton2.setSelected(true);
radioButton2.setSelected(true);
checkBox2.setSelected(true);
frame = new JFrame("Test");
frame.setLayout(new FlowLayout());
@ -96,6 +137,8 @@ public class TestButtonGroupFocusTraversal {
pane.add(toggleButton2);
pane.add(radioButton1);
pane.add(radioButton2);
pane.add(checkBox1);
pane.add(checkBox2);
pane.add(textFieldLast);
frame.pack();
@ -127,6 +170,20 @@ public class TestButtonGroupFocusTraversal {
}
}
private static void checkToggleButtonActionPerformed() {
if (toggleButtonActionPerformed) {
throw new RuntimeException("Toggle Button Action should not be" +
"performed");
}
}
private static void checkCheckboxActionPerformed() {
if (toggleButtonActionPerformed) {
throw new RuntimeException("Checkbox Action should not be" +
"performed");
}
}
public static void main(String[] args) throws Exception {
robot = new Robot();
robot.setAutoDelay(100);
@ -164,9 +221,15 @@ public class TestButtonGroupFocusTraversal {
pressKey(KeyEvent.VK_TAB);
checkFocusedComponent(radioButton2);
pressKey(KeyEvent.VK_TAB);
checkFocusedComponent(checkBox2);
pressKey(KeyEvent.VK_TAB);
checkFocusedComponent(textFieldLast);
pressKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
checkFocusedComponent(checkBox2);
pressKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
checkFocusedComponent(radioButton2);
@ -181,15 +244,19 @@ public class TestButtonGroupFocusTraversal {
pressKey(KeyEvent.VK_LEFT);
checkFocusedComponent(toggleButton1);
checkToggleButtonActionPerformed();
pressKey(KeyEvent.VK_RIGHT);
checkFocusedComponent(toggleButton2);
checkToggleButtonActionPerformed();
pressKey(KeyEvent.VK_UP);
checkFocusedComponent(toggleButton1);
checkToggleButtonActionPerformed();
pressKey(KeyEvent.VK_DOWN);
checkFocusedComponent(toggleButton2);
checkToggleButtonActionPerformed();
pressKey(KeyEvent.VK_TAB);
checkFocusedComponent(radioButton2);
@ -206,6 +273,24 @@ public class TestButtonGroupFocusTraversal {
pressKey(KeyEvent.VK_DOWN);
checkFocusedComponent(radioButton2);
pressKey(KeyEvent.VK_TAB);
checkFocusedComponent(checkBox2);
pressKey(KeyEvent.VK_LEFT);
checkCheckboxActionPerformed();
checkFocusedComponent(checkBox1);
pressKey(KeyEvent.VK_RIGHT);
checkCheckboxActionPerformed();
checkFocusedComponent(checkBox2);
pressKey(KeyEvent.VK_UP);
checkCheckboxActionPerformed();
checkFocusedComponent(checkBox1);
pressKey(KeyEvent.VK_DOWN);
checkCheckboxActionPerformed();
checkFocusedComponent(checkBox2);
} finally {
if (frame != null) {
SwingUtilities.invokeAndWait(frame::dispose);
@ -214,4 +299,3 @@ public class TestButtonGroupFocusTraversal {
}
}
}

@ -121,6 +121,10 @@ public class CompilationTestCase extends JavacTemplateTestBase {
return assertCompile(expandMarkers(constructs), this::assertCompileSucceeded, generate);
}
protected File assertOK(Consumer<Diagnostic<?>> diagConsumer, String... constructs) {
return assertCompile(expandMarkers(constructs), () -> assertCompileSucceeded(diagConsumer), false);
}
protected void assertOKWithWarning(String warning, String... constructs) {
assertCompile(expandMarkers(constructs), () -> assertCompileSucceededWithWarning(warning), false);
}

@ -66,6 +66,10 @@ public class Diagnostics implements javax.tools.DiagnosticListener<JavaFileObjec
return null;
}
public List<Diagnostic<?>> getAllDiags() {
return diags.stream().map(d -> (Diagnostic<?>)d).collect(toList());
}
/** Do the diagnostics contain the specified error key? */
public boolean containsErrorKey(String key) {
return diags.stream()

@ -177,6 +177,13 @@ public abstract class JavacTemplateTestBase {
fail("Expected successful compilation");
}
/** Assert that all previous calls to compile() succeeded, also accepts a diagnostics consumer */
protected void assertCompileSucceeded(Consumer<Diagnostic<?>> diagConsumer) {
if (diags.errorsFound())
fail("Expected successful compilation");
diags.getAllDiags().stream().forEach(diagConsumer);
}
/** Assert that all previous calls to compile() succeeded */
protected void assertCompileSucceededWithWarning(String warning) {
if (diags.errorsFound())

@ -1,67 +0,0 @@
/*
* Copyright (c) 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
* 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 8245956
* @summary JavaCompiler still uses File API instead of Path API in a specific case
* @run main T8245956
*/
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
public class T8245956 {
public static void main(String[] args) throws Exception {
Path zipFilePath = Path.of("T8245956.zip");
URI zipFileUri = zipFilePath.toUri();
URI jarZipFileUri = URI.create("jar:" + zipFileUri.toString());
Map<String, String> env = new LinkedHashMap<>();
env.put("create", "true");
try (FileSystem fs = FileSystems.newFileSystem(jarZipFileUri, env)) {
Path fsPath = fs.getPath("");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null)) {
List<Path> classPath = new ArrayList<>();
classPath.add(fsPath);
fileManager.setLocationFromPaths(StandardLocation.CLASS_PATH, classPath);
fileManager.getClassLoader(StandardLocation.CLASS_PATH); // Should not generate any exceptions.
System.out.println("The method getClassLoader terminated normally.\n");
}
}
}
}

@ -0,0 +1,41 @@
/*
* Copyright (c) 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
* 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.
*/
// key: compiler.note.method.ref.search.results.multi
// key: compiler.misc.bound
// key: compiler.misc.applicable.method.found.2
// key: compiler.misc.static
// key: compiler.misc.non.static
// key: compiler.misc.unbound
// options: --debug=dumpMethodReferenceSearchResults
import java.util.function.*;
class BoundUnboundMethRefSearch {
public String foo(Object o) { return "foo"; }
public static String foo(String o) { return "bar"; }
void m() {
Function<String, String> f = BoundUnboundMethRefSearch::foo;
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 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
* 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.
*/
// key: compiler.note.method.ref.search.results.multi
// key: compiler.misc.bound
// key: compiler.misc.applicable.method.found.3
// key: compiler.misc.static
// key: compiler.misc.partial.inst.sig
// key: compiler.misc.unbound
// options: --debug=dumpMethodReferenceSearchResults
import java.util.function.*;
class BoundUnboundMethRefSearch2 {
interface SAM <T> {
boolean test(T n, T m);
}
static <T> boolean foo(T x, T y) {
return false;
}
void bar() {
SAM <Integer> mRef = BoundUnboundMethRefSearch2::<Integer>foo;
}
}

@ -0,0 +1,136 @@
/*
* Copyright (c) 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
* 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 8231461
* @summary static/instance overload leads to 'unexpected static method found in unbound lookup' when resolving method reference
* @library /lib/combo /tools/lib /tools/javac/lib
* @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.util
* @run testng BoundUnboundSearchTest
*/
import java.util.function.*;
import javax.tools.Diagnostic;
import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.JCDiagnostic;
import org.testng.annotations.Test;
import tools.javac.combo.CompilationTestCase;
import static org.testng.Assert.assertEquals;
@Test
public class BoundUnboundSearchTest extends CompilationTestCase {
static final String TEMPLATE =
"""
import java.util.function.*;
class Test {
#CANDIDATES
void m() {
Function<String, String> f = Test::foo;
}
}
""";
public BoundUnboundSearchTest() {
setDefaultFilename("Test.java");
setCompileOptions(new String[]{"--debug=dumpMethodReferenceSearchResults"});
}
private Consumer<Diagnostic<?>> getDiagConsumer(final int boundCandidate, final int unboundCandidate) {
return diagWrapper -> {
JCDiagnostic diagnostic = ((DiagnosticSourceUnwrapper)diagWrapper).d;
Object[] args = diagnostic.getArgs();
if (args[0].toString().equals("bound")) {
Assert.check(args[2].equals(boundCandidate));
} else if (args[0].toString().equals("unbound")) {
Assert.check(args[2].equals(unboundCandidate));
}
};
}
public void test() {
assertOK(
getDiagConsumer(0, -1),
TEMPLATE.replaceFirst("#CANDIDATES",
"""
public String foo(Object o) { return "foo"; } // candidate 0
public static String foo(String o) { return "bar"; } // candidate 1
"""
)
);
assertOK(
getDiagConsumer(0, -1),
TEMPLATE.replaceFirst("#CANDIDATES",
"""
public static String foo(Object o) { return "foo"; } // candidate 0
public static String foo(String o) { return "bar"; } // candidate 0
"""
)
);
assertFail("compiler.err.prob.found.req",
getDiagConsumer(0, -1),
TEMPLATE.replaceFirst("#CANDIDATES",
"""
public static String foo(Object o) { return "foo"; } // candidate 0
public String foo(String o) { return "bar"; } // candidate 1
"""
)
);
assertFail("compiler.err.prob.found.req",
getDiagConsumer(0, -1),
TEMPLATE.replaceFirst("#CANDIDATES",
"""
public String foo(Object o) { return "foo"; } // candidate 0
public String foo(String o) { return "bar"; } // candidate 1
"""
)
);
assertFail("compiler.err.invalid.mref",
getDiagConsumer(-1, -1),
"""
import java.util.function.*;
public class Test {
public String foo(Object o) { return "foo"; }
public static String foo(String o) { return "bar"; }
public void test() {
// method bar doesn't exist
Function<String, String> f = Test::bar;
}
}
"""
);
}
}