--- old/src/hotspot/cpu/x86/templateTable_x86.cpp 2019-01-25 11:00:49.123306721 +0100 +++ new/src/hotspot/cpu/x86/templateTable_x86.cpp 2019-01-25 11:00:42.677315742 +0100 @@ -2477,7 +2477,7 @@ __ pop_ptr(rdx); const int is_value_mask = markOopDesc::always_locked_pattern; - if (EnableValhalla && UsePointerPerturbation) { + if (EnableValhalla && ACmpOnValues == 1) { Label is_null; __ testptr(rdx, rdx); __ jcc(Assembler::zero, is_null); @@ -2492,7 +2492,7 @@ __ cmpoop(rdx, rax); - if (EnableValhalla && !UsePointerPerturbation) { + if (EnableValhalla && ACmpOnValues != 1) { __ jcc(Assembler::notEqual, (cc == not_equal) ? taken : not_taken); __ testptr(rdx, rdx); __ jcc(Assembler::zero, (cc == equal) ? taken : not_taken); --- old/src/hotspot/share/classfile/systemDictionary.hpp 2019-01-25 11:00:55.747297449 +0100 +++ new/src/hotspot/share/classfile/systemDictionary.hpp 2019-01-25 11:00:49.274306509 +0100 @@ -171,6 +171,7 @@ do_klass(Context_klass, java_lang_invoke_MethodHandleNatives_CallSiteContext ) \ do_klass(ConstantCallSite_klass, java_lang_invoke_ConstantCallSite ) \ do_klass(MutableCallSite_klass, java_lang_invoke_MutableCallSite ) \ + do_klass(ValueBootstrapMethods_klass, java_lang_invoke_ValueBootstrapMethods ) \ do_klass(VolatileCallSite_klass, java_lang_invoke_VolatileCallSite ) \ /* Note: MethodHandle must be first, and VolatileCallSite last in group */ \ \ --- old/src/hotspot/share/classfile/vmSymbols.hpp 2019-01-25 11:01:01.587289275 +0100 +++ new/src/hotspot/share/classfile/vmSymbols.hpp 2019-01-25 11:00:55.869297278 +0100 @@ -512,6 +512,7 @@ template(threadgroup_string_void_signature, "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V") \ template(string_class_signature, "(Ljava/lang/String;)Ljava/lang/Class;") \ template(object_object_object_signature, "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \ + template(object_object_boolean_signature, "(Ljava/lang/Object;Ljava/lang/Object;)Z") \ template(string_string_string_signature, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;") \ template(string_string_signature, "(Ljava/lang/String;)Ljava/lang/String;") \ template(classloader_string_long_signature, "(Ljava/lang/ClassLoader;Ljava/lang/String;)J") \ @@ -660,6 +661,8 @@ template(toFileURL_signature, "(Ljava/lang/String;)Ljava/net/URL;") \ template(url_void_signature, "(Ljava/net/URL;)V") \ \ + template(java_lang_invoke_ValueBootstrapMethods, "java/lang/invoke/ValueBootstrapMethods") \ + template(isSubstitutable_name, "isSubstitutable") \ /*end*/ // Here are all the intrinsics known to the runtime and the CI. --- old/src/hotspot/share/code/compiledMethod.cpp 2019-01-25 11:01:08.107280150 +0100 +++ new/src/hotspot/share/code/compiledMethod.cpp 2019-01-25 11:01:01.702289113 +0100 @@ -345,15 +345,12 @@ void CompiledMethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { if (method() != NULL && !method()->is_native()) { address pc = fr.pc(); - SimpleScopeDesc ssd(this, pc); - Bytecode_invoke call(ssd.method(), ssd.bci()); - bool has_receiver = call.has_receiver(); - bool has_appendix = call.has_appendix(); - Symbol* signature = call.signature(); - // The method attached by JIT-compilers should be used, if present. // Bytecode can be inaccurate in such case. Method* callee = attached_method_before_pc(pc); + bool has_receiver = false; + bool has_appendix = false; + Symbol* signature = NULL; if (callee != NULL) { has_receiver = !(callee->access_flags().is_static()); has_appendix = false; @@ -366,6 +363,12 @@ signature = SigEntry::create_symbol(sig); has_receiver = false; // The extended signature contains the receiver type } + } else { + SimpleScopeDesc ssd(this, pc); + Bytecode_invoke call(ssd.method(), ssd.bci()); + has_receiver = call.has_receiver(); + has_appendix = call.has_appendix(); + signature = call.signature(); } fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f); --- old/src/hotspot/share/opto/parse2.cpp 2019-01-25 11:01:14.149271694 +0100 +++ new/src/hotspot/share/opto/parse2.cpp 2019-01-25 11:01:08.183280043 +0100 @@ -1816,6 +1816,211 @@ } void Parse::do_acmp(BoolTest::mask btest, Node* a, Node* b) { + ciMethod* subst_method = ciEnv::current()->ValueBootstrapMethods_klass()->find_method(ciSymbol::isSubstitutable_name(), ciSymbol::object_object_boolean_signature()); + // If current method is ValueBootstrapMethods::isSubstitutable(), + // compile the acmp as a regular pointer comparison otherwise we + // could call ValueBootstrapMethods::isSubstitutable() back + if (ACmpOnValues == 0 || !EnableValhalla || method() == subst_method) { + Node* cmp = CmpP(a, b); + cmp = optimize_cmp_with_klass(cmp); + do_if(btest, cmp); + return; + } + + if (ACmpOnValues == 3) { + // Substituability test + if (a->is_ValueType()) { + inc_sp(2); + a = a->as_ValueType()->allocate(this, true)->get_oop(); + dec_sp(2); + } + if (b->is_ValueType()) { + inc_sp(2); + b = b->as_ValueType()->allocate(this, true)->get_oop(); + dec_sp(2); + } + + const TypeOopPtr* ta = _gvn.type(a)->isa_oopptr(); + const TypeOopPtr* tb = _gvn.type(b)->isa_oopptr(); + + if (ta == NULL || !ta->can_be_value_type() || + tb == NULL || !tb->can_be_value_type()) { + Node* cmp = CmpP(a, b); + cmp = optimize_cmp_with_klass(cmp); + do_if(btest, cmp); + return; + } + + Node* cmp = CmpP(a, b); + cmp = optimize_cmp_with_klass(cmp); + Node* eq_region = NULL; + if (btest == BoolTest::eq) { + do_if(btest, cmp, true); + if (stopped()) { + return; + } + } else { + assert(btest == BoolTest::ne, "only eq or ne"); + Node* is_not_equal = NULL; + eq_region = new RegionNode(3); + { + PreserveJVMState pjvms(this); + do_if(btest, cmp, false, &is_not_equal); + if (!stopped()) { + eq_region->init_req(1, control()); + } + } + if (is_not_equal == NULL || is_not_equal->is_top()) { + record_for_igvn(eq_region); + set_control(_gvn.transform(eq_region)); + return; + } + set_control(is_not_equal); + } + // Pointers not equal, check for values + Node* ne_region = new RegionNode(6); + inc_sp(2); + Node* null_ctl = top(); + Node* not_null_a = null_check_oop(a, &null_ctl, !too_many_traps(Deoptimization::Reason_null_check), false, false); + dec_sp(2); + ne_region->init_req(1, null_ctl); + if (stopped()) { + record_for_igvn(ne_region); + set_control(_gvn.transform(ne_region)); + if (btest == BoolTest::ne) { + { + PreserveJVMState pjvms(this); + int target_bci = iter().get_dest(); + merge(target_bci); + } + record_for_igvn(eq_region); + set_control(_gvn.transform(eq_region)); + } + return; + } + + Node* is_value = is_always_locked(not_null_a); + Node* value_mask = _gvn.MakeConX(markOopDesc::always_locked_pattern); + Node* is_value_cmp = _gvn.transform(new CmpXNode(is_value, value_mask)); + Node* is_value_bol = _gvn.transform(new BoolNode(is_value_cmp, BoolTest::ne)); + IfNode* is_value_iff = create_and_map_if(control(), is_value_bol, PROB_FAIR, COUNT_UNKNOWN); + Node* not_value = _gvn.transform(new IfTrueNode(is_value_iff)); + set_control(_gvn.transform(new IfFalseNode(is_value_iff))); + ne_region->init_req(2, not_value); + + // One of the 2 pointers refer to a value, check if both are of + // the same class + inc_sp(2); + null_ctl = top(); + Node* not_null_b = null_check_oop(b, &null_ctl, !too_many_traps(Deoptimization::Reason_null_check), false, false); + dec_sp(2); + ne_region->init_req(3, null_ctl); + if (stopped()) { + record_for_igvn(ne_region); + set_control(_gvn.transform(ne_region)); + if (btest == BoolTest::ne) { + { + PreserveJVMState pjvms(this); + int target_bci = iter().get_dest(); + merge(target_bci); + } + record_for_igvn(eq_region); + set_control(_gvn.transform(eq_region)); + } + return; + } + Node* kls_a = load_object_klass(not_null_a); + Node* kls_b = load_object_klass(not_null_b); + Node* kls_cmp = CmpP(kls_a, kls_b); + Node* kls_bol = _gvn.transform(new BoolNode(kls_cmp, BoolTest::ne)); + IfNode* kls_iff = create_and_map_if(control(), kls_bol, PROB_FAIR, COUNT_UNKNOWN); + Node* kls_ne = _gvn.transform(new IfTrueNode(kls_iff)); + set_control(_gvn.transform(new IfFalseNode(kls_iff))); + ne_region->init_req(4, kls_ne); + + if (stopped()) { + record_for_igvn(ne_region); + set_control(_gvn.transform(ne_region)); + if (btest == BoolTest::ne) { + { + PreserveJVMState pjvms(this); + int target_bci = iter().get_dest(); + merge(target_bci); + } + record_for_igvn(eq_region); + set_control(_gvn.transform(eq_region)); + } + return; + } + // Both are values of the same class, we need to perform a + // substituability test. Delegate to + // ValueBootstrapMethods::isSubstitutable(). + + Node* ne_io_phi = PhiNode::make(ne_region, i_o()); + Node* mem = reset_memory(); + Node* ne_mem_phi = PhiNode::make(ne_region, mem); + + Node* eq_io_phi = NULL; + Node* eq_mem_phi = NULL; + if (eq_region != NULL) { + eq_io_phi = PhiNode::make(eq_region, i_o()); + eq_mem_phi = PhiNode::make(eq_region, mem); + } + + set_all_memory(mem); + + kill_dead_locals(); + CallStaticJavaNode *call = new CallStaticJavaNode(C, TypeFunc::make(subst_method), SharedRuntime::get_resolve_static_call_stub(), subst_method, bci()); + call->set_override_symbolic_info(true); + call->init_req(TypeFunc::Parms, not_null_a); + call->init_req(TypeFunc::Parms+1, not_null_b); + inc_sp(2); + set_edges_for_java_call(call, false, false); + Node* ret = set_results_for_java_call(call, false, true); + dec_sp(2); + + // Test the return value of ValueBootstrapMethods::isSubstitutable() + Node* subst_cmp = _gvn.transform(new CmpINode(ret, intcon(1))); + if (btest == BoolTest::eq) { + do_if(btest, subst_cmp); + } else { + assert(btest == BoolTest::ne, "only eq or ne"); + Node* is_not_equal = NULL; + { + PreserveJVMState pjvms(this); + do_if(btest, subst_cmp, false, &is_not_equal); + if (!stopped()) { + eq_region->init_req(2, control()); + eq_io_phi->init_req(2, i_o()); + eq_mem_phi->init_req(2, reset_memory()); + } + } + set_control(is_not_equal); + } + ne_region->init_req(5, control()); + ne_io_phi->init_req(5, i_o()); + ne_mem_phi->init_req(5, reset_memory()); + + record_for_igvn(ne_region); + set_control(_gvn.transform(ne_region)); + set_i_o(_gvn.transform(ne_io_phi)); + set_all_memory(_gvn.transform(ne_mem_phi)); + + if (btest == BoolTest::ne) { + { + PreserveJVMState pjvms(this); + int target_bci = iter().get_dest(); + merge(target_bci); + } + + record_for_igvn(eq_region); + set_control(_gvn.transform(eq_region)); + set_i_o(_gvn.transform(eq_io_phi)); + set_all_memory(_gvn.transform(eq_mem_phi)); + } + + return; + } // In the case were both operands might be value types, we need to // use the new acmp implementation. Otherwise, i.e. if one operand // is not a value type, we can use the old acmp implementation. @@ -1829,7 +2034,7 @@ Node* ctrl = NULL; bool safe_for_replace = true; - if (!UsePointerPerturbation) { + if (ACmpOnValues != 1) { // Emit old acmp before new acmp for quick a != b check cmp = CmpP(a, b); cmp = optimize_cmp_with_klass(_gvn.transform(cmp)); @@ -1889,7 +2094,7 @@ } Node* value_mask = _gvn.MakeConX(markOopDesc::always_locked_pattern); - if (UsePointerPerturbation) { + if (ACmpOnValues == 1) { Node* mark_addr = basic_plus_adr(not_null_a, oopDesc::mark_offset_in_bytes()); Node* mark = make_load(NULL, mark_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); Node* not_mark = _gvn.transform(new XorXNode(mark, _gvn.MakeConX(-1))); @@ -1904,7 +2109,7 @@ set_control(_gvn.transform(region)); is_value = _gvn.transform(is_value); - if (UsePointerPerturbation) { + if (ACmpOnValues == 1) { // Perturbe oop if operand is a value type to make comparison fail Node* pert = _gvn.transform(new AddPNode(a, a, is_value)); cmp = _gvn.transform(new CmpPNode(pert, b)); --- old/src/hotspot/share/opto/subnode.cpp 2019-01-25 11:01:20.503262803 +0100 +++ new/src/hotspot/share/opto/subnode.cpp 2019-01-25 11:01:14.236271572 +0100 @@ -834,9 +834,10 @@ // Simplify an CmpP (compare 2 pointers) node, based on local information. // If both inputs are constants, compare them. const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const { - if (t1->isa_valuetype() || t2->isa_valuetype() || - ((t1->is_valuetypeptr() || t2->is_valuetypeptr()) && - (!t1->maybe_null() || !t2->maybe_null()))) { + if (ACmpOnValues != 3 && + (t1->isa_valuetype() || t2->isa_valuetype() || + ((t1->is_valuetypeptr() || t2->is_valuetypeptr()) && + (!t1->maybe_null() || !t2->maybe_null())))) { // One operand is a value type and one operand is never null, fold to constant false return TypeInt::CC_GT; } @@ -1106,7 +1107,7 @@ // RawPtr comparison return NULL; } - assert(EnableValhalla && UsePointerPerturbation, "unexpected perturbed oop"); + assert(EnableValhalla && ACmpOnValues == 1, "unexpected perturbed oop"); return in(1); } return NULL; --- old/src/hotspot/share/runtime/globals.hpp 2019-01-25 11:01:27.158253486 +0100 +++ new/src/hotspot/share/runtime/globals.hpp 2019-01-25 11:01:20.585262689 +0100 @@ -2628,8 +2628,12 @@ develop(bool, ScalarizeValueTypes, true, \ "Scalarize value types in compiled code") \ \ - experimental(bool, UsePointerPerturbation, false, \ - "With value types, use the perturbation scheme for acmp") \ + experimental(uint, ACmpOnValues, 2, \ + "0 = regular acmp" \ + "1 = always false for value, perturbation scheme" \ + "2 = always false for value" \ + "3 = substitutably test") \ + range(0, 3) \ --- old/src/hotspot/share/runtime/sharedRuntime.cpp 2019-01-25 11:01:33.722244300 +0100 +++ new/src/hotspot/share/runtime/sharedRuntime.cpp 2019-01-25 11:01:27.264253338 +0100 @@ -1370,6 +1370,16 @@ // CLEANUP - with lazy deopt shouldn't need this lock nmethodLocker caller_lock(caller_nm); + if (!is_virtual && !is_optimized) { + SimpleScopeDesc ssd(caller_nm, caller_frame.pc()); + Bytecode bc(ssd.method(), ssd.method()->bcp_from(ssd.bci())); + // Substituability test implementation piggy backs on static call resolution + if (bc.code() == Bytecodes::_if_acmpeq || bc.code() == Bytecodes::_if_acmpne) { + SystemDictionary::ValueBootstrapMethods_klass()->initialize(CHECK_NULL); + return SystemDictionary::ValueBootstrapMethods_klass()->find_method(vmSymbols::isSubstitutable_name(), vmSymbols::object_object_boolean_signature()); + } + } + // determine call info & receiver // note: a) receiver is NULL for static calls // b) an exception is thrown if receiver is NULL for non-static calls --- old/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java 2019-01-25 11:01:40.888234274 +0100 +++ new/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java 2019-01-25 11:01:33.824244157 +0100 @@ -60,6 +60,45 @@ * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* * compiler.valhalla.valuetypes.TestNewAcmp 2 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch + * -XX:+EnableValhalla -XX:TypeProfileLevel=222 + * -XX:+UnlockExperimentalVMOptions -XX:ACmpOnValues=3 + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* + * compiler.valhalla.valuetypes.TestNewAcmp 0 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:+EnableValhalla -XX:TypeProfileLevel=222 + * -XX:+UnlockExperimentalVMOptions -XX:ACmpOnValues=3 + * -XX:+AlwaysIncrementalInline + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* + * compiler.valhalla.valuetypes.TestNewAcmp 0 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch + * -XX:+EnableValhalla -XX:TypeProfileLevel=222 + * -XX:+UnlockExperimentalVMOptions -XX:ACmpOnValues=3 + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* + * compiler.valhalla.valuetypes.TestNewAcmp 1 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:+EnableValhalla -XX:TypeProfileLevel=222 + * -XX:+UnlockExperimentalVMOptions -XX:ACmpOnValues=3 + * -XX:+AlwaysIncrementalInline + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* + * compiler.valhalla.valuetypes.TestNewAcmp 1 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch + * -XX:+EnableValhalla -XX:TypeProfileLevel=222 + * -XX:+UnlockExperimentalVMOptions -XX:ACmpOnValues=3 + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* + * compiler.valhalla.valuetypes.TestNewAcmp 2 + * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xbatch -XX:+EnableValhalla -XX:TypeProfileLevel=222 + * -XX:+UnlockExperimentalVMOptions -XX:ACmpOnValues=3 + * -XX:+AlwaysIncrementalInline + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::test* + * -XX:CompileCommand=dontinline,compiler.valhalla.valuetypes.TestNewAcmp::cmp* + * compiler.valhalla.valuetypes.TestNewAcmp 2 */ package compiler.valhalla.valuetypes; @@ -71,17 +110,34 @@ import java.lang.reflect.Method; import java.util.regex.Pattern; import java.util.regex.Matcher; +import java.util.Arrays; import sun.hotspot.WhiteBox; interface MyInterface { } -value class MyValue implements MyInterface { - final int x = 42; +value class MyValue1 implements MyInterface { + final int x = 0; + + static MyValue1 createDefault() { + return MyValue1.default; + } + + static MyValue1 setX(MyValue1 v, int x) { + return __WithField(v.x, x); + } +} + +value class MyValue2 implements MyInterface { + final int x = 0; + + static MyValue2 createDefault() { + return MyValue2.default; + } - static MyValue createDefault() { - return MyValue.default; + static MyValue2 setX(MyValue2 v, int x) { + return __WithField(v.x, x); } } @@ -91,11 +147,15 @@ // Mark test methods that return always false @Retention(RetentionPolicy.RUNTIME) -@interface AlwaysFalse { } +@interface AlwaysFalse { + int[] valid_for() default {1, 2}; +} // Mark test methods that return always true @Retention(RetentionPolicy.RUNTIME) -@interface AlwaysTrue { } +@interface AlwaysTrue { + int[] valid_for() default {1, 2}; +} // Mark test methods that return false if the argument is null @Retention(RetentionPolicy.RUNTIME) @@ -134,138 +194,138 @@ return getNotNull(u1) == getNotNull(u2); // new acmp without null check } - public boolean testEq02_1(MyValue v1, MyValue v2) { + public boolean testEq02_1(MyValue1 v1, MyValue1 v2) { return get(v1) == (Object)v2; // only true if both null } - public boolean testEq02_2(MyValue v1, MyValue v2) { + public boolean testEq02_2(MyValue1 v1, MyValue1 v2) { return (Object)v1 == get(v2); // only true if both null } - public boolean testEq02_3(MyValue v1, MyValue v2) { + public boolean testEq02_3(MyValue1 v1, MyValue1 v2) { return get(v1) == get(v2); // only true if both null } - public boolean testEq03_1(MyValue v, Object u) { + public boolean testEq03_1(MyValue1 v, Object u) { return get(v) == u; // only true if both null } - public boolean testEq03_2(MyValue v, Object u) { + public boolean testEq03_2(MyValue1 v, Object u) { return (Object)v == get(u); // only true if both null } - public boolean testEq03_3(MyValue v, Object u) { + public boolean testEq03_3(MyValue1 v, Object u) { return get(v) == get(u); // only true if both null } - public boolean testEq04_1(Object u, MyValue v) { + public boolean testEq04_1(Object u, MyValue1 v) { return get(u) == (Object)v; // only true if both null } - public boolean testEq04_2(Object u, MyValue v) { + public boolean testEq04_2(Object u, MyValue1 v) { return u == get(v); // only true if both null } - public boolean testEq04_3(Object u, MyValue v) { + public boolean testEq04_3(Object u, MyValue1 v) { return get(u) == get(v); // only true if both null } - public boolean testEq05_1(MyObject o, MyValue v) { + public boolean testEq05_1(MyObject o, MyValue1 v) { return get(o) == (Object)v; // only true if both null } - public boolean testEq05_2(MyObject o, MyValue v) { + public boolean testEq05_2(MyObject o, MyValue1 v) { return o == get(v); // only true if both null } - public boolean testEq05_3(MyObject o, MyValue v) { + public boolean testEq05_3(MyObject o, MyValue1 v) { return get(o) == get(v); // only true if both null } - public boolean testEq06_1(MyValue v, MyObject o) { + public boolean testEq06_1(MyValue1 v, MyObject o) { return get(v) == o; // only true if both null } - public boolean testEq06_2(MyValue v, MyObject o) { + public boolean testEq06_2(MyValue1 v, MyObject o) { return (Object)v == get(o); // only true if both null } - public boolean testEq06_3(MyValue v, MyObject o) { + public boolean testEq06_3(MyValue1 v, MyObject o) { return get(v) == get(o); // only true if both null } @AlwaysFalse - public boolean testEq07_1(MyValue v1, MyValue v2) { + public boolean testEq07_1(MyValue1 v1, MyValue1 v2) { return getNotNull(v1) == (Object)v2; // false } @AlwaysFalse - public boolean testEq07_2(MyValue v1, MyValue v2) { + public boolean testEq07_2(MyValue1 v1, MyValue1 v2) { return (Object)v1 == getNotNull(v2); // false } @AlwaysFalse - public boolean testEq07_3(MyValue v1, MyValue v2) { + public boolean testEq07_3(MyValue1 v1, MyValue1 v2) { return getNotNull(v1) == getNotNull(v2); // false } @AlwaysFalse - public boolean testEq08_1(MyValue v, Object u) { + public boolean testEq08_1(MyValue1 v, Object u) { return getNotNull(v) == u; // false } @AlwaysFalse - public boolean testEq08_2(MyValue v, Object u) { + public boolean testEq08_2(MyValue1 v, Object u) { return (Object)v == getNotNull(u); // false } @AlwaysFalse - public boolean testEq08_3(MyValue v, Object u) { + public boolean testEq08_3(MyValue1 v, Object u) { return getNotNull(v) == getNotNull(u); // false } @AlwaysFalse - public boolean testEq09_1(Object u, MyValue v) { + public boolean testEq09_1(Object u, MyValue1 v) { return getNotNull(u) == (Object)v; // false } @AlwaysFalse - public boolean testEq09_2(Object u, MyValue v) { + public boolean testEq09_2(Object u, MyValue1 v) { return u == getNotNull(v); // false } @AlwaysFalse - public boolean testEq09_3(Object u, MyValue v) { + public boolean testEq09_3(Object u, MyValue1 v) { return getNotNull(u) == getNotNull(v); // false } @AlwaysFalse - public boolean testEq10_1(MyObject o, MyValue v) { + public boolean testEq10_1(MyObject o, MyValue1 v) { return getNotNull(o) == (Object)v; // false } @AlwaysFalse - public boolean testEq10_2(MyObject o, MyValue v) { + public boolean testEq10_2(MyObject o, MyValue1 v) { return o == getNotNull(v); // false } @AlwaysFalse - public boolean testEq10_3(MyObject o, MyValue v) { + public boolean testEq10_3(MyObject o, MyValue1 v) { return getNotNull(o) == getNotNull(v); // false } @AlwaysFalse - public boolean testEq11_1(MyValue v, MyObject o) { + public boolean testEq11_1(MyValue1 v, MyObject o) { return getNotNull(v) == o; // false } @AlwaysFalse - public boolean testEq11_2(MyValue v, MyObject o) { + public boolean testEq11_2(MyValue1 v, MyObject o) { return (Object)v == getNotNull(o); // false } @AlwaysFalse - public boolean testEq11_3(MyValue v, MyObject o) { + public boolean testEq11_3(MyValue1 v, MyObject o) { return getNotNull(v) == getNotNull(o); // false } @@ -329,57 +389,57 @@ return get(u) == get(a); // old acmp } - public boolean testEq17_1(Object[] a, MyValue v) { + public boolean testEq17_1(Object[] a, MyValue1 v) { return get(a) == (Object)v; // only true if both null } - public boolean testEq17_2(Object[] a, MyValue v) { + public boolean testEq17_2(Object[] a, MyValue1 v) { return a == get(v); // only true if both null } - public boolean testEq17_3(Object[] a, MyValue v) { + public boolean testEq17_3(Object[] a, MyValue1 v) { return get(a) == get(v); // only true if both null } - public boolean testEq18_1(MyValue v, Object[] a) { + public boolean testEq18_1(MyValue1 v, Object[] a) { return get(v) == a; // only true if both null } - public boolean testEq18_2(MyValue v, Object[] a) { + public boolean testEq18_2(MyValue1 v, Object[] a) { return (Object)v == get(a); // only true if both null } - public boolean testEq18_3(MyValue v, Object[] a) { + public boolean testEq18_3(MyValue1 v, Object[] a) { return get(v) == get(a); // only true if both null } @AlwaysFalse - public boolean testEq19_1(Object[] a, MyValue v) { + public boolean testEq19_1(Object[] a, MyValue1 v) { return getNotNull(a) == (Object)v; // false } @AlwaysFalse - public boolean testEq19_2(Object[] a, MyValue v) { + public boolean testEq19_2(Object[] a, MyValue1 v) { return a == getNotNull(v); // false } @AlwaysFalse - public boolean testEq19_3(Object[] a, MyValue v) { + public boolean testEq19_3(Object[] a, MyValue1 v) { return getNotNull(a) == getNotNull(v); // false } @AlwaysFalse - public boolean testEq20_1(MyValue v, Object[] a) { + public boolean testEq20_1(MyValue1 v, Object[] a) { return getNotNull(v) == a; // false } @AlwaysFalse - public boolean testEq20_2(MyValue v, Object[] a) { + public boolean testEq20_2(MyValue1 v, Object[] a) { return (Object)v == getNotNull(a); // false } @AlwaysFalse - public boolean testEq20_3(MyValue v, Object[] a) { + public boolean testEq20_3(MyValue1 v, Object[] a) { return getNotNull(v) == getNotNull(a); // false } @@ -410,57 +470,57 @@ return getNotNull(u1) == getNotNull(u2); // new acmp without null check } - public boolean testEq22_1(MyValue v, MyInterface u) { + public boolean testEq22_1(MyValue1 v, MyInterface u) { return get(v) == u; // only true if both null } - public boolean testEq22_2(MyValue v, MyInterface u) { + public boolean testEq22_2(MyValue1 v, MyInterface u) { return (Object)v == get(u); // only true if both null } - public boolean testEq22_3(MyValue v, MyInterface u) { + public boolean testEq22_3(MyValue1 v, MyInterface u) { return get(v) == get(u); // only true if both null } - public boolean testEq23_1(MyInterface u, MyValue v) { + public boolean testEq23_1(MyInterface u, MyValue1 v) { return get(u) == (Object)v; // only true if both null } - public boolean testEq23_2(MyInterface u, MyValue v) { + public boolean testEq23_2(MyInterface u, MyValue1 v) { return u == get(v); // only true if both null } - public boolean testEq23_3(MyInterface u, MyValue v) { + public boolean testEq23_3(MyInterface u, MyValue1 v) { return get(u) == get(v); // only true if both null } @AlwaysFalse - public boolean testEq24_1(MyValue v, MyInterface u) { + public boolean testEq24_1(MyValue1 v, MyInterface u) { return getNotNull(v) == u; // false } @AlwaysFalse - public boolean testEq24_2(MyValue v, MyInterface u) { + public boolean testEq24_2(MyValue1 v, MyInterface u) { return (Object)v == getNotNull(u); // false } @AlwaysFalse - public boolean testEq24_3(MyValue v, MyInterface u) { + public boolean testEq24_3(MyValue1 v, MyInterface u) { return getNotNull(v) == getNotNull(u); // false } @AlwaysFalse - public boolean testEq25_1(MyInterface u, MyValue v) { + public boolean testEq25_1(MyInterface u, MyValue1 v) { return getNotNull(u) == (Object)v; // false } @AlwaysFalse - public boolean testEq25_2(MyInterface u, MyValue v) { + public boolean testEq25_2(MyInterface u, MyValue1 v) { return u == getNotNull(v); // false } @AlwaysFalse - public boolean testEq25_3(MyInterface u, MyValue v) { + public boolean testEq25_3(MyInterface u, MyValue1 v) { return getNotNull(u) == getNotNull(v); // false } @@ -512,92 +572,92 @@ return get(u) == get(a); // old acmp } - public boolean testEq30_1(MyInterface[] a, MyValue v) { + public boolean testEq30_1(MyInterface[] a, MyValue1 v) { return get(a) == (Object)v; // only true if both null } - public boolean testEq30_2(MyInterface[] a, MyValue v) { + public boolean testEq30_2(MyInterface[] a, MyValue1 v) { return a == get(v); // only true if both null } - public boolean testEq30_3(MyInterface[] a, MyValue v) { + public boolean testEq30_3(MyInterface[] a, MyValue1 v) { return get(a) == get(v); // only true if both null } - public boolean testEq31_1(MyValue v, MyInterface[] a) { + public boolean testEq31_1(MyValue1 v, MyInterface[] a) { return get(v) == a; // only true if both null } - public boolean testEq31_2(MyValue v, MyInterface[] a) { + public boolean testEq31_2(MyValue1 v, MyInterface[] a) { return (Object)v == get(a); // only true if both null } - public boolean testEq31_3(MyValue v, MyInterface[] a) { + public boolean testEq31_3(MyValue1 v, MyInterface[] a) { return get(v) == get(a); // only true if both null } @AlwaysFalse - public boolean testEq32_1(MyInterface[] a, MyValue v) { + public boolean testEq32_1(MyInterface[] a, MyValue1 v) { return getNotNull(a) == (Object)v; // false } @AlwaysFalse - public boolean testEq32_2(MyInterface[] a, MyValue v) { + public boolean testEq32_2(MyInterface[] a, MyValue1 v) { return a == getNotNull(v); // false } @AlwaysFalse - public boolean testEq32_3(MyInterface[] a, MyValue v) { + public boolean testEq32_3(MyInterface[] a, MyValue1 v) { return getNotNull(a) == getNotNull(v); // false } @AlwaysFalse - public boolean testEq33_1(MyValue v, MyInterface[] a) { + public boolean testEq33_1(MyValue1 v, MyInterface[] a) { return getNotNull(v) == a; // false } @AlwaysFalse - public boolean testEq33_2(MyValue v, MyInterface[] a) { + public boolean testEq33_2(MyValue1 v, MyInterface[] a) { return (Object)v == getNotNull(a); // false } @AlwaysFalse - public boolean testEq33_3(MyValue v, MyInterface[] a) { + public boolean testEq33_3(MyValue1 v, MyInterface[] a) { return getNotNull(v) == getNotNull(a); // false } // Null tests - public boolean testNull01_1(MyValue v) { + public boolean testNull01_1(MyValue1 v) { return (Object)v == null; // old acmp } - public boolean testNull01_2(MyValue v) { + public boolean testNull01_2(MyValue1 v) { return get(v) == null; // old acmp } - public boolean testNull01_3(MyValue v) { + public boolean testNull01_3(MyValue1 v) { return (Object)v == get((Object)null); // old acmp } - public boolean testNull01_4(MyValue v) { + public boolean testNull01_4(MyValue1 v) { return get(v) == get((Object)null); // old acmp } - public boolean testNull02_1(MyValue v) { + public boolean testNull02_1(MyValue1 v) { return null == (Object)v; // old acmp } - public boolean testNull02_2(MyValue v) { + public boolean testNull02_2(MyValue1 v) { return get((Object)null) == (Object)v; // old acmp } - public boolean testNull02_3(MyValue v) { + public boolean testNull02_3(MyValue1 v) { return null == get(v); // old acmp } - public boolean testNull02_4(MyValue v) { + public boolean testNull02_4(MyValue1 v) { return get((Object)null) == get(v); // old acmp } @@ -726,138 +786,138 @@ return getNotNull(u1) != getNotNull(u2); // new acmp without null check } - public boolean testNotEq02_1(MyValue v1, MyValue v2) { + public boolean testNotEq02_1(MyValue1 v1, MyValue1 v2) { return get(v1) != (Object)v2; // only false if both null } - public boolean testNotEq02_2(MyValue v1, MyValue v2) { + public boolean testNotEq02_2(MyValue1 v1, MyValue1 v2) { return (Object)v1 != get(v2); // only false if both null } - public boolean testNotEq02_3(MyValue v1, MyValue v2) { + public boolean testNotEq02_3(MyValue1 v1, MyValue1 v2) { return get(v1) != get(v2); // only false if both null } - public boolean testNotEq03_1(MyValue v, Object u) { + public boolean testNotEq03_1(MyValue1 v, Object u) { return get(v) != u; // only false if both null } - public boolean testNotEq03_2(MyValue v, Object u) { + public boolean testNotEq03_2(MyValue1 v, Object u) { return (Object)v != get(u); // only false if both null } - public boolean testNotEq03_3(MyValue v, Object u) { + public boolean testNotEq03_3(MyValue1 v, Object u) { return get(v) != get(u); // only false if both null } - public boolean testNotEq04_1(Object u, MyValue v) { + public boolean testNotEq04_1(Object u, MyValue1 v) { return get(u) != (Object)v; // only false if both null } - public boolean testNotEq04_2(Object u, MyValue v) { + public boolean testNotEq04_2(Object u, MyValue1 v) { return u != get(v); // only false if both null } - public boolean testNotEq04_3(Object u, MyValue v) { + public boolean testNotEq04_3(Object u, MyValue1 v) { return get(u) != get(v); // only false if both null } - public boolean testNotEq05_1(MyObject o, MyValue v) { + public boolean testNotEq05_1(MyObject o, MyValue1 v) { return get(o) != (Object)v; // only false if both null } - public boolean testNotEq05_2(MyObject o, MyValue v) { + public boolean testNotEq05_2(MyObject o, MyValue1 v) { return o != get(v); // only false if both null } - public boolean testNotEq05_3(MyObject o, MyValue v) { + public boolean testNotEq05_3(MyObject o, MyValue1 v) { return get(o) != get(v); // only false if both null } - public boolean testNotEq06_1(MyValue v, MyObject o) { + public boolean testNotEq06_1(MyValue1 v, MyObject o) { return get(v) != o; // only false if both null } - public boolean testNotEq06_2(MyValue v, MyObject o) { + public boolean testNotEq06_2(MyValue1 v, MyObject o) { return (Object)v != get(o); // only false if both null } - public boolean testNotEq06_3(MyValue v, MyObject o) { + public boolean testNotEq06_3(MyValue1 v, MyObject o) { return get(v) != get(o); // only false if both null } @AlwaysTrue - public boolean testNotEq07_1(MyValue v1, MyValue v2) { + public boolean testNotEq07_1(MyValue1 v1, MyValue1 v2) { return getNotNull(v1) != (Object)v2; // true } @AlwaysTrue - public boolean testNotEq07_2(MyValue v1, MyValue v2) { + public boolean testNotEq07_2(MyValue1 v1, MyValue1 v2) { return (Object)v1 != getNotNull(v2); // true } @AlwaysTrue - public boolean testNotEq07_3(MyValue v1, MyValue v2) { + public boolean testNotEq07_3(MyValue1 v1, MyValue1 v2) { return getNotNull(v1) != getNotNull(v2); // true } @AlwaysTrue - public boolean testNotEq08_1(MyValue v, Object u) { + public boolean testNotEq08_1(MyValue1 v, Object u) { return getNotNull(v) != u; // true } @AlwaysTrue - public boolean testNotEq08_2(MyValue v, Object u) { + public boolean testNotEq08_2(MyValue1 v, Object u) { return (Object)v != getNotNull(u); // true } @AlwaysTrue - public boolean testNotEq08_3(MyValue v, Object u) { + public boolean testNotEq08_3(MyValue1 v, Object u) { return getNotNull(v) != getNotNull(u); // true } @AlwaysTrue - public boolean testNotEq09_1(Object u, MyValue v) { + public boolean testNotEq09_1(Object u, MyValue1 v) { return getNotNull(u) != (Object)v; // true } @AlwaysTrue - public boolean testNotEq09_2(Object u, MyValue v) { + public boolean testNotEq09_2(Object u, MyValue1 v) { return u != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq09_3(Object u, MyValue v) { + public boolean testNotEq09_3(Object u, MyValue1 v) { return getNotNull(u) != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq10_1(MyObject o, MyValue v) { + public boolean testNotEq10_1(MyObject o, MyValue1 v) { return getNotNull(o) != (Object)v; // true } @AlwaysTrue - public boolean testNotEq10_2(MyObject o, MyValue v) { + public boolean testNotEq10_2(MyObject o, MyValue1 v) { return o != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq10_3(MyObject o, MyValue v) { + public boolean testNotEq10_3(MyObject o, MyValue1 v) { return getNotNull(o) != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq11_1(MyValue v, MyObject o) { + public boolean testNotEq11_1(MyValue1 v, MyObject o) { return getNotNull(v) != o; // true } @AlwaysTrue - public boolean testNotEq11_2(MyValue v, MyObject o) { + public boolean testNotEq11_2(MyValue1 v, MyObject o) { return (Object)v != getNotNull(o); // true } @AlwaysTrue - public boolean testNotEq11_3(MyValue v, MyObject o) { + public boolean testNotEq11_3(MyValue1 v, MyObject o) { return getNotNull(v) != getNotNull(o); // true } @@ -921,57 +981,57 @@ return get(u) != get(a); // old acmp } - public boolean testNotEq17_1(Object[] a, MyValue v) { + public boolean testNotEq17_1(Object[] a, MyValue1 v) { return get(a) != (Object)v; // only false if both null } - public boolean testNotEq17_2(Object[] a, MyValue v) { + public boolean testNotEq17_2(Object[] a, MyValue1 v) { return a != get(v); // only false if both null } - public boolean testNotEq17_3(Object[] a, MyValue v) { + public boolean testNotEq17_3(Object[] a, MyValue1 v) { return get(a) != get(v); // only false if both null } - public boolean testNotEq18_1(MyValue v, Object[] a) { + public boolean testNotEq18_1(MyValue1 v, Object[] a) { return get(v) != a; // only false if both null } - public boolean testNotEq18_2(MyValue v, Object[] a) { + public boolean testNotEq18_2(MyValue1 v, Object[] a) { return (Object)v != get(a); // only false if both null } - public boolean testNotEq18_3(MyValue v, Object[] a) { + public boolean testNotEq18_3(MyValue1 v, Object[] a) { return get(v) != get(a); // only false if both null } @AlwaysTrue - public boolean testNotEq19_1(Object[] a, MyValue v) { + public boolean testNotEq19_1(Object[] a, MyValue1 v) { return getNotNull(a) != (Object)v; // true } @AlwaysTrue - public boolean testNotEq19_2(Object[] a, MyValue v) { + public boolean testNotEq19_2(Object[] a, MyValue1 v) { return a != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq19_3(Object[] a, MyValue v) { + public boolean testNotEq19_3(Object[] a, MyValue1 v) { return getNotNull(a) != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq20_1(MyValue v, Object[] a) { + public boolean testNotEq20_1(MyValue1 v, Object[] a) { return getNotNull(v) != a; // true } @AlwaysTrue - public boolean testNotEq20_2(MyValue v, Object[] a) { + public boolean testNotEq20_2(MyValue1 v, Object[] a) { return (Object)v != getNotNull(a); // true } @AlwaysTrue - public boolean testNotEq20_3(MyValue v, Object[] a) { + public boolean testNotEq20_3(MyValue1 v, Object[] a) { return getNotNull(v) != getNotNull(a); // true } @@ -1002,57 +1062,57 @@ return getNotNull(u1) != getNotNull(u2); // new acmp without null check } - public boolean testNotEq22_1(MyValue v, MyInterface u) { + public boolean testNotEq22_1(MyValue1 v, MyInterface u) { return get(v) != u; // only false if both null } - public boolean testNotEq22_2(MyValue v, MyInterface u) { + public boolean testNotEq22_2(MyValue1 v, MyInterface u) { return (Object)v != get(u); // only false if both null } - public boolean testNotEq22_3(MyValue v, MyInterface u) { + public boolean testNotEq22_3(MyValue1 v, MyInterface u) { return get(v) != get(u); // only false if both null } - public boolean testNotEq23_1(MyInterface u, MyValue v) { + public boolean testNotEq23_1(MyInterface u, MyValue1 v) { return get(u) != (Object)v; // only false if both null } - public boolean testNotEq23_2(MyInterface u, MyValue v) { + public boolean testNotEq23_2(MyInterface u, MyValue1 v) { return u != get(v); // only false if both null } - public boolean testNotEq23_3(MyInterface u, MyValue v) { + public boolean testNotEq23_3(MyInterface u, MyValue1 v) { return get(u) != get(v); // only false if both null } @AlwaysTrue - public boolean testNotEq24_1(MyValue v, MyInterface u) { + public boolean testNotEq24_1(MyValue1 v, MyInterface u) { return getNotNull(v) != u; // true } @AlwaysTrue - public boolean testNotEq24_2(MyValue v, MyInterface u) { + public boolean testNotEq24_2(MyValue1 v, MyInterface u) { return (Object)v != getNotNull(u); // true } @AlwaysTrue - public boolean testNotEq24_3(MyValue v, MyInterface u) { + public boolean testNotEq24_3(MyValue1 v, MyInterface u) { return getNotNull(v) != getNotNull(u); // true } @AlwaysTrue - public boolean testNotEq25_1(MyInterface u, MyValue v) { + public boolean testNotEq25_1(MyInterface u, MyValue1 v) { return getNotNull(u) != (Object)v; // true } @AlwaysTrue - public boolean testNotEq25_2(MyInterface u, MyValue v) { + public boolean testNotEq25_2(MyInterface u, MyValue1 v) { return u != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq25_3(MyInterface u, MyValue v) { + public boolean testNotEq25_3(MyInterface u, MyValue1 v) { return getNotNull(u) != getNotNull(v); // true } @@ -1104,91 +1164,91 @@ return get(u) != get(a); // old acmp } - public boolean testNotEq30_1(MyInterface[] a, MyValue v) { + public boolean testNotEq30_1(MyInterface[] a, MyValue1 v) { return get(a) != (Object)v; // only false if both null } - public boolean testNotEq30_2(MyInterface[] a, MyValue v) { + public boolean testNotEq30_2(MyInterface[] a, MyValue1 v) { return a != get(v); // only false if both null } - public boolean testNotEq30_3(MyInterface[] a, MyValue v) { + public boolean testNotEq30_3(MyInterface[] a, MyValue1 v) { return get(a) != get(v); // only false if both null } - public boolean testNotEq31_1(MyValue v, MyInterface[] a) { + public boolean testNotEq31_1(MyValue1 v, MyInterface[] a) { return get(v) != a; // only false if both null } - public boolean testNotEq31_2(MyValue v, MyInterface[] a) { + public boolean testNotEq31_2(MyValue1 v, MyInterface[] a) { return (Object)v != get(a); // only false if both null } - public boolean testNotEq31_3(MyValue v, MyInterface[] a) { + public boolean testNotEq31_3(MyValue1 v, MyInterface[] a) { return get(v) != get(a); // only false if both null } @AlwaysTrue - public boolean testNotEq32_1(MyInterface[] a, MyValue v) { + public boolean testNotEq32_1(MyInterface[] a, MyValue1 v) { return getNotNull(a) != (Object)v; // true } @AlwaysTrue - public boolean testNotEq32_2(MyInterface[] a, MyValue v) { + public boolean testNotEq32_2(MyInterface[] a, MyValue1 v) { return a != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq32_3(MyInterface[] a, MyValue v) { + public boolean testNotEq32_3(MyInterface[] a, MyValue1 v) { return getNotNull(a) != getNotNull(v); // true } @AlwaysTrue - public boolean testNotEq33_1(MyValue v, MyInterface[] a) { + public boolean testNotEq33_1(MyValue1 v, MyInterface[] a) { return getNotNull(v) != a; // true } @AlwaysTrue - public boolean testNotEq33_2(MyValue v, MyInterface[] a) { + public boolean testNotEq33_2(MyValue1 v, MyInterface[] a) { return (Object)v != getNotNull(a); // true } @AlwaysTrue - public boolean testNotEq33_3(MyValue v, MyInterface[] a) { + public boolean testNotEq33_3(MyValue1 v, MyInterface[] a) { return getNotNull(v) != getNotNull(a); // true } // Null tests - public boolean testNotNull01_1(MyValue v) { + public boolean testNotNull01_1(MyValue1 v) { return (Object)v != null; // old acmp } - public boolean testNotNull01_2(MyValue v) { + public boolean testNotNull01_2(MyValue1 v) { return get(v) != null; // old acmp } - public boolean testNotNull01_3(MyValue v) { + public boolean testNotNull01_3(MyValue1 v) { return (Object)v != get((Object)null); // old acmp } - public boolean testNotNull01_4(MyValue v) { + public boolean testNotNull01_4(MyValue1 v) { return get(v) != get((Object)null); // old acmp } - public boolean testNotNull02_1(MyValue v) { + public boolean testNotNull02_1(MyValue1 v) { return null != (Object)v; // old acmp } - public boolean testNotNull02_2(MyValue v) { + public boolean testNotNull02_2(MyValue1 v) { return get((Object)null) != (Object)v; // old acmp } - public boolean testNotNull02_3(MyValue v) { + public boolean testNotNull02_3(MyValue1 v) { return null != get(v); // old acmp } - public boolean testNotNull02_4(MyValue v) { + public boolean testNotNull02_4(MyValue1 v) { return get((Object)null) != get(v); // old acmp } @@ -1298,12 +1358,12 @@ return (u != null) ? u : new Object(); } - public Object get(MyValue v) { + public Object get(MyValue1 v) { return v; } - public Object getNotNull(MyValue v) { - return ((Object)v != null) ? v : MyValue.createDefault(); + public Object getNotNull(MyValue1 v) { + return ((Object)v != null) ? v : MyValue1.createDefault(); } public Object get(MyObject o) { @@ -1311,7 +1371,7 @@ } public Object getNotNull(MyObject o) { - return (o != null) ? o : MyValue.createDefault(); + return (o != null) ? o : MyValue1.createDefault(); } public Object get(Object[] a) { @@ -1331,11 +1391,13 @@ } public boolean alwaysTrue(Method m) { - return m.isAnnotationPresent(AlwaysTrue.class); + return m.isAnnotationPresent(AlwaysTrue.class) && + Arrays.asList(((AlwaysTrue)m.getAnnotation(AlwaysTrue.class)).valid_for()).contains(ACmpOnValues); } public boolean alwaysFalse(Method m) { - return m.isAnnotationPresent(AlwaysFalse.class); + return m.isAnnotationPresent(AlwaysFalse.class) && + Arrays.asList(((AlwaysFalse)m.getAnnotation(AlwaysFalse.class)).valid_for()).contains(ACmpOnValues); } public boolean isNegated(Method m) { @@ -1385,8 +1447,9 @@ protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; + protected static final long ACmpOnValues = (Long)WHITE_BOX.getVMFlag("ACmpOnValues"); - public void runTest(Method m, Object[] args, int warmup, int nullMode) throws Exception { + public void runTest(Method m, Object[] args, int warmup, int nullMode, boolean[][] equalities) throws Exception { Class[] parameterTypes = m.getParameterTypes(); int parameterCount = parameterTypes.length; // Nullness mode for first argument @@ -1397,7 +1460,7 @@ if (args[i] != null && !parameterTypes[0].isInstance(args[i])) { continue; } - if (args[i] == null && parameterTypes[0] == MyValue.class.asValueType()) { + if (args[i] == null && parameterTypes[0] == MyValue1.class.asValueType()) { continue; } if (parameterCount == 1) { @@ -1407,7 +1470,7 @@ boolean expected = isNegated(m) ? (i != 0) : (i == 0); for (int run = 0; run < warmup; ++run) { Boolean result = (Boolean)m.invoke(this, args[i]); - if (result != expected) { + if (result != expected && WHITE_BOX.isMethodCompiled(m, false)) { System.out.println(" = " + result); throw new RuntimeException("Test failed: should return " + expected); } @@ -1419,17 +1482,17 @@ if (args[j] != null && !parameterTypes[1].isInstance(args[j])) { continue; } - if (args[j] == null && parameterTypes[1] == MyValue.class.asValueType()) { + if (args[j] == null && parameterTypes[1] == MyValue1.class.asValueType()) { continue; } System.out.print("Testing " + m.getName() + "(" + args[i] + ", " + args[j] + ")"); // Avoid acmp in the computation of the expected result! - boolean equal = (i == j) && (i != 3); + boolean equal = equalities[i][j]; equal = isNegated(m) ? !equal : equal; boolean expected = alwaysTrue(m) || ((i == 0 || j == 0) && trueIfNull(m)) || (!alwaysFalse(m) && equal && !(i == 0 && falseIfNull(m))); for (int run = 0; run < warmup; ++run) { Boolean result = (Boolean)m.invoke(this, args[i], args[j]); - if (result != expected) { + if (result != expected && WHITE_BOX.isMethodCompiled(m, false) && warmup == 1) { System.out.println(" = " + result); throw new RuntimeException("Test failed: should return " + expected); } @@ -1442,24 +1505,36 @@ public void run(int nullMode) throws Exception { // Prepare test arguments - Object[] args = new Object[6]; - args[0] = null; - args[1] = new Object(); - args[2] = new MyObject(); - args[3] = MyValue.createDefault(); - args[4] = new Object[10]; - args[5] = new MyObject[10]; - + Object[] args = { null, + new Object(), + new MyObject(), + MyValue1.setX(MyValue1.createDefault(), 42), + new Object[10], + new MyObject[10], + MyValue1.setX(MyValue1.createDefault(), 0x42), + MyValue1.setX(MyValue1.createDefault(), 42), + MyValue2.setX(MyValue2.createDefault(), 42), }; + + boolean[][] equalities = { { true, false, false, false, false, false, false, false, false }, + { false, true, false, false, false, false, false, false, false }, + { false, false, true, false, false, false, false, false, false }, + { false, false, false, ACmpOnValues == 3,false, false, false, ACmpOnValues == 3, false }, + { false, false, false, false, true, false, false, false, false }, + { false, false, false, false, false, true, false, false, false }, + { false, false, false, false, false, false, ACmpOnValues == 3, false, false }, + { false, false, false, ACmpOnValues == 3,false, false, false, ACmpOnValues == 3, false }, + { false, false, false, false, false, false, false, false, ACmpOnValues == 3 } }; + // Run tests for (Method m : getClass().getMethods()) { if (m.getName().startsWith("test")) { // Do some warmup runs - runTest(m, args, 1000, nullMode); + runTest(m, args, 1000, nullMode, equalities); // Make sure method is compiled WHITE_BOX.enqueueMethodForCompilation(m, COMP_LEVEL_FULL_OPTIMIZATION); Asserts.assertTrue(WHITE_BOX.isMethodCompiled(m, false), m + " not compiled"); // Run again to verify correctness of compiled code - runTest(m, args, 1, nullMode); + runTest(m, args, 1, nullMode, equalities); } } @@ -1475,8 +1550,8 @@ Asserts.assertTrue(cmpAlwaysUnEqual4(args[3])); int idx = i % args.length; - Asserts.assertEQ(cmpSometimesEqual1(args[idx]), idx != 3); - Asserts.assertNE(cmpSometimesEqual2(args[idx]), idx != 3); + Asserts.assertEQ(cmpSometimesEqual1(args[idx]), args[idx] == null || !args[idx].getClass().isValue()); + Asserts.assertNE(cmpSometimesEqual2(args[idx]), args[idx] == null || !args[idx].getClass().isValue()); } }