提交 e14828a4 编写于 作者: A amurillo

Merge

......@@ -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
......
......@@ -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");
......
......@@ -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() {
......
......@@ -34,8 +34,7 @@
#include <dlfcn.h>
#include <link.h>
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<UniqueValueVisitor*>(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<CPUVisitor*>(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<typename FuncType>
......@@ -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;
}
......@@ -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);
......
......@@ -307,7 +307,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
// 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();
......
......@@ -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);
......
......@@ -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
......
......@@ -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 */
......
/*
* 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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册