Mercurial > people > andrew > aarch32 > hotspot
changeset 9036:f1ee83181bfc
Merge
author | snazarki |
---|---|
date | Thu, 20 Apr 2017 15:03:07 +0300 |
parents | 40cc86629062 (current diff) 829ea9b92cda (diff) |
children | b93c39bf2bcf |
files | .hgtags src/os/linux/vm/os_linux.cpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/os.hpp src/share/vm/runtime/vm_version.cpp |
diffstat | 31 files changed, 485 insertions(+), 86 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Sun Feb 19 20:14:42 2017 +0000 +++ b/.hgtags Thu Apr 20 15:03:07 2017 +0300 @@ -951,3 +951,15 @@ 11f91811e4d7e5ddfaf938dcf386ec8fe5bf7b7c jdk8u121-b11 b132b08b28bf23a26329928cf6b4ffda5857f4d3 jdk8u121-b12 2d40c68f1daa3106bba5c4072a9da4d83d055128 jdk8u121-b13-aarch32-170210 +90f94521c3515e5f27af0ab9b31d036e88bb322a jdk8u121-b13 +c0a1ba0df20fda10ddb8599e888eb56ad98b3874 jdk8u131-b00 +0b85ccd6240991e1a501602ff5addec6b88ae0af jdk8u131-b01 +ef90c721a4e59b01ca36f25619010a1afe9ed4d5 jdk8u131-b02 +0ca47d0811b01ecf8651b6045a1e33a4a9bed0ee jdk8u131-b03 +dab1d597165207e14b6886b1823c1e990bc776a3 jdk8u131-b04 +c965fc1aa840a0903709ad69aa0e2100330ccd84 jdk8u131-b05 +6e4cfbc7534f83902692132efb61683528c04a59 jdk8u131-b06 +5b3cb4fbdbc7bdeb7c78a8703c3084ce068f6691 jdk8u131-b07 +db221c0a423e776bec5c3198d11d3f26827bd786 jdk8u131-b08 +56e71d16083904ceddfdd1d66312582a42781646 jdk8u131-b09 +1da23ae49386608550596502d90a381ee6c1dfaa jdk8u131-b10
--- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1023,11 +1023,16 @@ obj.load_item(); LIR_Opr out_reg = rlock_result(x); CodeStub* stub; - CodeEmitInfo* info_for_exception = state_for(x); + CodeEmitInfo* info_for_exception = + (x->needs_exception_state() ? state_for(x) : + state_for(x, x->state_before(), true /*ignore_xhandler*/)); if (x->is_incompatible_class_change_check()) { assert(patching_info == NULL, "can't patch this"); stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); + } else if (x->is_invokespecial_receiver_check()) { + assert(patching_info == NULL, "can't patch this"); + stub = new DeoptimizeStub(info_for_exception); } else { stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); }
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1228,12 +1228,17 @@ obj.load_item(); // info for exceptions - CodeEmitInfo* info_for_exception = state_for(x); + CodeEmitInfo* info_for_exception = + (x->needs_exception_state() ? state_for(x) : + state_for(x, x->state_before(), true /*ignore_xhandler*/)); CodeStub* stub; if (x->is_incompatible_class_change_check()) { assert(patching_info == NULL, "can't patch this"); stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception); + } else if (x->is_invokespecial_receiver_check()) { + assert(patching_info == NULL, "can't patch this"); + stub = new DeoptimizeStub(info_for_exception); } else { stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception); }
--- a/src/os/linux/vm/globals_linux.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/os/linux/vm/globals_linux.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -47,7 +47,10 @@ "Load DLLs with executable-stack attribute in the VM Thread") \ \ product(bool, UseSHM, false, \ - "Use SYSV shared memory for large pages") + "Use SYSV shared memory for large pages") \ + \ + diagnostic(bool, PrintActiveCpus, false, \ + "Print the number of CPUs detected in os::active_processor_count") // // Defines Linux-specific default values. The flags are available on all
--- a/src/os/linux/vm/os_linux.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/os/linux/vm/os_linux.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -106,6 +106,14 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC +#ifndef _GNU_SOURCE + #define _GNU_SOURCE + #include <sched.h> + #undef _GNU_SOURCE +#else + #include <sched.h> +#endif + // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling // getrusage() is prepared to handle the associated failure. #ifndef RUSAGE_THREAD @@ -1075,29 +1083,30 @@ // Locate initial thread stack. This special handling of initial thread stack // is needed because pthread_getattr_np() on most (all?) Linux distros returns -// bogus value for initial thread. +// bogus value for the primordial process thread. While the launcher has created +// the VM in a new thread since JDK 6, we still have to allow for the use of the +// JNI invocation API from a primordial thread. void os::Linux::capture_initial_stack(size_t max_size) { - // stack size is the easy part, get it from RLIMIT_STACK - size_t stack_size; + + // max_size is either 0 (which means accept OS default for thread stacks) or + // a user-specified value known to be at least the minimum needed. If we + // are actually on the primordial thread we can make it appear that we have a + // smaller max_size stack by inserting the guard pages at that location. But we + // cannot do anything to emulate a larger stack than what has been provided by + // the OS or threading library. In fact if we try to use a stack greater than + // what is set by rlimit then we will crash the hosting process. + + // Maximum stack size is the easy part, get it from RLIMIT_STACK. + // If this is "unlimited" then it will be a huge value. struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); - stack_size = rlim.rlim_cur; + size_t stack_size = rlim.rlim_cur; // 6308388: a bug in ld.so will relocate its own .data section to the // lower end of primordial stack; reduce ulimit -s value a little bit // so we won't install guard page on ld.so's data section. stack_size -= 2 * page_size(); - // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat - // 7.1, in both cases we will get 2G in return value. - // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0, - // SuSE 7.2, Debian) can not handle alternate signal stack correctly - // for initial thread if its stack size exceeds 6M. Cap it at 2M, - // in case other parts in glibc still assumes 2M max stack size. - // FIXME: alt signal stack is gone, maybe we can relax this constraint? - // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small - if (stack_size > 2 * K * K IA64_ONLY(*2)) - stack_size = 2 * K * K IA64_ONLY(*2); // Try to figure out where the stack base (top) is. This is harder. // // When an application is started, glibc saves the initial stack pointer in @@ -1257,14 +1266,18 @@ // stack_top could be partially down the page so align it stack_top = align_size_up(stack_top, page_size()); - if (max_size && stack_size > max_size) { - _initial_thread_stack_size = max_size; + // Allowed stack value is minimum of max_size and what we derived from rlimit + if (max_size > 0) { + _initial_thread_stack_size = MIN2(max_size, stack_size); } else { - _initial_thread_stack_size = stack_size; + // Accept the rlimit max, but if stack is unlimited then it will be huge, so + // clamp it at 8MB as we do on Solaris + _initial_thread_stack_size = MIN2(stack_size, 8*M); } _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; + assert(_initial_thread_stack_bottom < (address)stack_top, "overflow!"); } //////////////////////////////////////////////////////////////////////////////// @@ -5028,12 +5041,42 @@ } }; +static int os_cpu_count(const cpu_set_t* cpus) { + int count = 0; + // only look up to the number of configured processors + for (int i = 0; i < os::processor_count(); i++) { + if (CPU_ISSET(i, cpus)) { + count++; + } + } + return count; +} + +// Get the current number of available processors for this process. +// This value can change at any time during a process's lifetime. +// sched_getaffinity gives an accurate answer as it accounts for cpusets. +// If anything goes wrong we fallback to returning the number of online +// processors - which can be greater than the number available to the process. int os::active_processor_count() { - // Linux doesn't yet have a (official) notion of processor sets, - // so just return the number of online processors. - int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); - assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check"); - return online_cpus; + cpu_set_t cpus; // can represent at most 1024 (CPU_SETSIZE) processors + int cpus_size = sizeof(cpu_set_t); + int cpu_count = 0; + + // pid 0 means the current thread - which we have to assume represents the process + if (sched_getaffinity(0, cpus_size, &cpus) == 0) { + cpu_count = os_cpu_count(&cpus); + if (PrintActiveCpus) { + tty->print_cr("active_processor_count: sched_getaffinity processor count: %d", cpu_count); + } + } + else { + cpu_count = ::sysconf(_SC_NPROCESSORS_ONLN); + warning("sched_getaffinity failed (%s)- using online processor count (%d) " + "which may exceed available processors", strerror(errno), cpu_count); + } + + assert(cpu_count > 0 && cpu_count <= processor_count(), "sanity check"); + return cpu_count; } void os::set_native_thread_name(const char *name) {
--- a/src/os/windows/vm/os_windows.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/os/windows/vm/os_windows.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1747,8 +1747,7 @@ if (is_workstation) { st->print("10"); } else { - // The server version name of Windows 10 is not known at this time - st->print("%d.%d", major_version, minor_version); + st->print("Server 2016"); } break;
--- a/src/share/vm/c1/c1_CodeStubs.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/c1/c1_CodeStubs.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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,6 +57,7 @@ virtual bool is_exception_throw_stub() const { return false; } virtual bool is_range_check_stub() const { return false; } virtual bool is_divbyzero_stub() const { return false; } + virtual bool is_simple_exception_stub() const { return false; } #ifndef PRODUCT virtual void print_name(outputStream* out) const = 0; #endif @@ -484,6 +485,7 @@ virtual void emit_code(LIR_Assembler* e); virtual CodeEmitInfo* info() const { return _info; } virtual bool is_exception_throw_stub() const { return true; } + virtual bool is_simple_exception_stub() const { return true; } virtual void visit(LIR_OpVisitState* visitor) { if (_obj->is_valid()) visitor->do_input(_obj); visitor->do_slow_case(_info);
--- a/src/share/vm/c1/c1_GraphBuilder.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1823,6 +1823,20 @@ log->identify(target), Bytecodes::name(code)); + // invoke-special-super + if (bc_raw == Bytecodes::_invokespecial && !target->is_object_initializer()) { + ciInstanceKlass* sender_klass = + calling_klass->is_anonymous() ? calling_klass->host_klass() : + calling_klass; + if (sender_klass->is_interface()) { + int index = state()->stack_size() - (target->arg_size_no_receiver() + 1); + Value receiver = state()->stack_at(index); + CheckCast* c = new CheckCast(sender_klass, receiver, copy_state_before()); + c->set_invokespecial_receiver_check(); + state()->stack_at_put(index, append_split(c)); + } + } + // Some methods are obviously bindable without any type checks so // convert them directly to an invokespecial or invokestatic. if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
--- a/src/share/vm/c1/c1_Instruction.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/c1/c1_Instruction.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -381,6 +381,7 @@ UnorderedIsTrueFlag, NeedsPatchingFlag, ThrowIncompatibleClassChangeErrorFlag, + InvokeSpecialReceiverCheckFlag, ProfileMDOFlag, IsLinkedInBlockFlag, NeedsRangeCheckFlag, @@ -1456,6 +1457,16 @@ bool is_incompatible_class_change_check() const { return check_flag(ThrowIncompatibleClassChangeErrorFlag); } + void set_invokespecial_receiver_check() { + set_flag(InvokeSpecialReceiverCheckFlag, true); + } + bool is_invokespecial_receiver_check() const { + return check_flag(InvokeSpecialReceiverCheckFlag); + } + + virtual bool needs_exception_state() const { + return !is_invokespecial_receiver_check(); + } ciType* declared_type() const; };
--- a/src/share/vm/ci/ciInstanceKlass.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -58,6 +58,7 @@ _nonstatic_field_size = ik->nonstatic_field_size(); _has_nonstatic_fields = ik->has_nonstatic_fields(); _has_default_methods = ik->has_default_methods(); + _is_anonymous = ik->is_anonymous(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: _implementor = NULL; // we will fill these lazily @@ -100,6 +101,7 @@ _nonstatic_field_size = -1; _has_nonstatic_fields = false; _nonstatic_fields = NULL; + _is_anonymous = false; _loader = loader; _protection_domain = protection_domain; _is_shared = false; @@ -591,6 +593,16 @@ return impl; } +ciInstanceKlass* ciInstanceKlass::host_klass() { + assert(is_loaded(), "must be loaded"); + if (is_anonymous()) { + VM_ENTRY_MARK + Klass* host_klass = get_instanceKlass()->host_klass(); + return CURRENT_ENV->get_instance_klass(host_klass); + } + return NULL; +} + // Utility class for printing of the contents of the static fields for // use by compilation replay. It only prints out the information that // could be consumed by the compiler, so for primitive types it prints
--- a/src/share/vm/ci/ciInstanceKlass.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/ci/ciInstanceKlass.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -53,6 +53,7 @@ bool _has_subklass; bool _has_nonstatic_fields; bool _has_default_methods; + bool _is_anonymous; ciFlags _flags; jint _nonstatic_field_size; @@ -177,6 +178,10 @@ return _has_default_methods; } + bool is_anonymous() { + return _is_anonymous; + } + ciInstanceKlass* get_canonical_holder(int offset); ciField* get_field_by_offset(int field_offset, bool is_static); ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); @@ -248,6 +253,8 @@ return NULL; } + ciInstanceKlass* host_klass(); + // Dump the current state of this klass for compilation replay. virtual void dump_replay_data(outputStream* out); };
--- a/src/share/vm/ci/ciMethod.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/ci/ciMethod.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -948,6 +948,13 @@ } // ------------------------------------------------------------------ +// ciMethod::is_object_initializer +// +bool ciMethod::is_object_initializer() const { + return name() == ciSymbol::object_initializer_name(); +} + +// ------------------------------------------------------------------ // ciMethod::has_member_arg // // Return true if the method is a linker intrinsic like _linkToVirtual.
--- a/src/share/vm/ci/ciMethod.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/ci/ciMethod.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -316,6 +316,7 @@ bool can_be_statically_bound() const { return _can_be_statically_bound; } bool is_boxing_method() const; bool is_unboxing_method() const; + bool is_object_initializer() const; // Replay data methods void dump_name_as_ascii(outputStream* st);
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -631,11 +631,10 @@ double overall_cm_overhead = (double) MaxGCPauseMillis * marking_overhead / (double) GCPauseIntervalMillis; - double cpu_ratio = 1.0 / (double) os::processor_count(); + double cpu_ratio = 1.0 / os::initial_active_processor_count(); double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio); double marking_task_overhead = - overall_cm_overhead / marking_thread_num * - (double) os::processor_count(); + overall_cm_overhead / marking_thread_num * os::initial_active_processor_count(); double sleep_factor = (1.0 - marking_task_overhead) / marking_task_overhead;
--- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -80,7 +80,7 @@ // Determines how many mutator threads can process the buffers in parallel. uint DirtyCardQueueSet::num_par_ids() { - return (uint)os::processor_count(); + return (uint)os::initial_active_processor_count(); } void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
--- a/src/share/vm/interpreter/interpreterRuntime.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -693,7 +693,8 @@ IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) { // extract receiver from the outgoing argument list if necessary Handle receiver(thread, NULL); - if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { + if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface || + bytecode == Bytecodes::_invokespecial) { ResourceMark rm(thread); methodHandle m (thread, method(thread)); Bytecode_invoke call(m, bci(thread)); @@ -759,16 +760,25 @@ int index = info.resolved_method()->itable_index(); assert(info.itable_index() == index, ""); } + } else if (bytecode == Bytecodes::_invokespecial) { + assert(info.call_kind() == CallInfo::direct_call, "must be direct call"); } else { assert(info.call_kind() == CallInfo::direct_call || info.call_kind() == CallInfo::vtable_call, ""); } #endif + // Get sender or sender's host_klass, and only set cpCache entry to resolved if + // it is not an interface. The receiver for invokespecial calls within interface + // methods must be checked for every call. + InstanceKlass* sender = pool->pool_holder(); + sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; + switch (info.call_kind()) { case CallInfo::direct_call: cache_entry(thread)->set_direct_call( bytecode, - info.resolved_method()); + info.resolved_method(), + sender->is_interface()); break; case CallInfo::vtable_call: cache_entry(thread)->set_vtable_call(
--- a/src/share/vm/interpreter/linkResolver.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -913,11 +913,11 @@ } -void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, +void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { methodHandle resolved_method; linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); - runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK); + runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK); } // throws linktime exceptions @@ -1016,7 +1016,7 @@ // throws runtime exceptions void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, - KlassHandle current_klass, bool check_access, TRAPS) { + KlassHandle current_klass, Handle recv, bool check_access, TRAPS) { // resolved method is selected method unless we have an old-style lookup // for a superclass method @@ -1024,21 +1024,19 @@ // no checks for shadowing methodHandle sel_method(THREAD, resolved_method()); - // check if this is an old-style super call and do a new lookup if so - { KlassHandle method_klass = KlassHandle(THREAD, - resolved_method->method_holder()); + if (check_access && + // check if the method is not <init> + resolved_method->name() != vmSymbols::object_initializer_name()) { - if (check_access && + // check if this is an old-style super call and do a new lookup if so // a) check if ACC_SUPER flag is set for the current class - (current_klass->is_super() || !AllowNonVirtualCalls) && + if ((current_klass->is_super() || !AllowNonVirtualCalls) && // b) check if the class of the resolved_klass is a superclass // (not supertype in order to exclude interface classes) of the current class. // This check is not performed for super.invoke for interface methods // in super interfaces. current_klass->is_subclass_of(resolved_klass()) && - current_klass() != resolved_klass() && - // c) check if the method is not <init> - resolved_method->name() != vmSymbols::object_initializer_name()) { + current_klass() != resolved_klass()) { // Lookup super method KlassHandle super_klass(THREAD, current_klass->super()); lookup_instance_method_in_klasses(sel_method, super_klass, @@ -1053,6 +1051,27 @@ resolved_method->signature())); } } + + // Check that the class of objectref (the receiver) is the current class or interface, + // or a subtype of the current class or interface (the sender), otherwise invokespecial + // throws IllegalAccessError. + // The verifier checks that the sender is a subtype of the class in the I/MR operand. + // The verifier also checks that the receiver is a subtype of the sender, if the sender is + // a class. If the sender is an interface, the check has to be performed at runtime. + InstanceKlass* sender = InstanceKlass::cast(current_klass()); + sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; + if (sender->is_interface() && recv.not_null()) { + Klass* receiver_klass = recv->klass(); + if (!receiver_klass->is_subtype_of(sender)) { + ResourceMark rm(THREAD); + char buf[500]; + jio_snprintf(buf, sizeof(buf), + "Receiver class %s must be the current class or a subtype of interface %s", + receiver_klass->name()->as_C_string(), + sender->name()->as_C_string()); + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf); + } + } } // check if not static @@ -1479,7 +1498,7 @@ bool check_access) { EXCEPTION_MARK; CallInfo info; - resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD); + resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return methodHandle(); @@ -1495,7 +1514,7 @@ void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { switch (byte) { case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; - case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break; + case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break; case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break; case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; @@ -1526,13 +1545,13 @@ } -void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { +void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { KlassHandle resolved_klass; Symbol* method_name = NULL; Symbol* method_signature = NULL; KlassHandle current_klass; resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); - resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK); + resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK); }
--- a/src/share/vm/interpreter/linkResolver.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/interpreter/linkResolver.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -142,7 +142,7 @@ static void linktime_resolve_virtual_method (methodHandle &resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature,KlassHandle current_klass, bool check_access, TRAPS); static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); - static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS); + static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, Handle recv, bool check_access, TRAPS); static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS); static void runtime_resolve_interface_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS); @@ -173,7 +173,7 @@ // resolved_klass = specified class (i.e., static receiver class) // current_klass = sending method holder (i.e., class containing the method containing the call being resolved) static void resolve_static_call (CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool initialize_klass, TRAPS); - static void resolve_special_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); + static void resolve_special_call (CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS); static void resolve_virtual_call (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS); static void resolve_handle_call (CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS); @@ -196,7 +196,7 @@ // runtime resolving from constant pool static void resolve_invokestatic (CallInfo& result, constantPoolHandle pool, int index, TRAPS); - static void resolve_invokespecial (CallInfo& result, constantPoolHandle pool, int index, TRAPS); + static void resolve_invokespecial (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS); static void resolve_invokevirtual (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS); static void resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS); static void resolve_invokedynamic (CallInfo& result, constantPoolHandle pool, int index, TRAPS);
--- a/src/share/vm/oops/cpCache.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/oops/cpCache.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, 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 @@ -144,7 +144,8 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_code, methodHandle method, - int vtable_index) { + int vtable_index, + bool sender_is_interface) { bool is_vtable_call = (vtable_index >= 0); // FIXME: split this method on this boolean assert(method->interpreter_entry() != NULL, "should have been set at this point"); assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache"); @@ -208,7 +209,13 @@ if (byte_no == 1) { assert(invoke_code != Bytecodes::_invokevirtual && invoke_code != Bytecodes::_invokeinterface, ""); + // Don't mark invokespecial to method as resolved if sender is an interface. The receiver + // has to be checked that it is a subclass of the current class every time this bytecode + // is executed. + if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface || + method->name() == vmSymbols::object_initializer_name()) { set_bytecode_1(invoke_code); + } } else if (byte_no == 2) { if (change_to_virtual) { assert(invoke_code == Bytecodes::_invokeinterface, ""); @@ -238,17 +245,18 @@ NOT_PRODUCT(verify(tty)); } -void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method) { +void ConstantPoolCacheEntry::set_direct_call(Bytecodes::Code invoke_code, methodHandle method, + bool sender_is_interface) { int index = Method::nonvirtual_vtable_index; // index < 0; FIXME: inline and customize set_direct_or_vtable_call - set_direct_or_vtable_call(invoke_code, method, index); + set_direct_or_vtable_call(invoke_code, method, index, sender_is_interface); } void ConstantPoolCacheEntry::set_vtable_call(Bytecodes::Code invoke_code, methodHandle method, int index) { // either the method is a miranda or its holder should accept the given index assert(method->method_holder()->is_interface() || method->method_holder()->verify_vtable_index(index), ""); // index >= 0; FIXME: inline and customize set_direct_or_vtable_call - set_direct_or_vtable_call(invoke_code, method, index); + set_direct_or_vtable_call(invoke_code, method, index, false); } void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
--- a/src/share/vm/oops/cpCache.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/oops/cpCache.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -229,13 +229,15 @@ void set_direct_or_vtable_call( Bytecodes::Code invoke_code, // the bytecode used for invoking the method methodHandle method, // the method/prototype if any (NULL, otherwise) - int vtable_index // the vtable index if any, else negative + int vtable_index, // the vtable index if any, else negative + bool sender_is_interface ); public: void set_direct_call( // sets entry to exact concrete method entry Bytecodes::Code invoke_code, // the bytecode used for invoking the method - methodHandle method // the method to call + methodHandle method, // the method to call + bool sender_is_interface ); void set_vtable_call( // sets entry to vtable index
--- a/src/share/vm/opto/doCall.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/opto/doCall.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -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 @@ -477,6 +477,30 @@ speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL; } + // invoke-super-special + if (iter().cur_bc_raw() == Bytecodes::_invokespecial && !orig_callee->is_object_initializer()) { + ciInstanceKlass* calling_klass = method()->holder(); + ciInstanceKlass* sender_klass = + calling_klass->is_anonymous() ? calling_klass->host_klass() : + calling_klass; + if (sender_klass->is_interface()) { + Node* receiver_node = stack(sp() - nargs); + Node* cls_node = makecon(TypeKlassPtr::make(sender_klass)); + Node* bad_type_ctrl = NULL; + Node* casted_receiver = gen_checkcast(receiver_node, cls_node, &bad_type_ctrl); + if (bad_type_ctrl != NULL) { + PreserveJVMState pjvms(this); + set_control(bad_type_ctrl); + uncommon_trap(Deoptimization::Reason_class_check, + Deoptimization::Action_none); + } + if (stopped()) { + return; // MUST uncommon-trap? + } + set_stack(sp() - nargs, casted_receiver); + } + } + // Note: It's OK to try to inline a virtual call. // The call generator will not attempt to inline a polymorphic call // unless it knows how to optimize the receiver dispatch.
--- a/src/share/vm/opto/loopnode.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/opto/loopnode.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -278,8 +278,16 @@ return false; // Allow funny placement of Safepoint - if (back_control->Opcode() == Op_SafePoint) + if (back_control->Opcode() == Op_SafePoint) { + if (UseCountedLoopSafepoints) { + // Leaving the safepoint on the backedge and creating a + // CountedLoop will confuse optimizations. We can't move the + // safepoint around because its jvm state wouldn't match a new + // location. Give up on that loop. + return false; + } back_control = back_control->in(TypeFunc::Control); + } // Controlling test for loop Node *iftrue = back_control;
--- a/src/share/vm/prims/methodHandles.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/prims/methodHandles.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -679,7 +679,7 @@ defc, name, type, caller, THREAD); } else if (ref_kind == JVM_REF_invokeSpecial) { LinkResolver::resolve_special_call(result, - defc, name, type, caller, caller.not_null(), THREAD); + Handle(), defc, name, type, caller, caller.not_null(), THREAD); } else if (ref_kind == JVM_REF_invokeVirtual) { LinkResolver::resolve_virtual_call(result, Handle(), defc, defc, name, type, caller, caller.not_null(), false, THREAD); @@ -706,7 +706,7 @@ assert(!HAS_PENDING_EXCEPTION, ""); if (name == vmSymbols::object_initializer_name()) { LinkResolver::resolve_special_call(result, - defc, name, type, caller, caller.not_null(), THREAD); + Handle(), defc, name, type, caller, caller.not_null(), THREAD); } else { break; // will throw after end of switch }
--- a/src/share/vm/runtime/arguments.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/runtime/arguments.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -1768,10 +1768,39 @@ FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction); } - const julong phys_mem = + julong phys_mem = FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM) : (julong)MaxRAM; + // Experimental support for CGroup memory limits + if (UseCGroupMemoryLimitForHeap) { + // This is a rough indicator that a CGroup limit may be in force + // for this process + const char* lim_file = "/sys/fs/cgroup/memory/memory.limit_in_bytes"; + FILE *fp = fopen(lim_file, "r"); + if (fp != NULL) { + julong cgroup_max = 0; + int ret = fscanf(fp, JULONG_FORMAT, &cgroup_max); + if (ret == 1 && cgroup_max > 0) { + // If unlimited, cgroup_max will be a very large, but unspecified + // value, so use initial phys_mem as a limit + if (PrintGCDetails && Verbose) { + // Cannot use gclog_or_tty yet. + tty->print_cr("Setting phys_mem to the min of cgroup limit (" + JULONG_FORMAT "MB) and initial phys_mem (" + JULONG_FORMAT "MB)", cgroup_max/M, phys_mem/M); + } + phys_mem = MIN2(cgroup_max, phys_mem); + } else { + warning("Unable to read/parse cgroup memory limit from %s: %s", + lim_file, errno != 0 ? strerror(errno) : "unknown error"); + } + fclose(fp); + } else { + warning("Unable to open cgroup memory limit file %s (%s)", lim_file, strerror(errno)); + } + } + // If the maximum heap size has not been set with -Xmx, // then set it as fraction of the size of physical memory, // respecting the maximum and minimum sizes of the heap.
--- a/src/share/vm/runtime/globals.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/runtime/globals.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -2081,6 +2081,10 @@ "Maximum ergonomically set heap size (in bytes); zero means use " \ "MaxRAM / MaxRAMFraction") \ \ + experimental(bool, UseCGroupMemoryLimitForHeap, false, \ + "Use CGroup memory limit as physical memory limit for heap " \ + "sizing") \ + \ product(uintx, MaxRAMFraction, 4, \ "Maximum fraction (1/n) of real memory used for maximum heap " \ "size") \
--- a/src/share/vm/runtime/javaCalls.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/runtime/javaCalls.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -231,7 +231,7 @@ void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; - LinkResolver::resolve_special_call(callinfo, klass, name, signature, KlassHandle(), false, CHECK); + LinkResolver::resolve_special_call(callinfo, args->receiver(), klass, name, signature, KlassHandle(), false, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception");
--- a/src/share/vm/runtime/os.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/runtime/os.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -78,6 +78,7 @@ uintptr_t os::_serialize_page_mask = 0; long os::_rand_seed = 1; int os::_processor_count = 0; +int os::_initial_active_processor_count = 0; size_t os::_page_sizes[os::page_sizes_max]; #ifndef PRODUCT @@ -322,6 +323,7 @@ } void os::init_before_ergo() { + initialize_initial_active_processor_count(); // We need to initialize large page support here because ergonomics takes some // decisions depending on large page support and the calculated large page size. large_page_init(); @@ -835,7 +837,11 @@ st->print("CPU:"); st->print("total %d", os::processor_count()); // It's not safe to query number of active processors after crash - // st->print("(active %d)", os::active_processor_count()); + // st->print("(active %d)", os::active_processor_count()); but we can + // print the initial number of active processors. + // We access the raw value here because the assert in the accessor will + // fail if the crash occurs before initialization of this value. + st->print(" (initial active %d)", _initial_active_processor_count); st->print(" %s", VM_Version::cpu_features()); st->cr(); pd_print_cpu_info(st); @@ -1418,6 +1424,11 @@ return result; } +void os::initialize_initial_active_processor_count() { + assert(_initial_active_processor_count == 0, "Initial active processor count already set."); + _initial_active_processor_count = active_processor_count(); +} + void os::SuspendedThreadTask::run() { assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this"); internal_do_task();
--- a/src/share/vm/runtime/os.hpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/runtime/os.hpp Thu Apr 20 15:03:07 2017 +0300 @@ -151,6 +151,7 @@ static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned); + static void initialize_initial_active_processor_count(); public: static void init(void); // Called before command line parsing static void init_before_ergo(void); // Called after command line parsing @@ -238,6 +239,13 @@ // Note that on some OSes this can change dynamically. static int active_processor_count(); + // At startup the number of active CPUs this process is allowed to run on. + // This value does not change dynamically. May be different from active_processor_count(). + static int initial_active_processor_count() { + assert(_initial_active_processor_count > 0, "Initial active processor count not set yet."); + return _initial_active_processor_count; + } + // Bind processes to processors. // This is a two step procedure: // first you generate a distribution of processes to processors, @@ -978,8 +986,9 @@ protected: - static long _rand_seed; // seed for random number generator - static int _processor_count; // number of processors + static long _rand_seed; // seed for random number generator + static int _processor_count; // number of processors + static int _initial_active_processor_count; // number of active processors during initialization. static char* format_boot_path(const char* format_string, const char* home,
--- a/src/share/vm/runtime/vm_version.cpp Sun Feb 19 20:14:42 2017 +0000 +++ b/src/share/vm/runtime/vm_version.cpp Thu Apr 20 15:03:07 2017 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, 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 @@ -300,7 +300,7 @@ // processor after the first 8. For example, on a 72 cpu machine // and a chosen fraction of 5/8 // use 8 + (72 - 8) * (5/8) == 48 worker threads. - unsigned int ncpus = (unsigned int) os::active_processor_count(); + unsigned int ncpus = (unsigned int) os::initial_active_processor_count(); return (ncpus <= switch_pt) ? ncpus : (switch_pt + ((ncpus - switch_pt) * num) / den);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/loopopts/TestCountedLoopSafepointBackedge.java Thu Apr 20 15:03:07 2017 +0300 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, 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 + * @bug 8161147 + * @summary Safepoint on backedge breaks UseCountedLoopSafepoints + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+UseCountedLoopSafepoints TestCountedLoopSafepointBackedge + * + */ + +public class TestCountedLoopSafepointBackedge { + static void test(int[] arr, int inc) { + int i = 0; + for (;;) { + for (int j = 0; j < 10; j++); + arr[i] = i; + i++; + if (i >= 100) { + break; + } + for (int j = 0; j < 10; j++); + } + } + + static public void main(String[] args) { + int[] arr = new int[100]; + for (int i = 0; i < 20000; i++) { + test(arr, 1); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/os/AvailableProcessors.java Thu Apr 20 15:03:07 2017 +0300 @@ -0,0 +1,103 @@ +/* + * 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. + */ +import java.io.File; +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; +import java.util.ArrayList; + +/* + * @test + * @bug 6515172 + * @summary Check that availableProcessors reports the correct value when running in a cpuset on linux + * @requires os.family == "linux" + * @library /testlibrary + * @build com.oracle.java.testlibrary.* + * @run driver AvailableProcessors + */ +public class AvailableProcessors { + + static final String SUCCESS_STRING = "Found expected processors: "; + + public static void main(String[] args) throws Throwable { + if (args.length > 0) + checkProcessors(Integer.parseInt(args[0])); + else { + // run ourselves under different cpu configurations + // using the taskset command + String taskset; + final String taskset1 = "/bin/taskset"; + final String taskset2 = "/usr/bin/taskset"; + if (new File(taskset1).exists()) + taskset = taskset1; + else if (new File(taskset2).exists()) + taskset = taskset2; + else { + System.out.println("Skipping test: could not find taskset command"); + return; + } + + int available = Runtime.getRuntime().availableProcessors(); + + if (available == 1) { + System.out.println("Skipping test: only one processor available"); + return; + } + + // Get the java command we want to execute + // Enable logging for easier failure diagnosis + ProcessBuilder master = + ProcessTools.createJavaProcessBuilder(false, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+PrintActiveCpus", + "AvailableProcessors"); + + int[] expected = new int[] { 1, available/2, available-1, available }; + + for (int i : expected) { + System.out.println("Testing for " + i + " processors ..."); + int max = i - 1; + ArrayList<String> cmdline = new ArrayList<>(master.command()); + // prepend taskset command + cmdline.add(0, "0-" + max); + cmdline.add(0, "-c"); + cmdline.add(0, taskset); + // append expected processor count + cmdline.add(String.valueOf(i)); + ProcessBuilder pb = new ProcessBuilder(cmdline); + System.out.println("Final command line: " + + ProcessTools.getCommandLine(pb)); + OutputAnalyzer output = ProcessTools.executeProcess(pb); + output.shouldContain(SUCCESS_STRING); + } + } + } + + static void checkProcessors(int expected) { + int available = Runtime.getRuntime().availableProcessors(); + if (available != expected) + throw new Error("Expected " + expected + " processors, but found " + + available); + else + System.out.println(SUCCESS_STRING + available); + } +}