8242108: Performance regression after fix for JDK-8229496
Backed out the fix for 8229496. Reviewed-by: kvn, roland
This commit is contained in:
parent
d8d8424db9
commit
0c7e01fa32
@ -8439,17 +8439,6 @@ instruct castII(iRegI dst)
|
||||
ins_pipe(pipe_class_empty);
|
||||
%}
|
||||
|
||||
instruct castLL(iRegL dst)
|
||||
%{
|
||||
match(Set dst (CastLL dst));
|
||||
|
||||
size(0);
|
||||
format %{ "# castLL of $dst" %}
|
||||
ins_encode(/* empty encoding */);
|
||||
ins_cost(0);
|
||||
ins_pipe(pipe_class_empty);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// Atomic operation instructions
|
||||
//
|
||||
|
@ -5312,14 +5312,6 @@ instruct castII( iRegI dst ) %{
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
instruct castLL( iRegL dst ) %{
|
||||
match(Set dst (CastLL dst));
|
||||
format %{ "! castLL of $dst" %}
|
||||
ins_encode( /*empty encoding*/ );
|
||||
ins_cost(0);
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
//----------Arithmetic Instructions--------------------------------------------
|
||||
// Addition Instructions
|
||||
// Register Addition
|
||||
|
@ -10885,14 +10885,6 @@ instruct castII(iRegIdst dst) %{
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct castLL(iRegLdst dst) %{
|
||||
match(Set dst (CastLL dst));
|
||||
format %{ " -- \t// castLL of $dst" %}
|
||||
size(0);
|
||||
ins_encode( /*empty*/ );
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct checkCastPP(iRegPdst dst) %{
|
||||
match(Set dst (CheckCastPP dst));
|
||||
format %{ " -- \t// checkcastPP of $dst" %}
|
||||
|
@ -5434,14 +5434,6 @@ instruct castII(iRegI dst) %{
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
instruct castLL(iRegL dst) %{
|
||||
match(Set dst (CastLL dst));
|
||||
size(0);
|
||||
format %{ "# castLL of $dst" %}
|
||||
ins_encode(/*empty*/);
|
||||
ins_pipe(pipe_class_dummy);
|
||||
%}
|
||||
|
||||
|
||||
//----------Conditional_store--------------------------------------------------
|
||||
// Conditional-store of the updated heap-top.
|
||||
|
@ -6807,14 +6807,6 @@ instruct castII( iRegI dst ) %{
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
instruct castLL( iRegL dst ) %{
|
||||
match(Set dst (CastLL dst));
|
||||
format %{ "# castLL of $dst" %}
|
||||
ins_encode( /*empty encoding*/ );
|
||||
ins_cost(0);
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
//----------Arithmetic Instructions--------------------------------------------
|
||||
// Addition Instructions
|
||||
// Register Addition
|
||||
|
@ -7237,15 +7237,6 @@ instruct castII( rRegI dst ) %{
|
||||
ins_pipe( empty );
|
||||
%}
|
||||
|
||||
instruct castLL( eRegL dst ) %{
|
||||
match(Set dst (CastLL dst));
|
||||
format %{ "#castLL of $dst" %}
|
||||
ins_encode( /*empty encoding*/ );
|
||||
ins_cost(0);
|
||||
ins_pipe( empty );
|
||||
%}
|
||||
|
||||
|
||||
// Load-locked - same as a regular pointer load when used with compare-swap
|
||||
instruct loadPLocked(eRegP dst, memory mem) %{
|
||||
match(Set dst (LoadPLocked mem));
|
||||
|
@ -7504,17 +7504,6 @@ instruct castII(rRegI dst)
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
instruct castLL(rRegL dst)
|
||||
%{
|
||||
match(Set dst (CastLL dst));
|
||||
|
||||
size(0);
|
||||
format %{ "# castLL of $dst" %}
|
||||
ins_encode(/* empty encoding */);
|
||||
ins_cost(0);
|
||||
ins_pipe(empty);
|
||||
%}
|
||||
|
||||
// LoadP-locked same as a regular LoadP when used with compare-swap
|
||||
instruct loadPLocked(rRegP dst, memory mem)
|
||||
%{
|
||||
|
@ -63,14 +63,6 @@ const Type* ConstraintCastNode::Value(PhaseGVN* phase) const {
|
||||
if (rt->empty()) assert(ft == Type::TOP, "special case #2");
|
||||
break;
|
||||
}
|
||||
case Op_CastLL:
|
||||
{
|
||||
const Type* t1 = phase->type(in(1));
|
||||
if (t1 == Type::TOP) assert(ft == Type::TOP, "special case #1");
|
||||
const Type* rt = t1->join_speculative(_type);
|
||||
if (rt->empty()) assert(ft == Type::TOP, "special case #2");
|
||||
break;
|
||||
}
|
||||
case Op_CastPP:
|
||||
if (phase->type(in(1)) == TypePtr::NULL_PTR &&
|
||||
_type->isa_ptr() && _type->is_ptr()->_ptr == TypePtr::NotNull)
|
||||
@ -104,11 +96,6 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
|
||||
cast->set_req(0, c);
|
||||
return cast;
|
||||
}
|
||||
case Op_CastLL: {
|
||||
Node* cast = new CastLLNode(n, t, carry_dependency);
|
||||
cast->set_req(0, c);
|
||||
return cast;
|
||||
}
|
||||
case Op_CastPP: {
|
||||
Node* cast = new CastPPNode(n, t, carry_dependency);
|
||||
cast->set_req(0, c);
|
||||
@ -292,45 +279,6 @@ void CastIINode::dump_spec(outputStream* st) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
Node* CastLLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
|
||||
Node* progress = ConstraintCastNode::Ideal(phase, can_reshape);
|
||||
if (progress != NULL) {
|
||||
return progress;
|
||||
}
|
||||
|
||||
// Same as in CastIINode::Ideal but for TypeLong instead of TypeInt
|
||||
if (can_reshape && !phase->C->major_progress()) {
|
||||
const TypeLong* this_type = this->type()->is_long();
|
||||
const TypeLong* in_type = phase->type(in(1))->isa_long();
|
||||
if (in_type != NULL && this_type != NULL &&
|
||||
(in_type->_lo != this_type->_lo ||
|
||||
in_type->_hi != this_type->_hi)) {
|
||||
jlong lo1 = this_type->_lo;
|
||||
jlong hi1 = this_type->_hi;
|
||||
int w1 = this_type->_widen;
|
||||
|
||||
if (lo1 >= 0) {
|
||||
// Keep a range assertion of >=0.
|
||||
lo1 = 0; hi1 = max_jlong;
|
||||
} else if (hi1 < 0) {
|
||||
// Keep a range assertion of <0.
|
||||
lo1 = min_jlong; hi1 = -1;
|
||||
} else {
|
||||
lo1 = min_jlong; hi1 = max_jlong;
|
||||
}
|
||||
const TypeLong* wtype = TypeLong::make(MAX2(in_type->_lo, lo1),
|
||||
MIN2(in_type->_hi, hi1),
|
||||
MAX2((int)in_type->_widen, w1));
|
||||
if (wtype != type()) {
|
||||
set_type(wtype);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//------------------------------Identity---------------------------------------
|
||||
// If input is already higher or equal to cast type, then this is an identity.
|
||||
|
@ -91,19 +91,6 @@ class CastIINode: public ConstraintCastNode {
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------CastLLNode-------------------------------------
|
||||
// cast long to long (different range)
|
||||
class CastLLNode: public ConstraintCastNode {
|
||||
public:
|
||||
CastLLNode(Node* n, const Type* t, bool carry_dependency = false)
|
||||
: ConstraintCastNode(n, t, carry_dependency) {
|
||||
init_class_id(Class_CastLL);
|
||||
}
|
||||
virtual int Opcode() const;
|
||||
virtual uint ideal_reg() const { return Op_RegL; }
|
||||
virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
|
||||
};
|
||||
|
||||
//------------------------------CastPPNode-------------------------------------
|
||||
// cast pointer to pointer (different type)
|
||||
class CastPPNode: public ConstraintCastNode {
|
||||
|
@ -1915,13 +1915,12 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// Wait until after parsing for the type information to propagate from the casts.
|
||||
assert(can_reshape, "Invalid during parsing");
|
||||
const Type* phi_type = bottom_type();
|
||||
assert(phi_type->isa_int() || phi_type->isa_long() || phi_type->isa_ptr(), "bad phi type");
|
||||
// Add casts to carry the control dependency of the Phi that is going away
|
||||
assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type");
|
||||
// Add casts to carry the control dependency of the Phi that is
|
||||
// going away
|
||||
Node* cast = NULL;
|
||||
if (phi_type->isa_int()) {
|
||||
cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true);
|
||||
} else if (phi_type->isa_long()) {
|
||||
cast = ConstraintCastNode::make_cast(Op_CastLL, r, uin, phi_type, true);
|
||||
} else {
|
||||
const Type* uin_type = phase->type(uin);
|
||||
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
|
||||
|
@ -61,7 +61,6 @@ macro(CallLeafNoFP)
|
||||
macro(CallRuntime)
|
||||
macro(CallStaticJava)
|
||||
macro(CastII)
|
||||
macro(CastLL)
|
||||
macro(CastX2P)
|
||||
macro(CastP2X)
|
||||
macro(CastPP)
|
||||
|
@ -1365,37 +1365,35 @@ Node* GraphKit::null_check_common(Node* value, BasicType type,
|
||||
|
||||
// Cast obj to not-null on this path, if there is no null_control.
|
||||
// (If there is a null_control, a non-null value may come back to haunt us.)
|
||||
return cast_not_null(value, (null_control == NULL || (*null_control) == top()));
|
||||
if (type == T_OBJECT) {
|
||||
Node* cast = cast_not_null(value, false);
|
||||
if (null_control == NULL || (*null_control) == top())
|
||||
replace_in_map(value, cast);
|
||||
value = cast;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------cast_not_null----------------------------------
|
||||
// Cast obj to not-null on this path
|
||||
Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
|
||||
Node* cast = NULL;
|
||||
const Type* t = _gvn.type(obj);
|
||||
if (t->make_ptr() != NULL) {
|
||||
const Type* t_not_null = t->join_speculative(TypePtr::NOTNULL);
|
||||
// Object is already not-null?
|
||||
if (t == t_not_null) {
|
||||
return obj;
|
||||
}
|
||||
cast = ConstraintCastNode::make_cast(Op_CastPP, control(), obj, t_not_null, false);
|
||||
} else if (t->isa_int() != NULL) {
|
||||
cast = ConstraintCastNode::make_cast(Op_CastII, control(), obj, TypeInt::INT, true);
|
||||
} else if (t->isa_long() != NULL) {
|
||||
cast = ConstraintCastNode::make_cast(Op_CastLL, control(), obj, TypeLong::LONG, true);
|
||||
} else {
|
||||
fatal("unexpected type: %s", type2name(t->basic_type()));
|
||||
}
|
||||
cast = _gvn.transform(cast);
|
||||
const Type *t = _gvn.type(obj);
|
||||
const Type *t_not_null = t->join_speculative(TypePtr::NOTNULL);
|
||||
// Object is already not-null?
|
||||
if( t == t_not_null ) return obj;
|
||||
|
||||
Node *cast = new CastPPNode(obj,t_not_null);
|
||||
cast->init_req(0, control());
|
||||
cast = _gvn.transform( cast );
|
||||
|
||||
// Scan for instances of 'obj' in the current JVM mapping.
|
||||
// These instances are known to be not-null after the test.
|
||||
if (do_replace_in_map) {
|
||||
if (do_replace_in_map)
|
||||
replace_in_map(obj, cast);
|
||||
}
|
||||
return cast;
|
||||
|
||||
return cast; // Return casted value
|
||||
}
|
||||
|
||||
// Sometimes in intrinsics, we implicitly know an object is not null
|
||||
|
@ -52,7 +52,6 @@ class CallNode;
|
||||
class CallRuntimeNode;
|
||||
class CallStaticJavaNode;
|
||||
class CastIINode;
|
||||
class CastLLNode;
|
||||
class CatchNode;
|
||||
class CatchProjNode;
|
||||
class CheckCastPPNode;
|
||||
@ -667,8 +666,7 @@ public:
|
||||
DEFINE_CLASS_ID(Phi, Type, 0)
|
||||
DEFINE_CLASS_ID(ConstraintCast, Type, 1)
|
||||
DEFINE_CLASS_ID(CastII, ConstraintCast, 0)
|
||||
DEFINE_CLASS_ID(CastLL, ConstraintCast, 1)
|
||||
DEFINE_CLASS_ID(CheckCastPP, ConstraintCast, 2)
|
||||
DEFINE_CLASS_ID(CheckCastPP, ConstraintCast, 1)
|
||||
DEFINE_CLASS_ID(CMove, Type, 3)
|
||||
DEFINE_CLASS_ID(SafePointScalarObject, Type, 4)
|
||||
DEFINE_CLASS_ID(DecodeNarrowPtr, Type, 5)
|
||||
@ -811,7 +809,6 @@ public:
|
||||
DEFINE_CLASS_QUERY(CatchProj)
|
||||
DEFINE_CLASS_QUERY(CheckCastPP)
|
||||
DEFINE_CLASS_QUERY(CastII)
|
||||
DEFINE_CLASS_QUERY(CastLL)
|
||||
DEFINE_CLASS_QUERY(ConstraintCast)
|
||||
DEFINE_CLASS_QUERY(ClearArray)
|
||||
DEFINE_CLASS_QUERY(CMove)
|
||||
|
@ -1583,7 +1583,6 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
declare_c2_type(DecodeNKlassNode, TypeNode) \
|
||||
declare_c2_type(ConstraintCastNode, TypeNode) \
|
||||
declare_c2_type(CastIINode, ConstraintCastNode) \
|
||||
declare_c2_type(CastLLNode, ConstraintCastNode) \
|
||||
declare_c2_type(CastPPNode, ConstraintCastNode) \
|
||||
declare_c2_type(CheckCastPPNode, TypeNode) \
|
||||
declare_c2_type(Conv2BNode, Node) \
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.java.text;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@Warmup(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)
|
||||
@Fork(1)
|
||||
@State(Scope.Benchmark)
|
||||
public class DefFormatterBench {
|
||||
|
||||
@Param({"1.23", "1.49", "1.80", "1.7", "0.0", "-1.49", "-1.50", "9999.9123", "1.494", "1.495", "1.03", "25.996", "-25.996"})
|
||||
public double value;
|
||||
|
||||
private DefNumerFormat dnf = new DefNumerFormat();
|
||||
|
||||
@Benchmark
|
||||
public void testDefNumberFormatter(final Blackhole blackhole) {
|
||||
blackhole.consume(this.dnf.format(this.value));
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
Options opts = new OptionsBuilder().include(DefFormatterBench.class.getSimpleName()).shouldDoGC(true).build();
|
||||
new Runner(opts).run();
|
||||
}
|
||||
|
||||
private static class DefNumerFormat {
|
||||
|
||||
private final NumberFormat n;
|
||||
|
||||
public DefNumerFormat() {
|
||||
this.n = NumberFormat.getInstance(Locale.ENGLISH);
|
||||
this.n.setMaximumFractionDigits(2);
|
||||
this.n.setMinimumFractionDigits(2);
|
||||
this.n.setGroupingUsed(false);
|
||||
}
|
||||
|
||||
public String format(final double d) {
|
||||
return this.n.format(d);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user