--- old/src/hotspot/cpu/x86/templateTable_x86.cpp 2018-02-22 16:36:15.820572237 +0100 +++ new/src/hotspot/cpu/x86/templateTable_x86.cpp 2018-02-22 16:36:15.548573999 +0100 @@ -2442,8 +2442,27 @@ void TemplateTable::if_acmp(Condition cc) { transition(atos, vtos); // assume branch is more often taken than not (loops use backward branches) - Label not_taken; + Label not_taken, is_null; __ pop_ptr(rdx); + + if (UseNewAcmp) { + // TODO what about interpreter buffered values? + const int mask = Universe::oop_metadata_odd_mask(); + __ testptr(rdx, rdx); + __ jcc(Assembler::zero, is_null); + __ movl(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ andptr(rbx, mask); + // Check if a shift is required for perturbation to affect aligned bits + if (mask == KlassPtrEvenOddMask && ObjectAlignmentInBytes <= KlassAlignmentInBytes) { + assert((mask >> LogKlassAlignmentInBytes) == 1, "invalid shift"); + __ shrptr(rbx, LogKlassAlignmentInBytes); + } else { + assert(mask < ObjectAlignmentInBytes, "invalid mask"); + } + __ orptr(rdx, rbx); + __ bind(is_null); + } + __ cmpoop(rdx, rax); __ jcc(j_not(cc), not_taken); branch(false, false); --- old/src/hotspot/cpu/x86/x86_64.ad 2018-02-22 16:36:16.668566742 +0100 +++ new/src/hotspot/cpu/x86/x86_64.ad 2018-02-22 16:36:16.296569153 +0100 @@ -6436,6 +6436,19 @@ ins_pipe(ialu_reg_reg); // XXX %} +instruct castN2X(rRegL dst, rRegN src) +%{ + match(Set dst (CastP2X src)); + + format %{ "movq $dst, $src\t# ptr -> long" %} + ins_encode %{ + if ($dst$$reg != $src$$reg) { + __ movptr($dst$$Register, $src$$Register); + } + %} + ins_pipe(ialu_reg_reg); // XXX +%} + instruct castP2X(rRegL dst, rRegP src) %{ match(Set dst (CastP2X src)); --- old/src/hotspot/share/ci/ciKlass.hpp 2018-02-22 16:36:17.292562698 +0100 +++ new/src/hotspot/share/ci/ciKlass.hpp 2018-02-22 16:36:17.028564409 +0100 @@ -129,6 +129,10 @@ void print_name_on(outputStream* st); const char* external_name() const; + + bool is_value_based() const { + return get_Klass()->is_value_based(); + } }; #endif // SHARE_VM_CI_CIKLASS_HPP --- old/src/hotspot/share/memory/universe.cpp 2018-02-22 16:36:17.864558992 +0100 +++ new/src/hotspot/share/memory/universe.cpp 2018-02-22 16:36:17.584560806 +0100 @@ -167,7 +167,7 @@ NarrowPtrStruct Universe::_narrow_klass = { NULL, 0, true }; address Universe::_narrow_ptrs_base; -int Universe::_oop_metadata_odd_mask = 0; +int Universe::_oop_metadata_odd_mask = KlassPtrEvenOddMask; void Universe::basic_type_classes_do(void f(Klass*)) { f(boolArrayKlassObj()); --- old/src/hotspot/share/memory/universe.hpp 2018-02-22 16:36:18.552554534 +0100 +++ new/src/hotspot/share/memory/universe.hpp 2018-02-22 16:36:18.204556789 +0100 @@ -444,7 +444,9 @@ static void set_narrow_klass_shift(int shift) { assert(shift == 0 || shift == LogKlassAlignmentInBytes, "invalid shift for klass ptrs"); _narrow_klass._shift = shift; - _oop_metadata_odd_mask = (shift) ? 1 : KlassPtrEvenOddMask; + if (shift == LogKlassAlignmentInBytes) { + _oop_metadata_odd_mask = 1; + } } static int oop_metadata_odd_mask() { return _oop_metadata_odd_mask; } --- old/src/hotspot/share/oops/klass.cpp 2018-02-22 16:36:19.600547742 +0100 +++ new/src/hotspot/share/oops/klass.cpp 2018-02-22 16:36:19.104550956 +0100 @@ -177,9 +177,9 @@ if (is_value ^ (((addr & KlassPtrEvenOddMask) >> LogKlassAlignmentInBytes) != 0)) { addr += (1 << LogKlassAlignmentInBytes); } - assert(is_aligned(addr, (1 << LogKlassAlignmentInBytes)), "Klass base alignment incorrect"); - assert(is_value || ((addr & KlassPtrEvenOddMask) == 0), "Klass even alignment incorrect"); - assert((!is_value) || ((addr & KlassPtrEvenOddMask) != 0), "Klass odd alignment incorrect"); + assert(is_aligned(addr, (1 << LogKlassAlignmentInBytes)), "Klass base alignment incorrect"); + assert( is_value || ((addr & KlassPtrEvenOddMask) == 0), "Klass even alignment incorrect"); + assert(!is_value || ((addr & KlassPtrEvenOddMask) != 0), "Klass odd alignment incorrect"); return (void*) addr; } --- old/src/hotspot/share/oops/klass.inline.hpp 2018-02-22 16:36:20.436542325 +0100 +++ new/src/hotspot/share/oops/klass.inline.hpp 2018-02-22 16:36:20.096544528 +0100 @@ -74,6 +74,7 @@ inline bool Klass::decode_ptr_is_value_based(narrowKlass v) { return (v & Universe::oop_metadata_odd_mask()) != 0; } + inline bool Klass::ptr_is_value_based(Klass* v) { return ((uintptr_t)v & Universe::oop_metadata_odd_mask()) != 0; } --- old/src/hotspot/share/opto/castnode.cpp 2018-02-22 16:36:21.184537478 +0100 +++ new/src/hotspot/share/opto/castnode.cpp 2018-02-22 16:36:20.840539707 +0100 @@ -462,6 +462,23 @@ uintptr_t bits = (uintptr_t) t->is_rawptr()->get_con(); return TypeX::make(bits); } + + PhaseIterGVN* igvn = phase->is_IterGVN(); + if (igvn != NULL && (t->is_zero_type() || !TypePtr::NULL_PTR->higher_equal(t))) { + for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) { + Node* u = fast_out(i); + if (u->Opcode() == Op_OrL) { + for (DUIterator_Fast jmax, j = u->fast_outs(jmax); j < jmax; j++) { + Node* cmp = u->fast_out(j); + if (cmp->Opcode() == Op_CmpL) { + // Give CmpL a chance to get optimized + igvn->_worklist.push(cmp); + } + } + } + } + } + return CastP2XNode::bottom_type(); } --- old/src/hotspot/share/opto/compile.cpp 2018-02-22 16:36:21.948532527 +0100 +++ new/src/hotspot/share/opto/compile.cpp 2018-02-22 16:36:21.576534938 +0100 @@ -4507,6 +4507,61 @@ } } +Node* Compile::load_is_value_bit(PhaseGVN* phase, Node* oop) { + // Load the klass pointer and check if it's odd, i.e., if it defines a value type + // is_value = (klass & oop_metadata_odd_mask) >> LogKlassAlignmentInBytes + Node* k_adr = phase->transform(new AddPNode(oop, oop, phase->MakeConX(oopDesc::klass_offset_in_bytes()))); + Node* klass = NULL; + if (UseCompressedClassPointers) { + klass = phase->transform(new LoadNKlassNode(NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT->make_narrowklass(), MemNode::unordered)); + } else { + klass = phase->transform(new LoadKlassNode(NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT, MemNode::unordered)); + } + const int mask = Universe::oop_metadata_odd_mask(); + Node* is_value = phase->transform(new CastP2XNode(NULL, klass)); + is_value = phase->transform(new AndXNode(is_value, phase->MakeConX(mask))); + // Check if a shift is required for perturbation to affect aligned bits of oop + if (mask == KlassPtrEvenOddMask && ObjectAlignmentInBytes <= KlassAlignmentInBytes) { + assert((mask >> LogKlassAlignmentInBytes) == 1, "invalid shift"); + is_value = phase->transform(new URShiftXNode(is_value, phase->intcon(LogKlassAlignmentInBytes))); + } else { + assert(mask < ObjectAlignmentInBytes, "invalid mask"); + } + return is_value; +} + +Node* Compile::optimize_acmp(PhaseGVN* phase, Node* a, Node* b) { + const TypeInstPtr* ta = phase->type(a)->isa_instptr(); + const TypeInstPtr* tb = phase->type(b)->isa_instptr(); + if (!UseNewAcmp || phase->type(a)->is_zero_type() || phase->type(b)->is_zero_type()) { + // Use old acmp if new acmp is disabled or degraded to a null check + if (Verbose && phase->is_IterGVN()) { tty->print_cr("\n# NULL CHECK"); } + return new CmpPNode(a, b); + } else if ((ta != NULL && ta->is_value_based()) || (tb != NULL && tb->is_value_based())) { + // We statically know that one operand is a value. Therefore, + // new acmp will only return true if both operands are NULL. + if ((ta != NULL && !TypePtr::NULL_PTR->higher_equal(ta)) || + (tb != NULL && !TypePtr::NULL_PTR->higher_equal(tb))) { + // One operand is never NULL, fold to constant false + if (Verbose && !phase->is_IterGVN()) { tty->print_cr("\n# CONSTANT FALSE (parse time)"); } else if(Verbose) { tty->print_cr("\n# CONSTANT FALSE"); } + return new CmpINode(phase->intcon(0), phase->intcon(1)); + } else { + // Check if both operands are null by or'ing the oops + a = phase->transform(new CastP2XNode(NULL, a)); + b = phase->transform(new CastP2XNode(NULL, b)); + a = phase->transform(new OrXNode(a, b)); + if (Verbose && !phase->is_IterGVN()) { tty->print_cr("\n# DOUBLE NULL CHECK (parse time)"); } else if (Verbose) { tty->print_cr("\n# DOUBLE NULL CHECK"); } + return new CmpXNode(a, phase->MakeConX(0)); + } + } else if (ta == NULL || !ta->can_be_value_based() || tb == NULL || !tb->can_be_value_based()) { + // Use old acmp + if (Verbose && phase->is_IterGVN()) { tty->print_cr("\n# OLD ACMP "); } + return new CmpPNode(a, b); + } + // Use new acmp + return NULL; +} + // Auxiliary method to support randomized stressing/fuzzing. // // This method can be called the arbitrary number of times, with current count --- old/src/hotspot/share/opto/compile.hpp 2018-02-22 16:36:22.968525918 +0100 +++ new/src/hotspot/share/opto/compile.hpp 2018-02-22 16:36:22.612528225 +0100 @@ -1331,6 +1331,9 @@ // Convert integer value to a narrowed long type dependent on ctrl (for example, a range check) static Node* constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl); + Node* load_is_value_bit(PhaseGVN* phase, Node* oop); + Node* optimize_acmp(PhaseGVN* phase, Node* a, Node* b); + // Auxiliary method for randomized fuzzing/stressing static bool randomized_select(int count); --- old/src/hotspot/share/opto/escape.cpp 2018-02-22 16:36:23.620521693 +0100 +++ new/src/hotspot/share/opto/escape.cpp 2018-02-22 16:36:23.336523533 +0100 @@ -37,6 +37,7 @@ #include "opto/phaseX.hpp" #include "opto/movenode.hpp" #include "opto/rootnode.hpp" +#include "opto/subnode.hpp" ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) : _nodes(C->comp_arena(), C->unique(), C->unique(), NULL), @@ -160,7 +161,8 @@ // scalar replaceable objects in split_unique_types(). _mergemem_worklist.append(n->as_MergeMem()); } else if (OptimizePtrCompare && n->is_Cmp() && - (n->Opcode() == Op_CmpP || n->Opcode() == Op_CmpN)) { + ((n->Opcode() == Op_CmpP && !(((CmpPNode*)n)->has_perturbed_operand() != NULL)) || + n->Opcode() == Op_CmpN)) { // Collect compare pointers nodes. ptr_cmp_worklist.append(n); } else if (n->is_MemBarStoreStore()) { --- old/src/hotspot/share/opto/graphKit.cpp 2018-02-22 16:36:24.100518582 +0100 +++ new/src/hotspot/share/opto/graphKit.cpp 2018-02-22 16:36:23.880520008 +0100 @@ -38,6 +38,7 @@ #include "opto/intrinsicnode.hpp" #include "opto/locknode.hpp" #include "opto/machnode.hpp" +#include "opto/narrowptrnode.hpp" #include "opto/opaquenode.hpp" #include "opto/parse.hpp" #include "opto/rootnode.hpp" @@ -4534,3 +4535,44 @@ // assumption of CCP analysis. return _gvn.transform(new CastPPNode(ary, ary_type->cast_to_stable(true))); } + +Node* GraphKit::acmp(Node* a, Node* b) { + // 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. + Node* cmp = C->optimize_acmp(&_gvn, a, b); + if (cmp != NULL) { + return cmp; // Use optimized/old acmp + } + + Node* region = new RegionNode(2); + Node* is_value = new PhiNode(region, TypeX_X); + + // Null check operand before loading the is_value bit + if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(b))) { + // Operand 'b' is never null, swap operands to avoid null check + swap(a, b); + } + // TODO we need to speculate on 'a' being non-null / always null + Node* null_ctl = top(); + Node* not_null_a = null_check_oop(a, &null_ctl); + assert(!stopped(), "operand is always null"); + if (null_ctl != top()) { + region->add_req(null_ctl); + is_value->add_req(_gvn.MakeConX(0)); + if (Verbose) tty->print_cr("\n# NEW (parse time)"); + } else { + if (Verbose) tty->print_cr("\n# NEW WITHOUT NULL (parse time)"); + } + + Node* value_bit = C->load_is_value_bit(&_gvn, not_null_a); + region->init_req(1, control()); + is_value->set_req(1, value_bit); + + set_control(_gvn.transform(region)); + is_value = _gvn.transform(is_value); + + // Perturbe oop if operand is a value type to make comparison fail + Node* pert = _gvn.transform(new AddPNode(a, a, is_value)); + return new CmpPNode(pert, b); +} --- old/src/hotspot/share/opto/graphKit.hpp 2018-02-22 16:36:24.544515705 +0100 +++ new/src/hotspot/share/opto/graphKit.hpp 2018-02-22 16:36:24.348516975 +0100 @@ -919,6 +919,8 @@ // Produce new array node of stable type Node* cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type); + + Node* acmp(Node* a, Node* b); }; // Helper class to support building of control flow branches. Upon --- old/src/hotspot/share/opto/macro.cpp 2018-02-22 16:36:24.944513113 +0100 +++ new/src/hotspot/share/opto/macro.cpp 2018-02-22 16:36:24.748514383 +0100 @@ -767,6 +767,13 @@ DEBUG_ONLY(disq_node = use;) } can_eliminate = false; + } else { + assert(use->Opcode() == Op_CastP2X, "should be"); + if (use->has_out_with(Op_OrL)) { + // Fixme + // This is not a card mark! + can_eliminate = false; + } } } } --- old/src/hotspot/share/opto/parse2.cpp 2018-02-22 16:36:25.348510495 +0100 +++ new/src/hotspot/share/opto/parse2.cpp 2018-02-22 16:36:25.156511740 +0100 @@ -2302,7 +2302,7 @@ maybe_add_safepoint(iter().get_dest()); a = pop(); b = pop(); - c = _gvn.transform( new CmpPNode(b, a) ); + c = _gvn.transform(acmp(a, b)); c = optimize_cmp_with_klass(c); do_if(btest, c); break; --- old/src/hotspot/share/opto/subnode.cpp 2018-02-22 16:36:25.756507852 +0100 +++ new/src/hotspot/share/opto/subnode.cpp 2018-02-22 16:36:25.560509122 +0100 @@ -715,6 +715,27 @@ return NULL; // No change } +//------------------------------Ideal------------------------------------------ +Node* CmpLNode::Ideal(PhaseGVN* phase, bool can_reshape) { + if (in(1)->Opcode() == Op_OrL && in(1)->in(1)->Opcode() == Op_CastP2X && in(1)->in(2)->Opcode() == Op_CastP2X) { + Node* a = in(1)->in(1)->in(1); + Node* b = in(1)->in(2)->in(1); + const Type* ta = phase->type(a); + const Type* tb = phase->type(b); + if (ta->is_zero_type() || tb->is_zero_type()) { + if (Verbose) tty->print_cr("\n# NULL CHECK (CmpLNode::Ideal)"); + return new CmpPNode(a, b); + } else if (!TypePtr::NULL_PTR->higher_equal(ta) || !TypePtr::NULL_PTR->higher_equal(tb)) { + // One operand is never NULL, emit constant false + if (Verbose) tty->print_cr("\n# CONSTANT FALSE (CmpLNode::Ideal)"); + set_req(1, phase->longcon(0)); + set_req(2, phase->longcon(1)); + return this; + } + } + return NULL; +} + //============================================================================= // Simplify a CmpL (compare 2 longs ) node, based on local information. @@ -932,6 +953,35 @@ // checking to see an unknown klass subtypes a known klass with no subtypes; // this only happens on an exact match. We can shorten this test by 1 load. Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { + Node* pert = has_perturbed_operand(); + if (pert != NULL) { + // Optimize new acmp + Node* a = pert->in(AddPNode::Base); // unperturbed a + Node* b = in(2); + Node* cmp = phase->C->optimize_acmp(phase, a, b); + if (cmp != NULL) { + return cmp; + } + if ( TypePtr::NULL_PTR->higher_equal(phase->type(a)) && + !TypePtr::NULL_PTR->higher_equal(phase->type(b))) { + // Operand 'b' is never null, swap operands to avoid null check + Node* is_value = phase->C->load_is_value_bit(phase, b); + set_req(1, phase->transform(new AddPNode(b, b, is_value))); + set_req(2, a); + return this; + } + } else { + // Optimize old acmp with value type operands + const TypeInstPtr* ta = phase->type(in(1))->isa_instptr(); + const TypeInstPtr* tb = phase->type(in(2))->isa_instptr(); + if (((ta != NULL && ta->is_loaded() && ta->is_value_based()) || (tb != NULL && tb->is_loaded() && tb->is_value_based())) && + (!TypePtr::NULL_PTR->higher_equal(phase->type(in(1))) || !TypePtr::NULL_PTR->higher_equal(phase->type(in(2))))) { + // One operand is a value type and one operand is never null, fold to constant false + if (Verbose) tty->print_cr("\n# CONSTANT FALSE"); + return new CmpINode(phase->intcon(0), phase->intcon(1)); + } + } + // Normalize comparisons between Java mirrors into comparisons of the low- // level klass, where a dependent load could be shortened. // @@ -1032,6 +1082,22 @@ return this; } +// Checks if one operand is perturbed and returns it +Node* CmpPNode::has_perturbed_operand() const { + // We always perturbe the first operand + AddPNode* addP = in(1)->isa_AddP(); + if (addP != NULL) { + Node* base = addP->in(AddPNode::Base); + if (base->is_top()) { + // RawPtr comparison + return NULL; + } + assert(UseNewAcmp, "unexpected perturbed oop"); + return in(1); + } + return NULL; +} + //============================================================================= //------------------------------sub-------------------------------------------- // Simplify an CmpN (compare 2 pointers) node, based on local information. --- old/src/hotspot/share/opto/subnode.hpp 2018-02-22 16:36:26.184505078 +0100 +++ new/src/hotspot/share/opto/subnode.hpp 2018-02-22 16:36:25.984506374 +0100 @@ -177,6 +177,7 @@ virtual int Opcode() const; virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); virtual const Type *sub( const Type *, const Type * ) const; + Node* has_perturbed_operand() const; }; //------------------------------CmpNNode-------------------------------------- @@ -195,6 +196,7 @@ public: CmpLNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {} virtual int Opcode() const; + virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); virtual const Type *sub( const Type *, const Type * ) const; }; --- old/src/hotspot/share/opto/type.cpp 2018-02-22 16:36:26.580502512 +0100 +++ new/src/hotspot/share/opto/type.cpp 2018-02-22 16:36:26.384503782 +0100 @@ -3950,6 +3950,14 @@ return hash; } +const bool TypeInstPtr::is_value_based() const { + return klass()->is_value_based(); +} + +const bool TypeInstPtr::can_be_value_based() const { + return !is_zero_type() && (!klass()->is_loaded() || klass()->is_interface() || klass()->is_java_lang_Object() || klass()->is_value_based()); +} + //------------------------------dump2------------------------------------------ // Dump oop Type #ifndef PRODUCT --- old/src/hotspot/share/opto/type.hpp 2018-02-22 16:36:26.992499842 +0100 +++ new/src/hotspot/share/opto/type.hpp 2018-02-22 16:36:26.800501086 +0100 @@ -1121,6 +1121,9 @@ virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const; virtual const Type *xdual() const; // Compute dual right now. + const bool is_value_based() const; + const bool can_be_value_based() const; + // Convenience common pre-built types. static const TypeInstPtr *NOTNULL; static const TypeInstPtr *BOTTOM; --- old/src/hotspot/share/runtime/globals.hpp 2018-02-22 16:36:27.392497250 +0100 +++ new/src/hotspot/share/runtime/globals.hpp 2018-02-22 16:36:27.200498494 +0100 @@ -4096,7 +4096,11 @@ product(ccstrlist, ValueBasedClasses, \ NULL, \ "A comma separated list of classes whom should be treated as " \ - "value-based") + "value-based") \ + \ + product(bool, UseNewAcmp, false, \ + "Enable L-World behavior of the acmp bytecode.") \ + --- /dev/null 2018-02-22 08:13:42.785713644 +0100 +++ new/./Test.java 2018-02-22 16:36:27.612495825 +0100 @@ -0,0 +1,1262 @@ + +// Run with -XX:+UseNewAcmp -XX:ValueBasedClasses="MyValue" + +import java.lang.invoke.*; +import java.lang.reflect.Method; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +interface MyInterface { + +} + +class MyValue implements MyInterface { + int x; +} + +class MyObject implements MyInterface { + int x; +} + +public class Test { + + public Object f1 = null; + + public void myMethod() { + + } + +/* + public boolean testEq01_1(Object u1, Object u2) { + if (u1 == null) { + return false; + } + if (u2 == u1) { + return true; + } + //System.gc(); + myMethod(); + if (f1 == u1) { + return true; + } + return false; + } +*/ + + public boolean testEq01_1(Object u1, Object u2) { + return get(u1) == u2; // new acmp + } + + public boolean testEq01_2(Object u1, Object u2) { + return u1 == get(u2); // new acmp + } + + public boolean testEq01_3(Object u1, Object u2) { + return get(u1) == get(u2); // new acmp + } + + public boolean testEq01_4(Object u1, Object u2) { + return getNotNull(u1) == u2; // new acmp without null check + } + + public boolean testEq01_5(Object u1, Object u2) { + return u1 == getNotNull(u2); // new acmp without null check + } + + public boolean testEq01_6(Object u1, Object u2) { + return getNotNull(u1) == getNotNull(u2); // new acmp without null check + } + + public boolean testEq02_1(MyValue v1, MyValue v2) { + return get(v1) == v2; // only true if both null + } + + public boolean testEq02_2(MyValue v1, MyValue v2) { + return v1 == get(v2); // only true if both null + } + + public boolean testEq02_3(MyValue v1, MyValue v2) { + return get(v1) == get(v2); // only true if both null + } + + public boolean testEq03_1(MyValue v, Object u) { + return get(v) == u; // only true if both null + } + + public boolean testEq03_2(MyValue v, Object u) { + return v == get(u); // only true if both null + } + + public boolean testEq03_3(MyValue v, Object u) { + return get(v) == get(u); // only true if both null + } + + public boolean testEq04_1(Object u, MyValue v) { + return get(u) == v; // only true if both null + } + + public boolean testEq04_2(Object u, MyValue v) { + return u == get(v); // only true if both null + } + + public boolean testEq04_3(Object u, MyValue v) { + return get(u) == get(v); // only true if both null + } + + public boolean testEq05_1(MyObject o, MyValue v) { + return get(o) == v; // only true if both null + } + + public boolean testEq05_2(MyObject o, MyValue v) { + return o == get(v); // only true if both null + } + + public boolean testEq05_3(MyObject o, MyValue v) { + return get(o) == get(v); // only true if both null + } + + public boolean testEq06_1(MyValue v, MyObject o) { + return get(v) == o; // only true if both null + } + + public boolean testEq06_2(MyValue v, MyObject o) { + return v == get(o); // only true if both null + } + + public boolean testEq06_3(MyValue v, MyObject o) { + return get(v) == get(o); // only true if both null + } + + public boolean testEq07_1(MyValue v1, MyValue v2) { + return getNotNull(v1) == v2; // false + } + + public boolean testEq07_2(MyValue v1, MyValue v2) { + return v1 == getNotNull(v2); // false + } + + public boolean testEq07_3(MyValue v1, MyValue v2) { + return getNotNull(v1) == getNotNull(v2); // false + } + + public boolean testEq08_1(MyValue v, Object u) { + return getNotNull(v) == u; // false + } + + public boolean testEq08_2(MyValue v, Object u) { + return v == getNotNull(u); // false + } + + public boolean testEq08_3(MyValue v, Object u) { + return getNotNull(v) == getNotNull(u); // false + } + + public boolean testEq09_1(Object u, MyValue v) { + return getNotNull(u) == v; // false + } + + public boolean testEq09_2(Object u, MyValue v) { + return u == getNotNull(v); // false + } + + public boolean testEq09_3(Object u, MyValue v) { + return getNotNull(u) == getNotNull(v); // false + } + + public boolean testEq10_1(MyObject o, MyValue v) { + return getNotNull(o) == v; // false + } + + public boolean testEq10_2(MyObject o, MyValue v) { + return o == getNotNull(v); // false + } + + public boolean testEq10_3(MyObject o, MyValue v) { + return getNotNull(o) == getNotNull(v); // false + } + + public boolean testEq11_1(MyValue v, MyObject o) { + return getNotNull(v) == o; // false + } + + public boolean testEq11_2(MyValue v, MyObject o) { + return v == getNotNull(o); // false + } + + public boolean testEq11_3(MyValue v, MyObject o) { + return getNotNull(v) == getNotNull(o); // false + } + + public boolean testEq12_1(MyObject o1, MyObject o2) { + return get(o1) == o2; // old acmp + } + + public boolean testEq12_2(MyObject o1, MyObject o2) { + return o1 == get(o2); // old acmp + } + + public boolean testEq12_3(MyObject o1, MyObject o2) { + return get(o1) == get(o2); // old acmp + } + + public boolean testEq13_1(Object u, MyObject o) { + return get(u) == o; // old acmp + } + + public boolean testEq13_2(Object u, MyObject o) { + return u == get(o); // old acmp + } + + public boolean testEq13_3(Object u, MyObject o) { + return get(u) == get(o); // old acmp + } + + public boolean testEq14_1(MyObject o, Object u) { + return get(o) == u; // old acmp + } + + public boolean testEq14_2(MyObject o, Object u) { + return o == get(u); // old acmp + } + + public boolean testEq14_3(MyObject o, Object u) { + return get(o) == get(u); // old acmp + } + + public boolean testEq15_1(Object[] a, Object u) { + return get(a) == u; // old acmp + } + + public boolean testEq15_2(Object[] a, Object u) { + return a == get(u); // old acmp + } + + public boolean testEq15_3(Object[] a, Object u) { + return get(a) == get(u); // old acmp + } + + public boolean testEq16_1(Object u, Object[] a) { + return get(u) == a; // old acmp + } + + public boolean testEq16_2(Object u, Object[] a) { + return u == get(a); // old acmp + } + + public boolean testEq16_3(Object u, Object[] a) { + return get(u) == get(a); // old acmp + } + + public boolean testEq17_1(Object[] a, MyValue v) { + return get(a) == v; // only true if both null + } + + public boolean testEq17_2(Object[] a, MyValue v) { + return a == get(v); // only true if both null + } + + public boolean testEq17_3(Object[] a, MyValue v) { + return get(a) == get(v); // only true if both null + } + + public boolean testEq18_1(MyValue v, Object[] a) { + return get(v) == a; // only true if both null + } + + public boolean testEq18_2(MyValue v, Object[] a) { + return v == get(a); // only true if both null + } + + public boolean testEq18_3(MyValue v, Object[] a) { + return get(v) == get(a); // only true if both null + } + + public boolean testEq19_1(Object[] a, MyValue v) { + return getNotNull(a) == v; // false + } + + public boolean testEq19_2(Object[] a, MyValue v) { + return a == getNotNull(v); // false + } + + public boolean testEq19_3(Object[] a, MyValue v) { + return getNotNull(a) == getNotNull(v); // false + } + + public boolean testEq20_1(MyValue v, Object[] a) { + return getNotNull(v) == a; // false + } + + public boolean testEq20_2(MyValue v, Object[] a) { + return v == getNotNull(a); // false + } + + public boolean testEq20_3(MyValue v, Object[] a) { + return getNotNull(v) == getNotNull(a); // false + } + + public boolean testEq21_1(MyInterface u1, MyInterface u2) { + return get(u1) == u2; // new acmp + } + + public boolean testEq21_2(MyInterface u1, MyInterface u2) { + return u1 == get(u2); // new acmp + } + + public boolean testEq21_3(MyInterface u1, MyInterface u2) { + return get(u1) == get(u2); // new acmp + } + + public boolean testEq21_4(MyInterface u1, MyInterface u2) { + return getNotNull(u1) == u2; // new acmp without null check + } + + public boolean testEq21_5(MyInterface u1, MyInterface u2) { + return u1 == getNotNull(u2); // new acmp without null check + } + + public boolean testEq21_6(MyInterface u1, MyInterface u2) { + return getNotNull(u1) == getNotNull(u2); // new acmp without null check + } + + public boolean testEq22_1(MyValue v, MyInterface u) { + return get(v) == u; // only true if both null + } + + public boolean testEq22_2(MyValue v, MyInterface u) { + return v == get(u); // only true if both null + } + + public boolean testEq22_3(MyValue v, MyInterface u) { + return get(v) == get(u); // only true if both null + } + + public boolean testEq23_1(MyInterface u, MyValue v) { + return get(u) == v; // only true if both null + } + + public boolean testEq23_2(MyInterface u, MyValue v) { + return u == get(v); // only true if both null + } + + public boolean testEq23_3(MyInterface u, MyValue v) { + return get(u) == get(v); // only true if both null + } + + public boolean testEq24_1(MyValue v, MyInterface u) { + return getNotNull(v) == u; // false + } + + public boolean testEq24_2(MyValue v, MyInterface u) { + return v == getNotNull(u); // false + } + + public boolean testEq24_3(MyValue v, MyInterface u) { + return getNotNull(v) == getNotNull(u); // false + } + + public boolean testEq25_1(MyInterface u, MyValue v) { + return getNotNull(u) == v; // false + } + + public boolean testEq25_2(MyInterface u, MyValue v) { + return u == getNotNull(v); // false + } + + public boolean testEq25_3(MyInterface u, MyValue v) { + return getNotNull(u) == getNotNull(v); // false + } + + public boolean testEq26_1(MyInterface u, MyObject o) { + return get(u) == o; // old acmp + } + + public boolean testEq26_2(MyInterface u, MyObject o) { + return u == get(o); // old acmp + } + + public boolean testEq26_3(MyInterface u, MyObject o) { + return get(u) == get(o); // old acmp + } + + public boolean testEq27_1(MyObject o, MyInterface u) { + return get(o) == u; // old acmp + } + + public boolean testEq27_2(MyObject o, MyInterface u) { + return o == get(u); // old acmp + } + + public boolean testEq27_3(MyObject o, MyInterface u) { + return get(o) == get(u); // old acmp + } + + public boolean testEq28_1(MyInterface[] a, MyInterface u) { + return get(a) == u; // old acmp + } + + public boolean testEq28_2(MyInterface[] a, MyInterface u) { + return a == get(u); // old acmp + } + + public boolean testEq28_3(MyInterface[] a, MyInterface u) { + return get(a) == get(u); // old acmp + } + + public boolean testEq29_1(MyInterface u, MyInterface[] a) { + return get(u) == a; // old acmp + } + + public boolean testEq29_2(MyInterface u, MyInterface[] a) { + return u == get(a); // old acmp + } + + public boolean testEq29_3(MyInterface u, MyInterface[] a) { + return get(u) == get(a); // old acmp + } + + public boolean testEq30_1(MyInterface[] a, MyValue v) { + return get(a) == v; // only true if both null + } + + public boolean testEq30_2(MyInterface[] a, MyValue v) { + return a == get(v); // only true if both null + } + + public boolean testEq30_3(MyInterface[] a, MyValue v) { + return get(a) == get(v); // only true if both null + } + + public boolean testEq31_1(MyValue v, MyInterface[] a) { + return get(v) == a; // only true if both null + } + + public boolean testEq31_2(MyValue v, MyInterface[] a) { + return v == get(a); // only true if both null + } + + public boolean testEq31_3(MyValue v, MyInterface[] a) { + return get(v) == get(a); // only true if both null + } + + public boolean testEq32_1(MyInterface[] a, MyValue v) { + return getNotNull(a) == v; // false + } + + public boolean testEq32_2(MyInterface[] a, MyValue v) { + return a == getNotNull(v); // false + } + + public boolean testEq32_3(MyInterface[] a, MyValue v) { + return getNotNull(a) == getNotNull(v); // false + } + + public boolean testEq33_1(MyValue v, MyInterface[] a) { + return getNotNull(v) == a; // false + } + + public boolean testEq33_2(MyValue v, MyInterface[] a) { + return v == getNotNull(a); // false + } + + public boolean testEq33_3(MyValue v, MyInterface[] a) { + return getNotNull(v) == getNotNull(a); // false + } + + + // Null tests + + public boolean testNull01_1(MyValue v) { + return v == null; // old acmp + } + + public boolean testNull01_2(MyValue v) { + return get(v) == null; // old acmp + } + + public boolean testNull01_3(MyValue v) { + return v == get((Object)null); // old acmp + } + + public boolean testNull01_4(MyValue v) { + return get(v) == get((Object)null); // old acmp + } + + public boolean testNull02_1(MyValue v) { + return null == v; // old acmp + } + + public boolean testNull02_2(MyValue v) { + return get((Object)null) == v; // old acmp + } + + public boolean testNull02_3(MyValue v) { + return null == get(v); // old acmp + } + + public boolean testNull02_4(MyValue v) { + return get((Object)null) == get(v); // old acmp + } + + public boolean testNull03_1(Object u) { + return u == null; // old acmp + } + + public boolean testNull03_2(Object u) { + return get(u) == null; // old acmp + } + + public boolean testNull03_3(Object u) { + return u == get((Object)null); // old acmp + } + + public boolean testNull03_4(Object u) { + return get(u) == get((Object)null); // old acmp + } + + public boolean testNull04_1(Object u) { + return null == u; // old acmp + } + + public boolean testNull04_2(Object u) { + return get((Object)null) == u; // old acmp + } + + public boolean testNull04_3(Object u) { + return null == get(u); // old acmp + } + + public boolean testNull04_4(Object u) { + return get((Object)null) == get(u); // old acmp + } + + public boolean testNull05_1(MyObject o) { + return o == null; // old acmp + } + + public boolean testNull05_2(MyObject o) { + return get(o) == null; // old acmp + } + + public boolean testNull05_3(MyObject o) { + return o == get((Object)null); // old acmp + } + + public boolean testNull05_4(MyObject o) { + return get(o) == get((Object)null); // old acmp + } + + public boolean testNull06_1(MyObject o) { + return null == o; // old acmp + } + + public boolean testNull06_2(MyObject o) { + return get((Object)null) == o; // old acmp + } + + public boolean testNull06_3(MyObject o) { + return null == get(o); // old acmp + } + + public boolean testNull06_4(MyObject o) { + return get((Object)null) == get(o); // old acmp + } + + public boolean testNull07_1(MyInterface u) { + return u == null; // old acmp + } + + public boolean testNull07_2(MyInterface u) { + return get(u) == null; // old acmp + } + + public boolean testNull07_3(MyInterface u) { + return u == get((Object)null); // old acmp + } + + public boolean testNull07_4(MyInterface u) { + return get(u) == get((Object)null); // old acmp + } + + public boolean testNull08_1(MyInterface u) { + return null == u; // old acmp + } + + public boolean testNull08_2(MyInterface u) { + return get((Object)null) == u; // old acmp + } + + public boolean testNull08_3(MyInterface u) { + return null == get(u); // old acmp + } + + public boolean testNull08_4(MyInterface u) { + return get((Object)null) == get(u); // old acmp + } + + // Same tests as above but negated + + public boolean testNotEq01_1(Object u1, Object u2) { + return get(u1) != u2; // new acmp + } + + public boolean testNotEq01_2(Object u1, Object u2) { + return u1 != get(u2); // new acmp + } + + public boolean testNotEq01_3(Object u1, Object u2) { + return get(u1) != get(u2); // new acmp + } + + public boolean testNotEq01_4(Object u1, Object u2) { + return getNotNull(u1) != u2; // new acmp without null check + } + + public boolean testNotEq01_5(Object u1, Object u2) { + return u1 != getNotNull(u2); // new acmp without null check + } + + public boolean testNotEq01_6(Object u1, Object u2) { + return getNotNull(u1) != getNotNull(u2); // new acmp without null check + } + + public boolean testNotEq02_1(MyValue v1, MyValue v2) { + return get(v1) != v2; // only false if both null + } + + public boolean testNotEq02_2(MyValue v1, MyValue v2) { + return v1 != get(v2); // only false if both null + } + + public boolean testNotEq02_3(MyValue v1, MyValue v2) { + return get(v1) != get(v2); // only false if both null + } + + public boolean testNotEq03_1(MyValue v, Object u) { + return get(v) != u; // only false if both null + } + + public boolean testNotEq03_2(MyValue v, Object u) { + return v != get(u); // only false if both null + } + + public boolean testNotEq03_3(MyValue v, Object u) { + return get(v) != get(u); // only false if both null + } + + public boolean testNotEq04_1(Object u, MyValue v) { + return get(u) != v; // only false if both null + } + + public boolean testNotEq04_2(Object u, MyValue v) { + return u != get(v); // only false if both null + } + + public boolean testNotEq04_3(Object u, MyValue v) { + return get(u) != get(v); // only false if both null + } + + public boolean testNotEq05_1(MyObject o, MyValue v) { + return get(o) != v; // only false if both null + } + + public boolean testNotEq05_2(MyObject o, MyValue v) { + return o != get(v); // only false if both null + } + + public boolean testNotEq05_3(MyObject o, MyValue v) { + return get(o) != get(v); // only false if both null + } + + public boolean testNotEq06_1(MyValue v, MyObject o) { + return get(v) != o; // only false if both null + } + + public boolean testNotEq06_2(MyValue v, MyObject o) { + return v != get(o); // only false if both null + } + + public boolean testNotEq06_3(MyValue v, MyObject o) { + return get(v) != get(o); // only false if both null + } + + public boolean testNotEq07_1(MyValue v1, MyValue v2) { + return getNotNull(v1) != v2; // true + } + + public boolean testNotEq07_2(MyValue v1, MyValue v2) { + return v1 != getNotNull(v2); // true + } + + public boolean testNotEq07_3(MyValue v1, MyValue v2) { + return getNotNull(v1) != getNotNull(v2); // true + } + + public boolean testNotEq08_1(MyValue v, Object u) { + return getNotNull(v) != u; // true + } + + public boolean testNotEq08_2(MyValue v, Object u) { + return v != getNotNull(u); // true + } + + public boolean testNotEq08_3(MyValue v, Object u) { + return getNotNull(v) != getNotNull(u); // true + } + + public boolean testNotEq09_1(Object u, MyValue v) { + return getNotNull(u) != v; // true + } + + public boolean testNotEq09_2(Object u, MyValue v) { + return u != getNotNull(v); // true + } + + public boolean testNotEq09_3(Object u, MyValue v) { + return getNotNull(u) != getNotNull(v); // true + } + + public boolean testNotEq10_1(MyObject o, MyValue v) { + return getNotNull(o) != v; // true + } + + public boolean testNotEq10_2(MyObject o, MyValue v) { + return o != getNotNull(v); // true + } + + public boolean testNotEq10_3(MyObject o, MyValue v) { + return getNotNull(o) != getNotNull(v); // true + } + + public boolean testNotEq11_1(MyValue v, MyObject o) { + return getNotNull(v) != o; // true + } + + public boolean testNotEq11_2(MyValue v, MyObject o) { + return v != getNotNull(o); // true + } + + public boolean testNotEq11_3(MyValue v, MyObject o) { + return getNotNull(v) != getNotNull(o); // true + } + + public boolean testNotEq12_1(MyObject o1, MyObject o2) { + return get(o1) != o2; // old acmp + } + + public boolean testNotEq12_2(MyObject o1, MyObject o2) { + return o1 != get(o2); // old acmp + } + + public boolean testNotEq12_3(MyObject o1, MyObject o2) { + return get(o1) != get(o2); // old acmp + } + + public boolean testNotEq13_1(Object u, MyObject o) { + return get(u) != o; // old acmp + } + + public boolean testNotEq13_2(Object u, MyObject o) { + return u != get(o); // old acmp + } + + public boolean testNotEq13_3(Object u, MyObject o) { + return get(u) != get(o); // old acmp + } + + public boolean testNotEq14_1(MyObject o, Object u) { + return get(o) != u; // old acmp + } + + public boolean testNotEq14_2(MyObject o, Object u) { + return o != get(u); // old acmp + } + + public boolean testNotEq14_3(MyObject o, Object u) { + return get(o) != get(u); // old acmp + } + + public boolean testNotEq15_1(Object[] a, Object u) { + return get(a) != u; // old acmp + } + + public boolean testNotEq15_2(Object[] a, Object u) { + return a != get(u); // old acmp + } + + public boolean testNotEq15_3(Object[] a, Object u) { + return get(a) != get(u); // old acmp + } + + public boolean testNotEq16_1(Object u, Object[] a) { + return get(u) != a; // old acmp + } + + public boolean testNotEq16_2(Object u, Object[] a) { + return u != get(a); // old acmp + } + + public boolean testNotEq16_3(Object u, Object[] a) { + return get(u) != get(a); // old acmp + } + + public boolean testNotEq17_1(Object[] a, MyValue v) { + return get(a) != v; // only false if both null + } + + public boolean testNotEq17_2(Object[] a, MyValue v) { + return a != get(v); // only false if both null + } + + public boolean testNotEq17_3(Object[] a, MyValue v) { + return get(a) != get(v); // only false if both null + } + + public boolean testNotEq18_1(MyValue v, Object[] a) { + return get(v) != a; // only false if both null + } + + public boolean testNotEq18_2(MyValue v, Object[] a) { + return v != get(a); // only false if both null + } + + public boolean testNotEq18_3(MyValue v, Object[] a) { + return get(v) != get(a); // only false if both null + } + + public boolean testNotEq19_1(Object[] a, MyValue v) { + return getNotNull(a) != v; // true + } + + public boolean testNotEq19_2(Object[] a, MyValue v) { + return a != getNotNull(v); // true + } + + public boolean testNotEq19_3(Object[] a, MyValue v) { + return getNotNull(a) != getNotNull(v); // true + } + + public boolean testNotEq20_1(MyValue v, Object[] a) { + return getNotNull(v) != a; // true + } + + public boolean testNotEq20_2(MyValue v, Object[] a) { + return v != getNotNull(a); // true + } + + public boolean testNotEq20_3(MyValue v, Object[] a) { + return getNotNull(v) != getNotNull(a); // true + } + + public boolean testNotEq21_1(MyInterface u1, MyInterface u2) { + return get(u1) != u2; // new acmp + } + + public boolean testNotEq21_2(MyInterface u1, MyInterface u2) { + return u1 != get(u2); // new acmp + } + + public boolean testNotEq21_3(MyInterface u1, MyInterface u2) { + return get(u1) != get(u2); // new acmp + } + + public boolean testNotEq21_4(MyInterface u1, MyInterface u2) { + return getNotNull(u1) != u2; // new acmp without null check + } + + public boolean testNotEq21_5(MyInterface u1, MyInterface u2) { + return u1 != getNotNull(u2); // new acmp without null check + } + + public boolean testNotEq21_6(MyInterface u1, MyInterface u2) { + return getNotNull(u1) != getNotNull(u2); // new acmp without null check + } + + public boolean testNotEq22_1(MyValue v, MyInterface u) { + return get(v) != u; // only false if both null + } + + public boolean testNotEq22_2(MyValue v, MyInterface u) { + return v != get(u); // only false if both null + } + + public boolean testNotEq22_3(MyValue v, MyInterface u) { + return get(v) != get(u); // only false if both null + } + + public boolean testNotEq23_1(MyInterface u, MyValue v) { + return get(u) != v; // only false if both null + } + + public boolean testNotEq23_2(MyInterface u, MyValue v) { + return u != get(v); // only false if both null + } + + public boolean testNotEq23_3(MyInterface u, MyValue v) { + return get(u) != get(v); // only false if both null + } + + public boolean testNotEq24_1(MyValue v, MyInterface u) { + return getNotNull(v) != u; // true + } + + public boolean testNotEq24_2(MyValue v, MyInterface u) { + return v != getNotNull(u); // true + } + + public boolean testNotEq24_3(MyValue v, MyInterface u) { + return getNotNull(v) != getNotNull(u); // true + } + + public boolean testNotEq25_1(MyInterface u, MyValue v) { + return getNotNull(u) != v; // true + } + + public boolean testNotEq25_2(MyInterface u, MyValue v) { + return u != getNotNull(v); // true + } + + public boolean testNotEq25_3(MyInterface u, MyValue v) { + return getNotNull(u) != getNotNull(v); // true + } + + public boolean testNotEq26_1(MyInterface u, MyObject o) { + return get(u) != o; // old acmp + } + + public boolean testNotEq26_2(MyInterface u, MyObject o) { + return u != get(o); // old acmp + } + + public boolean testNotEq26_3(MyInterface u, MyObject o) { + return get(u) != get(o); // old acmp + } + + public boolean testNotEq27_1(MyObject o, MyInterface u) { + return get(o) != u; // old acmp + } + + public boolean testNotEq27_2(MyObject o, MyInterface u) { + return o != get(u); // old acmp + } + + public boolean testNotEq27_3(MyObject o, MyInterface u) { + return get(o) != get(u); // old acmp + } + + public boolean testNotEq28_1(MyInterface[] a, MyInterface u) { + return get(a) != u; // old acmp + } + + public boolean testNotEq28_2(MyInterface[] a, MyInterface u) { + return a != get(u); // old acmp + } + + public boolean testNotEq28_3(MyInterface[] a, MyInterface u) { + return get(a) != get(u); // old acmp + } + + public boolean testNotEq29_1(MyInterface u, MyInterface[] a) { + return get(u) != a; // old acmp + } + + public boolean testNotEq29_2(MyInterface u, MyInterface[] a) { + return u != get(a); // old acmp + } + + public boolean testNotEq29_3(MyInterface u, MyInterface[] a) { + return get(u) != get(a); // old acmp + } + + public boolean testNotEq30_1(MyInterface[] a, MyValue v) { + return get(a) != v; // only false if both null + } + + public boolean testNotEq30_2(MyInterface[] a, MyValue v) { + return a != get(v); // only false if both null + } + + public boolean testNotEq30_3(MyInterface[] a, MyValue v) { + return get(a) != get(v); // only false if both null + } + + public boolean testNotEq31_1(MyValue v, MyInterface[] a) { + return get(v) != a; // only false if both null + } + + public boolean testNotEq31_2(MyValue v, MyInterface[] a) { + return v != get(a); // only false if both null + } + + public boolean testNotEq31_3(MyValue v, MyInterface[] a) { + return get(v) != get(a); // only false if both null + } + + public boolean testNotEq32_1(MyInterface[] a, MyValue v) { + return getNotNull(a) != v; // true + } + + public boolean testNotEq32_2(MyInterface[] a, MyValue v) { + return a != getNotNull(v); // true + } + + public boolean testNotEq32_3(MyInterface[] a, MyValue v) { + return getNotNull(a) != getNotNull(v); // true + } + + public boolean testNotEq33_1(MyValue v, MyInterface[] a) { + return getNotNull(v) != a; // true + } + + public boolean testNotEq33_2(MyValue v, MyInterface[] a) { + return v != getNotNull(a); // true + } + + public boolean testNotEq33_3(MyValue v, MyInterface[] a) { + return getNotNull(v) != getNotNull(a); // true + } + + // Null tests + + public boolean testNotNull01_1(MyValue v) { + return v != null; // old acmp + } + + public boolean testNotNull01_2(MyValue v) { + return get(v) != null; // old acmp + } + + public boolean testNotNull01_3(MyValue v) { + return v != get((Object)null); // old acmp + } + + public boolean testNotNull01_4(MyValue v) { + return get(v) != get((Object)null); // old acmp + } + + public boolean testNotNull02_1(MyValue v) { + return null != v; // old acmp + } + + public boolean testNotNull02_2(MyValue v) { + return get((Object)null) != v; // old acmp + } + + public boolean testNotNull02_3(MyValue v) { + return null != get(v); // old acmp + } + + public boolean testNotNull02_4(MyValue v) { + return get((Object)null) != get(v); // old acmp + } + + public boolean testNotNull03_1(Object u) { + return u != null; // old acmp + } + + public boolean testNotNull03_2(Object u) { + return get(u) != null; // old acmp + } + + public boolean testNotNull03_3(Object u) { + return u != get((Object)null); // old acmp + } + + public boolean testNotNull03_4(Object u) { + return get(u) != get((Object)null); // old acmp + } + + public boolean testNotNull04_1(Object u) { + return null != u; // old acmp + } + + public boolean testNotNull04_2(Object u) { + return get((Object)null) != u; // old acmp + } + + public boolean testNotNull04_3(Object u) { + return null != get(u); // old acmp + } + + public boolean testNotNull04_4(Object u) { + return get((Object)null) != get(u); // old acmp + } + + public boolean testNotNull05_1(MyObject o) { + return o != null; // old acmp + } + + public boolean testNotNull05_2(MyObject o) { + return get(o) != null; // old acmp + } + + public boolean testNotNull05_3(MyObject o) { + return o != get((Object)null); // old acmp + } + + public boolean testNotNull05_4(MyObject o) { + return get(o) != get((Object)null); // old acmp + } + + public boolean testNotNull06_1(MyObject o) { + return null != o; // old acmp + } + + public boolean testNotNull06_2(MyObject o) { + return get((Object)null) != o; // old acmp + } + + public boolean testNotNull06_3(MyObject o) { + return null != get(o); // old acmp + } + + public boolean testNotNull06_4(MyObject o) { + return get((Object)null) != get(o); // old acmp + } + + public boolean testNotNull07_1(MyInterface u) { + return u != null; // old acmp + } + + public boolean testNotNull07_2(MyInterface u) { + return get(u) != null; // old acmp + } + + public boolean testNotNull07_3(MyInterface u) { + return u != get((Object)null); // old acmp + } + + public boolean testNotNull07_4(MyInterface u) { + return get(u) != get((Object)null); // old acmp + } + + public boolean testNotNull08_1(MyInterface u) { + return null != u; // old acmp + } + + public boolean testNotNull08_2(MyInterface u) { + return get((Object)null) != u; // old acmp + } + + public boolean testNotNull08_3(MyInterface u) { + return null != get(u); // old acmp + } + + public boolean testNotNull08_4(MyInterface u) { + return get((Object)null) != get(u); // old acmp + } + + // The following methods are used with -XX:+AlwaysIncrementalInline to hide exact types during parsing + + public Object get(Object u) { + return u; + } + + public Object getNotNull(Object u) { + return (u != null) ? u : new Object(); + } + + public Object get(MyValue v) { + return v; + } + + public Object getNotNull(MyValue v) { + return (v != null) ? v : new MyValue(); + } + + public Object get(MyObject o) { + return o; + } + + public Object getNotNull(MyObject o) { + return (o != null) ? o : new MyObject(); + } + + public Object get(Object[] a) { + return a; + } + + public Object getNotNull(Object[] a) { + return (a != null) ? a : new Object[1]; + } + + public boolean falseIfNull(Method m) { + String name = m.getName(); + Pattern pattern = Pattern.compile("(01_4|01_5|01_6|21_4|21_5|21_6)$"); + Matcher matcher = pattern.matcher(name); + return matcher.find(); + } + + public boolean alwaysFalse(Method m) { + String name = m.getName(); + Pattern pattern = Pattern.compile("(07_1|07_2|07_3|08_1|08_2|08_3|09_1|09_2|09_3|10_1|10_2|10_3|11_1|11_2|11_3|19_1|19_2|19_3|20_1|20_2|20_3|24_1|24_2|24_3|25_1|25_2|25_3|32_1|32_2|32_3|33_1|33_2|33_3)$"); + Matcher matcher = pattern.matcher(name); + return matcher.find(); + } + + public void runMethod(Method m, Object[] args, int warmup) throws Exception { + Class[] parameterTypes = m.getParameterTypes(); + int parameterCount = parameterTypes.length; + for (int i = 0; i < args.length; ++i) { + if (args[i] != null && !parameterTypes[0].isInstance(args[i])) { + continue; + } + if (parameterCount == 1) { + // Null checks + System.out.print("Testing " + m.getName() + "(" + args[i] + ")"); + boolean negated = m.getName().startsWith("testNot"); + boolean expected = args[i] == null; + if (negated) expected = !expected; + for (int run = 0; run < warmup; ++run) { + Boolean result = (Boolean)m.invoke(this, args[i]); + if (result != expected) { + System.out.println(" = " + result); + throw new RuntimeException("Test failed: should return " + expected); + } + } + System.out.println(" = " + expected); + } else { + // Equality checks + for (int j = 0; j < args.length; ++j) { + if (args[j] != null && !parameterTypes[1].isInstance(args[j])) { + continue; + } + System.out.print("Testing " + m.getName() + "(" + args[i] + ", " + args[j] + ")"); + boolean negated = m.getName().startsWith("testNot"); + boolean expected = (i == j) && !(args[i] instanceof MyValue) && !alwaysFalse(m) && !((args[i] == null || args[j] == null) && falseIfNull(m)); + if (negated) expected = !expected; + for (int run = 0; run < warmup; ++run) { + Boolean result = (Boolean)m.invoke(this, args[i], args[j]); + if (result != expected) { + System.out.println(" = " + result); + throw new RuntimeException("Test failed: should return " + expected); + } + } + System.out.println(" = " + expected); + } + } + } + } + + public void run() throws Exception { + Object[] args = new Object[5]; + args[0] = null; + args[1] = new Object(); + args[2] = new MyObject(); + args[3] = new MyValue(); + args[4] = new Object[10]; + + for (Method m : getClass().getMethods()) { + if (m.getName().startsWith("test")) { + // runMethod(m, args, 100_000); + runMethod(m, args, 10_000); + } + } + } + + public static void main(String[] args) throws Exception { + Test t = new Test(); + t.run(); + } +} +