diff --git a/make/hotspot_version b/make/hotspot_version index a4bbce6eab9e4fb0ed0f2a4ae839abcb4a9d1fb1..d8b94232b7c7bb1fde99d284e9ea8d6463fc2b13 100644 --- a/make/hotspot_version +++ b/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2015 HS_MAJOR_VER=25 HS_MINOR_VER=60 -HS_BUILD_NUMBER=11 +HS_BUILD_NUMBER=12 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff --git a/src/cpu/sparc/vm/vm_version_sparc.cpp b/src/cpu/sparc/vm/vm_version_sparc.cpp index 2fd9c396a5901ff0872272d0ad0373b5574373c0..664f29e0fdec9a7046a37e4568720f692b843a2a 100644 --- a/src/cpu/sparc/vm/vm_version_sparc.cpp +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp @@ -37,7 +37,7 @@ int VM_Version::_features = VM_Version::unknown_m; const char* VM_Version::_features_str = ""; -unsigned int VM_Version::_L2_cache_line_size = 0; +unsigned int VM_Version::_L2_data_cache_line_size = 0; void VM_Version::initialize() { _features = determine_features(); @@ -363,7 +363,7 @@ void VM_Version::initialize() { #ifndef PRODUCT if (PrintMiscellaneous && Verbose) { - tty->print_cr("L2 cache line size: %u", L2_cache_line_size()); + tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size()); tty->print("Allocation"); if (AllocatePrefetchStyle <= 0) { tty->print_cr(": no prefetching"); diff --git a/src/cpu/sparc/vm/vm_version_sparc.hpp b/src/cpu/sparc/vm/vm_version_sparc.hpp index fa823863bdbf0017f17ee2dcc1269088895ad8c4..59969ed1089beeaf7029754afdb87c9c884d0f42 100644 --- a/src/cpu/sparc/vm/vm_version_sparc.hpp +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp @@ -96,8 +96,8 @@ protected: static int _features; static const char* _features_str; - static unsigned int _L2_cache_line_size; - static unsigned int L2_cache_line_size() { return _L2_cache_line_size; } + static unsigned int _L2_data_cache_line_size; + static unsigned int L2_data_cache_line_size() { return _L2_data_cache_line_size; } static void print_features(); static int determine_features(); @@ -171,7 +171,7 @@ public: static const char* cpu_features() { return _features_str; } // default prefetch block size on sparc - static intx prefetch_data_size() { return L2_cache_line_size(); } + static intx prefetch_data_size() { return L2_data_cache_line_size(); } // Prefetch static intx prefetch_copy_interval_in_bytes() { diff --git a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp index 56c9420964449315b70f141c7aa9cd8db8dcb192..8a3c46c2c3ce78be13254f4ed261f197ffefe257 100644 --- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp +++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp @@ -34,8 +34,7 @@ #include #include -extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); -extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result); +extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result); // Functions from the library we need (signatures should match those in picl.h) extern "C" { @@ -128,60 +127,87 @@ class PICL { bool is_inconsistent() { return _state == INCONSISTENT; } void set_inconsistent() { _state = INCONSISTENT; } - static int visit(picl_nodehdl_t nodeh, const char* name, void *arg) { - UniqueValueVisitor *state = static_cast(arg); - PICL* picl = state->_picl; - assert(!state->is_inconsistent(), "Precondition"); + bool visit(picl_nodehdl_t nodeh, const char* name) { + assert(!is_inconsistent(), "Precondition"); int curr; - if (picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { - if (!state->is_assigned()) { // first iteration - state->set_value(curr); - } else if (curr != state->value()) { // following iterations - state->set_inconsistent(); + if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) { + if (!is_assigned()) { // first iteration + set_value(curr); + } else if (curr != value()) { // following iterations + set_inconsistent(); } + return true; } - if (state->is_inconsistent()) { + return false; + } + }; + + class CPUVisitor { + UniqueValueVisitor _l1_visitor; + UniqueValueVisitor _l2_visitor; + int _limit; // number of times visit() can be run + public: + CPUVisitor(PICL *picl, int limit) : _l1_visitor(picl), _l2_visitor(picl), _limit(limit) {} + static int visit(picl_nodehdl_t nodeh, void *arg) { + CPUVisitor *cpu_visitor = static_cast(arg); + UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor(); + UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor(); + if (!l1_visitor->is_inconsistent()) { + l1_visitor->visit(nodeh, "l1-dcache-line-size"); + } + static const char* l2_data_cache_line_property_name = NULL; + // On the first visit determine the name of the l2 cache line size property and memoize it. + if (l2_data_cache_line_property_name == NULL) { + assert(!l2_visitor->is_inconsistent(), "First iteration cannot be inconsistent"); + l2_data_cache_line_property_name = "l2-cache-line-size"; + if (!l2_visitor->visit(nodeh, l2_data_cache_line_property_name)) { + l2_data_cache_line_property_name = "l2-dcache-line-size"; + l2_visitor->visit(nodeh, l2_data_cache_line_property_name); + } + } else { + if (!l2_visitor->is_inconsistent()) { + l2_visitor->visit(nodeh, l2_data_cache_line_property_name); + } + } + + if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) { + return PICL_WALK_TERMINATE; + } + cpu_visitor->_limit--; + if (cpu_visitor->_limit <= 0) { return PICL_WALK_TERMINATE; } return PICL_WALK_CONTINUE; } + UniqueValueVisitor* l1_visitor() { return &_l1_visitor; } + UniqueValueVisitor* l2_visitor() { return &_l2_visitor; } }; - int _L1_data_cache_line_size; - int _L2_cache_line_size; + int _L2_data_cache_line_size; public: - static int get_l1_data_cache_line_size(picl_nodehdl_t nodeh, void *state) { - return UniqueValueVisitor::visit(nodeh, "l1-dcache-line-size", state); - } - static int get_l2_cache_line_size(picl_nodehdl_t nodeh, void *state) { - return UniqueValueVisitor::visit(nodeh, "l2-cache-line-size", state); + static int visit_cpu(picl_nodehdl_t nodeh, void *state) { + return CPUVisitor::visit(nodeh, state); } - PICL() : _L1_data_cache_line_size(0), _L2_cache_line_size(0), _dl_handle(NULL) { + PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) { if (!open_library()) { return; } if (_picl_initialize() == PICL_SUCCESS) { picl_nodehdl_t rooth; if (_picl_get_root(&rooth) == PICL_SUCCESS) { - UniqueValueVisitor L1_state(this); - // Visit all "cpu" class instances - _picl_walk_tree_by_class(rooth, "cpu", &L1_state, PICL_get_l1_data_cache_line_size_helper); - if (L1_state.is_initial()) { // Still initial, iteration found no values - // Try walk all "core" class instances, it might be a Fujitsu machine - _picl_walk_tree_by_class(rooth, "core", &L1_state, PICL_get_l1_data_cache_line_size_helper); + const char* cpu_class = "cpu"; + // If it's a Fujitsu machine, it's a "core" + if (is_fujitsu) { + cpu_class = "core"; } - if (L1_state.is_assigned()) { // Is there a value? - _L1_data_cache_line_size = L1_state.value(); + CPUVisitor cpu_visitor(this, os::processor_count()); + _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper); + if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value? + _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value(); } - - UniqueValueVisitor L2_state(this); - _picl_walk_tree_by_class(rooth, "cpu", &L2_state, PICL_get_l2_cache_line_size_helper); - if (L2_state.is_initial()) { - _picl_walk_tree_by_class(rooth, "core", &L2_state, PICL_get_l2_cache_line_size_helper); - } - if (L2_state.is_assigned()) { - _L2_cache_line_size = L2_state.value(); + if (cpu_visitor.l2_visitor()->is_assigned()) { + _L2_data_cache_line_size = cpu_visitor.l2_visitor()->value(); } } _picl_shutdown(); @@ -190,14 +216,12 @@ public: } unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; } - unsigned int L2_cache_line_size() const { return _L2_cache_line_size; } + unsigned int L2_data_cache_line_size() const { return _L2_data_cache_line_size; } }; -extern "C" static int PICL_get_l1_data_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { - return PICL::get_l1_data_cache_line_size(nodeh, result); -} -extern "C" static int PICL_get_l2_cache_line_size_helper(picl_nodehdl_t nodeh, void *result) { - return PICL::get_l2_cache_line_size(nodeh, result); + +extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) { + return PICL::visit_cpu(nodeh, result); } template @@ -470,8 +494,8 @@ int VM_Version::platform_features(int features) { } // Figure out cache line sizes using PICL - PICL picl; - _L2_cache_line_size = picl.L2_cache_line_size(); + PICL picl((features & sparc64_family_m) != 0); + _L2_data_cache_line_size = picl.L2_data_cache_line_size(); return features; } diff --git a/src/share/vm/classfile/classLoaderData.cpp b/src/share/vm/classfile/classLoaderData.cpp index f0137567e9ed2fe97a750b2bf460284292c71546..2e852f3182975349333dcfcc44f080ac289ad9b4 100644 --- a/src/share/vm/classfile/classLoaderData.cpp +++ b/src/share/vm/classfile/classLoaderData.cpp @@ -882,7 +882,7 @@ Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass) } Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() { - Klass* head = (Klass*)_next_klass; + Klass* head = _next_klass; while (head != NULL) { Klass* next = next_klass_in_cldg(head); diff --git a/src/share/vm/classfile/classLoaderData.hpp b/src/share/vm/classfile/classLoaderData.hpp index c7b07b095ea010eee3e80155aabad4bc7101de39..e12512dc577560432cb26b59d2d3cbb87a1fbc9b 100644 --- a/src/share/vm/classfile/classLoaderData.hpp +++ b/src/share/vm/classfile/classLoaderData.hpp @@ -307,7 +307,7 @@ class ClassLoaderData : public CHeapObj { // An iterator that distributes Klasses to parallel worker threads. class ClassLoaderDataGraphKlassIteratorAtomic : public StackObj { - volatile Klass* _next_klass; + Klass* volatile _next_klass; public: ClassLoaderDataGraphKlassIteratorAtomic(); Klass* next_klass(); diff --git a/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp index bb29839fb8f11500294604545cb8faf70e383e7e..c380b894a33a8623d978fc36f1c1d5d3b8ca5115 100644 --- a/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp +++ b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp @@ -93,11 +93,13 @@ void G1RootProcessor::worker_has_discovered_all_strong_classes() { uint n_workers = _g1h->n_par_threads(); assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); - uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes); - if (new_value == n_workers) { - // This thread is last. Notify the others. - MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); - _lock.notify_all(); + if (n_workers > 0) { + uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes); + if (new_value == n_workers) { + // This thread is last. Notify the others. + MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); + _lock.notify_all(); + } } } @@ -105,7 +107,7 @@ void G1RootProcessor::wait_until_all_strong_classes_discovered() { uint n_workers = _g1h->n_par_threads(); assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); - if ((uint)_n_workers_discovered_strong_classes != n_workers) { + if (n_workers > 0 && (uint)_n_workers_discovered_strong_classes != n_workers) { MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); while ((uint)_n_workers_discovered_strong_classes != n_workers) { _lock.wait(Mutex::_no_safepoint_check_flag, 0, false); diff --git a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 7dcecd8ac3d1b47dee55d2ed17dcd99e98691d04..8ef1bd2cdaed7924aea8cf792fa1c558207f3fb4 100644 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -1197,8 +1197,10 @@ oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo( return real_forwardee(old); } - new_obj = _next_gen->par_promote(par_scan_state->thread_num(), - old, m, sz); + if (!_promotion_failed) { + new_obj = _next_gen->par_promote(par_scan_state->thread_num(), + old, m, sz); + } if (new_obj == NULL) { // promotion failed, forward to self diff --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index 16ed6558466d854677c37d73c7e71d0cc9d3faaa..642cddda5f90eaf1cc7bf1cfb57a7c74b4515ceb 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -110,7 +110,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, len = name->utf8_length(); \ } \ HS_DTRACE_PROBE4(hotspot, class__initialization__##type, \ - data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type); \ + data, len, (void *)(clss)->class_loader(), thread_type); \ } #define DTRACE_CLASSINIT_PROBE_WAIT(type, clss, thread_type, wait) \ @@ -123,7 +123,7 @@ HS_DTRACE_PROBE_DECL5(hotspot, class__initialization__end, len = name->utf8_length(); \ } \ HS_DTRACE_PROBE5(hotspot, class__initialization__##type, \ - data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), thread_type, wait); \ + data, len, (void *)(clss)->class_loader(), thread_type, wait); \ } #else /* USDT2 */ diff --git a/src/share/vm/services/classLoadingService.cpp b/src/share/vm/services/classLoadingService.cpp index 51dfa9b1b75db7a205bca8c6d276baf9bd6cc8e6..92a548ba50a4c7b8052af0bd3f7f7c9a78062775 100644 --- a/src/share/vm/services/classLoadingService.cpp +++ b/src/share/vm/services/classLoadingService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, 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 @@ -52,7 +52,7 @@ HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool); len = name->utf8_length(); \ } \ HS_DTRACE_PROBE4(hotspot, class__##type, \ - data, len, SOLARIS_ONLY((void *))(clss)->class_loader(), (shared)); \ + data, len, (void *)(clss)->class_loader(), (shared)); \ } #else /* USDT2 */