This commit is contained in:
Jesper Wilhelmsson 2017-03-17 16:15:14 -07:00
commit 1fab71d649
19 changed files with 197 additions and 114 deletions

View File

@ -12,7 +12,7 @@
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xprof output cpu profiling data (deprecated)
-Xfuture enable strictest checks, anticipating future default
-Xrs reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni perform additional checks for JNI functions

View File

@ -1540,7 +1540,7 @@ void GraphBuilder::method_return(Value x, bool ignore_return) {
ciMethod* caller = state()->scope()->method();
ciMethodData* md = caller->method_data_or_null();
ciProfileData* data = md->bci_to_data(invoke_bci);
if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
bool has_return = data->is_CallTypeData() ? ((ciCallTypeData*)data)->has_return() : ((ciVirtualCallTypeData*)data)->has_return();
// May not be true in case of an inlined call through a method handle intrinsic.
if (has_return) {
@ -1758,7 +1758,7 @@ Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool
start = has_receiver ? 1 : 0;
if (profile_arguments()) {
ciProfileData* data = method()->method_data()->bci_to_data(bci());
if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
}
}
@ -4349,7 +4349,7 @@ void GraphBuilder::profile_return_type(Value ret, ciMethod* callee, ciMethod* m,
}
ciMethodData* md = m->method_data_or_null();
ciProfileData* data = md->bci_to_data(invoke_bci);
if (data->is_CallTypeData() || data->is_VirtualCallTypeData()) {
if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
append(new ProfileReturnType(m , invoke_bci, callee, ret));
}
}

View File

@ -3262,6 +3262,7 @@ void LIRGenerator::profile_arguments(ProfileCall* x) {
int bci = x->bci_of_invoke();
ciMethodData* md = x->method()->method_data_or_null();
ciProfileData* data = md->bci_to_data(bci);
if (data != NULL) {
if ((data->is_CallTypeData() && data->as_CallTypeData()->has_arguments()) ||
(data->is_VirtualCallTypeData() && data->as_VirtualCallTypeData()->has_arguments())) {
ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset();
@ -3309,6 +3310,7 @@ void LIRGenerator::profile_arguments(ProfileCall* x) {
}
}
}
}
// profile parameters on entry to an inlined method
void LIRGenerator::profile_parameters_at_call(ProfileCall* x) {
@ -3396,6 +3398,7 @@ void LIRGenerator::do_ProfileReturnType(ProfileReturnType* x) {
int bci = x->bci_of_invoke();
ciMethodData* md = x->method()->method_data_or_null();
ciProfileData* data = md->bci_to_data(bci);
if (data != NULL) {
assert(data->is_CallTypeData() || data->is_VirtualCallTypeData(), "wrong profile data type");
ciReturnTypeEntry* ret = data->is_CallTypeData() ? ((ciCallTypeData*)data)->ret() : ((ciVirtualCallTypeData*)data)->ret();
LIR_Opr mdp = LIR_OprFact::illegalOpr;
@ -3416,6 +3419,7 @@ void LIRGenerator::do_ProfileReturnType(ProfileReturnType* x) {
md->set_return_type(bci, exact);
}
}
}
void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) {
// We can safely ignore accessors here, since c2 will inline them anyway,

View File

@ -408,6 +408,7 @@ void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
MethodData* mdo = get_MethodData();
if (mdo != NULL) {
ProfileData* data = mdo->bci_to_data(bci);
if (data != NULL) {
if (data->is_CallTypeData()) {
data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
} else {
@ -416,6 +417,7 @@ void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
}
}
}
}
void ciMethodData::set_parameter_type(int i, ciKlass* k) {
VM_ENTRY_MARK;
@ -430,6 +432,7 @@ void ciMethodData::set_return_type(int bci, ciKlass* k) {
MethodData* mdo = get_MethodData();
if (mdo != NULL) {
ProfileData* data = mdo->bci_to_data(bci);
if (data != NULL) {
if (data->is_CallTypeData()) {
data->as_CallTypeData()->set_return_type(k->get_Klass());
} else {
@ -438,6 +441,7 @@ void ciMethodData::set_return_type(int bci, ciKlass* k) {
}
}
}
}
bool ciMethodData::has_escape_info() {
return eflag_set(MethodData::estimated);

View File

@ -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
@ -96,10 +96,14 @@ CompactHashtable<oop, char> StringTable::_shared_table;
// Pick hashing algorithm
unsigned int StringTable::hash_string(const jchar* s, int len) {
return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
return use_alternate_hashcode() ? alt_hash_string(s, len) :
java_lang_String::hash_code(s, len);
}
unsigned int StringTable::alt_hash_string(const jchar* s, int len) {
return AltHashing::murmur3_32(seed(), s, len);
}
unsigned int StringTable::hash_string(oop string) {
EXCEPTION_MARK;
if (string == NULL) {
@ -117,11 +121,10 @@ unsigned int StringTable::hash_string(oop string) {
}
}
oop StringTable::lookup_shared(jchar* name, int len) {
// java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
// use the hash value from StringTable::hash_string() as it might use alternate hashcode.
return _shared_table.lookup((const char*)name,
java_lang_String::hash_code(name, len), len);
oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
assert(hash == java_lang_String::hash_code(name, len),
"hash must be computed using java_lang_String::hash_code");
return _shared_table.lookup((const char*)name, hash, len);
}
oop StringTable::lookup_in_main_table(int index, jchar* name,
@ -156,7 +159,7 @@ oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
unsigned int hashValue;
int index;
if (use_alternate_hashcode()) {
hashValue = hash_string(name, len);
hashValue = alt_hash_string(name, len);
index = hash_to_index(hashValue);
} else {
hashValue = hashValue_arg;
@ -199,12 +202,15 @@ static void ensure_string_alive(oop string) {
}
oop StringTable::lookup(jchar* name, int len) {
oop string = lookup_shared(name, len);
// shared table always uses java_lang_String::hash_code
unsigned int hash = java_lang_String::hash_code(name, len);
oop string = lookup_shared(name, len, hash);
if (string != NULL) {
return string;
}
unsigned int hash = hash_string(name, len);
if (use_alternate_hashcode()) {
hash = alt_hash_string(name, len);
}
int index = the_table()->hash_to_index(hash);
string = the_table()->lookup_in_main_table(index, name, len, hash);
@ -215,12 +221,15 @@ oop StringTable::lookup(jchar* name, int len) {
oop StringTable::intern(Handle string_or_null, jchar* name,
int len, TRAPS) {
oop found_string = lookup_shared(name, len);
// shared table always uses java_lang_String::hash_code
unsigned int hashValue = java_lang_String::hash_code(name, len);
oop found_string = lookup_shared(name, len, hashValue);
if (found_string != NULL) {
return found_string;
}
unsigned int hashValue = hash_string(name, len);
if (use_alternate_hashcode()) {
hashValue = alt_hash_string(name, len);
}
int index = the_table()->hash_to_index(hashValue);
found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);

View File

@ -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
@ -56,7 +56,7 @@ private:
unsigned int hashValue, TRAPS);
oop lookup_in_main_table(int index, jchar* chars, int length, unsigned int hashValue);
static oop lookup_shared(jchar* name, int len);
static oop lookup_shared(jchar* name, int len, unsigned int hash);
// Apply the give oop closure to the entries to the buckets
// in the range [start_idx, end_idx).
@ -65,6 +65,13 @@ private:
// in the range [start_idx, end_idx).
static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
// Hashing algorithm, used as the hash value used by the
// StringTable for bucket selection and comparison (stored in the
// HashtableEntry structures). This is used in the String.intern() method.
static unsigned int hash_string(const jchar* s, int len);
static unsigned int hash_string(oop string);
static unsigned int alt_hash_string(const jchar* s, int len);
StringTable() : RehashableHashtable<oop, mtSymbol>((int)StringTableSize,
sizeof (HashtableEntry<oop, mtSymbol>)) {}
@ -109,12 +116,6 @@ public:
}
static void possibly_parallel_oops_do(OopClosure* f);
// Hashing algorithm, used as the hash value used by the
// StringTable for bucket selection and comparison (stored in the
// HashtableEntry structures). This is used in the String.intern() method.
static unsigned int hash_string(const jchar* s, int len);
static unsigned int hash_string(oop string);
// Internal test.
static void test_alt_hash() PRODUCT_RETURN;

View File

@ -100,7 +100,9 @@ void set_client_compilation_mode() {
FLAG_SET_ERGO(size_t, MetaspaceSize, 12*M);
}
if (FLAG_IS_DEFAULT(MaxRAM)) {
FLAG_SET_ERGO(uint64_t, MaxRAM, 1ULL*G);
// Do not use FLAG_SET_ERGO to update MaxRAM, as this will impact
// heap setting done based on available phys_mem (see Arguments::set_heap_size).
FLAG_SET_DEFAULT(MaxRAM, 1ULL*G);
}
if (FLAG_IS_DEFAULT(CompileThreshold)) {
FLAG_SET_ERGO(intx, CompileThreshold, 1500);

View File

@ -225,7 +225,6 @@ bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape,
Node* dest = in(ArrayCopyNode::Dest);
const Type* src_type = phase->type(src);
const TypeAryPtr* ary_src = src_type->isa_aryptr();
assert(ary_src != NULL, "should be an array copy/clone");
if (is_arraycopy() || is_copyofrange() || is_copyof()) {
const Type* dest_type = phase->type(dest);
@ -286,6 +285,7 @@ bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape,
copy_type = dest_elem;
} else {
assert(ary_src != NULL, "should be a clone");
assert(is_clonebasic(), "should be");
disjoint_bases = true;

View File

@ -784,8 +784,8 @@ bool CallNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
}
// May modify (by reflection) if an boxing object is passed
// as argument or returned.
if (returns_pointer() && (proj_out(TypeFunc::Parms) != NULL)) {
Node* proj = proj_out(TypeFunc::Parms);
Node* proj = returns_pointer() ? proj_out(TypeFunc::Parms) : NULL;
if (proj != NULL) {
const TypeInstPtr* inst_t = phase->type(proj)->isa_instptr();
if ((inst_t != NULL) && (!inst_t->klass_is_exact() ||
(inst_t->klass() == boxing_klass))) {

View File

@ -1465,8 +1465,9 @@ Node* IfNode::dominated_by(Node* prev_dom, PhaseIterGVN *igvn) {
// be skipped. For example, range check predicate has two checks
// for lower and upper bounds.
ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj();
if (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) != NULL)
if ((unc_proj != NULL) && (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) != NULL)) {
prev_dom = idom;
}
// Now walk the current IfNode's projections.
// Loop ends when 'this' has no more uses.

View File

@ -2375,7 +2375,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
bool need_mem_bar;
switch (kind) {
case Relaxed:
need_mem_bar = mismatched || can_access_non_heap;
need_mem_bar = mismatched && !adr_type->isa_aryptr();
break;
case Opaque:
// Opaque uses CPUOrder membars for protection against code movement.

View File

@ -3174,6 +3174,11 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
return false;
}
Node* exit = head->loopexit()->proj_out(0);
if (exit == NULL) {
return false;
}
#ifndef PRODUCT
if (TraceLoopOpts) {
tty->print("ArrayFill ");
@ -3281,7 +3286,6 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
*/
// Redirect the old control and memory edges that are outside the loop.
Node* exit = head->loopexit()->proj_out(0);
// Sometimes the memory phi of the head is used as the outgoing
// state of the loop. It's safe in this case to replace it with the
// result_mem.

View File

@ -826,6 +826,9 @@ float Parse::dynamic_branch_prediction(float &cnt, BoolTest::mask btest, Node* t
ciMethodData* methodData = method()->method_data();
if (!methodData->is_mature()) return PROB_UNKNOWN;
ciProfileData* data = methodData->bci_to_data(bci());
if (data == NULL) {
return PROB_UNKNOWN;
}
if (!data->is_JumpData()) return PROB_UNKNOWN;
// get taken and not taken values
@ -917,8 +920,8 @@ float Parse::branch_prediction(float& cnt,
// of the OSR-ed method, and we want to deopt to gather more stats.
// If you have ANY counts, then this loop is simply 'cold' relative
// to the OSR loop.
if (data->as_BranchData()->taken() +
data->as_BranchData()->not_taken() == 0 ) {
if (data == NULL ||
(data->as_BranchData()->taken() + data->as_BranchData()->not_taken() == 0)) {
// This is the only way to return PROB_UNKNOWN:
return PROB_UNKNOWN;
}

View File

@ -891,8 +891,9 @@ bool StringConcat::validate_control_flow() {
ctrl_path.push(cn);
ctrl_path.push(cn->proj_out(0));
ctrl_path.push(cn->proj_out(0)->unique_out());
if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
Node* catchproj = cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0);
if (catchproj != NULL) {
ctrl_path.push(catchproj);
}
} else {
ShouldNotReachHere();

View File

@ -3174,6 +3174,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
// -Xprof
} else if (match_option(option, "-Xprof")) {
#if INCLUDE_FPROF
log_warning(arguments)("Option -Xprof was deprecated in version 9 and will likely be removed in a future release.");
_has_profile = true;
#else // INCLUDE_FPROF
jio_fprintf(defaultStream::error_stream(),

View File

@ -182,12 +182,12 @@ void mutex_init() {
if (UseG1GC) {
def(SATB_Q_FL_lock , PaddedMutex , special , true, Monitor::_safepoint_check_never);
def(SATB_Q_CBL_mon , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never);
def(Shared_SATB_Q_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
def(SATB_Q_CBL_mon , PaddedMonitor, leaf - 1 , true, Monitor::_safepoint_check_never);
def(Shared_SATB_Q_lock , PaddedMutex , leaf - 1 , true, Monitor::_safepoint_check_never);
def(DirtyCardQ_FL_lock , PaddedMutex , special , true, Monitor::_safepoint_check_never);
def(DirtyCardQ_CBL_mon , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_never);
def(Shared_DirtyCardQ_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
def(DirtyCardQ_CBL_mon , PaddedMonitor, leaf - 1 , true, Monitor::_safepoint_check_never);
def(Shared_DirtyCardQ_lock , PaddedMutex , leaf - 1 , true, Monitor::_safepoint_check_never);
def(FreeList_lock , PaddedMutex , leaf , true, Monitor::_safepoint_check_never);
def(SecondaryFreeList_lock , PaddedMonitor, leaf , true, Monitor::_safepoint_check_never);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* Copyright (c) 2012, 2017 SAP SE. 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
@ -153,6 +153,9 @@ inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); }
// offset_of as it is defined for gcc.
#define offset_of(klass,field) (size_t)((intx)&(((klass*)16)->field) - 16)
// AIX 5.3 has buggy __thread support. (see JDK-8176442).
#define USE_LIBRARY_BASED_TLS_ONLY 1
#ifndef USE_LIBRARY_BASED_TLS_ONLY
#define THREAD_LOCAL_DECL __thread
#endif

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017, SAP SE 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 8176505
* @summary Wrong assertion 'should be an array copy/clone' in arraycopynode.cpp
*
* @run main/othervm -Xbatch -XX:-UseOnStackReplacement compiler.arraycopy.TestObjectArrayCopy
*
* @author Volker Simonis
*/
package compiler.arraycopy;
public class TestObjectArrayCopy {
public static boolean crash(Object src) {
String[] dst = new String[1];
System.arraycopy(src, 0, dst, 0, 1);
return dst[0] == null;
}
public static void main(String[] args) {
String[] sa = new String[1];
for (int i = 0; i < 20_000; i++) {
crash(sa);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 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
@ -44,7 +44,7 @@ public class IgnoreModulePropertiesTest {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-D" + prop + "=" + value, "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("java version ");
output.shouldContain(" version ");
output.shouldHaveExitValue(0);
// Ensure that the property and its value aren't available.