src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/library_call.cpp	Thu May 15 17:09:28 2014
--- new/src/share/vm/opto/library_call.cpp	Thu May 15 17:09:27 2014

*** 968,987 **** --- 968,987 ---- return NULL; } IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform(new (C) IfTrueNode(iff)); if (if_slow == top()) { // The slow branch is never taken. No need to build this guard. return NULL; } if (region != NULL) region->add_req(if_slow); - Node* if_fast = _gvn.transform(new (C) IfFalseNode(iff)); set_control(if_fast); return if_slow; }
*** 996,1011 **** --- 996,1011 ---- Node* *pos_index) { if (stopped()) return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint] return NULL; // index is already adequately typed - Node* cmp_lt = _gvn.transform(new (C) CmpINode(index, intcon(0))); - Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt)); Node* is_neg = generate_guard(bol_lt, region, PROB_MIN); if (is_neg != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. - Node* ccast = new (C) CastIINode(index, TypeInt::POS); ccast->set_req(0, control()); (*pos_index) = _gvn.transform(ccast); } return is_neg; }
*** 1014,1030 **** --- 1014,1030 ---- Node* *pos_index) { if (stopped()) return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint] return NULL; // index is already adequately typed - Node* cmp_le = _gvn.transform(new (C) CmpINode(index, intcon(0))); BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le); - Node* bol_le = _gvn.transform(new (C) BoolNode(cmp_le, le_or_eq)); Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN); if (is_notp != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. - Node* ccast = new (C) CastIINode(index, TypeInt::POS1); ccast->set_req(0, control()); (*pos_index) = _gvn.transform(ccast); } return is_notp; }
*** 1052,1074 **** --- 1052,1074 ---- bool zero_offset = _gvn.type(offset) == TypeInt::ZERO; if (zero_offset && subseq_length->eqv_uncast(array_length)) return NULL; // common case of whole-array copy Node* last = subseq_length; if (!zero_offset) // last += offset - last = _gvn.transform(new (C) AddINode(last, offset)); - Node* cmp_lt = _gvn.transform(new (C) CmpUNode(array_length, last)); - Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt)); Node* is_over = generate_guard(bol_lt, region, PROB_MIN); return is_over; } //--------------------------generate_current_thread-------------------- Node* LibraryCallKit::generate_current_thread(Node* &tls_output) { ciKlass* thread_klass = env()->Thread_klass(); const Type* thread_type = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull); - Node* thread = _gvn.transform(new (C) ThreadLocalNode()); Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset())); Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT, MemNode::unordered); tls_output = thread; return threadObj; }
*** 1099,1120 **** --- 1099,1120 ---- switch (opcode) { case Op_StrIndexOf: // Get length of string 2 str2_len = load_String_length(no_ctrl, str2); - result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), str1_start, str1_len, str2_start, str2_len); break; case Op_StrComp: // Get length of string 2 str2_len = load_String_length(no_ctrl, str2); - result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS), str1_start, str1_len, str2_start, str2_len); break; case Op_StrEquals: - result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), str1_start, str2_start, str1_len); break; default: ShouldNotReachHere(); return NULL;
*** 1132,1150 **** --- 1132,1150 ---- // Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2) { Node* result = NULL; switch (opcode) { case Op_StrIndexOf: - result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS), str1_start, cnt1, str2_start, cnt2); break; case Op_StrComp: - result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS), str1_start, cnt1, str2_start, cnt2); break; case Op_StrEquals: - result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS), str1_start, str2_start, cnt1); break; default: ShouldNotReachHere(); return NULL;
*** 1177,1192 **** --- 1177,1192 ---- if (stopped()) { return true; } // paths (plus control) merge - RegionNode* region = new (C) RegionNode(5); - Node* phi = new (C) PhiNode(region, TypeInt::BOOL); // does source == target string? - Node* cmp = _gvn.transform(new (C) CmpPNode(receiver, argument)); - Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq)); Node* if_eq = generate_slow_guard(bol, NULL); if (if_eq != NULL) { // receiver == argument phi->init_req(2, intcon(1));
*** 1196,1207 **** --- 1196,1207 ---- // get String klass for instanceOf ciInstanceKlass* klass = env()->String_klass(); if (!stopped()) { Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass))); - Node* cmp = _gvn.transform(new (C) CmpINode(inst, intcon(1))); - Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne)); Node* inst_false = generate_guard(bol, NULL, PROB_MIN); //instanceOf == true, fallthrough if (inst_false != NULL) {
*** 1212,1222 **** --- 1212,1222 ---- if (!stopped()) { const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass); // Properly cast the argument to String - argument = _gvn.transform(new (C) CheckCastPPNode(control(), argument, string_type)); // This path is taken only when argument's type is String:NotNull. argument = cast_not_null(argument, false); Node* no_ctrl = NULL;
*** 1235,1246 **** --- 1235,1246 ---- // Get length of argument Node* argument_cnt = load_String_length(no_ctrl, argument); // Check for receiver count != argument count - Node* cmp = _gvn.transform(new(C) CmpINode(receiver_cnt, argument_cnt)); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::ne)); Node* if_ne = generate_slow_guard(bol, NULL); if (if_ne != NULL) { phi->init_req(4, intcon(0)); region->init_req(4, if_ne); }
*** 1264,1274 **** --- 1264,1274 ---- //------------------------------inline_array_equals---------------------------- bool LibraryCallKit::inline_array_equals() { Node* arg1 = argument(0); Node* arg2 = argument(1); - set_result(_gvn.transform(new (C) AryEqNode(control(), memory(TypeAryPtr::CHARS), arg1, arg2))); return true; } // Java version of String.indexOf(constant string) // class StringDecl {
*** 1433,1444 **** --- 1433,1444 ---- ciInstanceKlass* str_klass = env()->String_klass(); const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass); // Make the merge point - RegionNode* result_rgn = new (C) RegionNode(4); - Node* result_phi = new (C) PhiNode(result_rgn, TypeInt::INT); Node* no_ctrl = NULL; // Get start addr of source string Node* source = load_String_value(no_ctrl, receiver); Node* source_offset = load_String_offset(no_ctrl, receiver);
*** 1454,1475 **** --- 1454,1475 ---- // Get length of source string Node* substr_cnt = load_String_length(no_ctrl, arg); // Check for substr count > string count - Node* cmp = _gvn.transform(new(C) CmpINode(substr_cnt, source_cnt)); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::gt)); Node* if_gt = generate_slow_guard(bol, NULL); if (if_gt != NULL) { result_phi->init_req(2, intcon(-1)); result_rgn->init_req(2, if_gt); } if (!stopped()) { // Check for substr count == 0 - cmp = _gvn.transform(new(C) CmpINode(substr_cnt, intcon(0))); - bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq)); Node* if_zero = generate_slow_guard(bol, NULL); if (if_zero != NULL) { result_phi->init_req(3, intcon(0)); result_rgn->init_req(3, if_zero); }
*** 1557,1567 **** --- 1557,1567 ---- //--------------------------round_double_node-------------------------------- // Round a double node if necessary. Node* LibraryCallKit::round_double_node(Node* n) { if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1) - n = _gvn.transform(new (C) RoundDoubleNode(0, n)); return n; } //------------------------------inline_math----------------------------------- // public static double Math.abs(double)
*** 1570,1583 **** --- 1570,1583 ---- // public static double Math.log10(double) bool LibraryCallKit::inline_math(vmIntrinsics::ID id) { Node* arg = round_double_node(argument(0)); Node* n; switch (id) { - case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break; - case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(C, control(), arg); break; - case vmIntrinsics::_dlog: n = new (C) LogDNode(C, control(), arg); break; - case vmIntrinsics::_dlog10: n = new (C) Log10DNode(C, control(), arg); break; default: fatal_unexpected_iid(id); break; } set_result(_gvn.transform(n)); return true; }
*** 1588,1600 **** --- 1588,1600 ---- bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) { Node* arg = round_double_node(argument(0)); Node* n = NULL; switch (id) { - case vmIntrinsics::_dsin: n = new (C) SinDNode(C, control(), arg); break; - case vmIntrinsics::_dcos: n = new (C) CosDNode(C, control(), arg); break; - case vmIntrinsics::_dtan: n = new (C) TanDNode(C, control(), arg); break; default: fatal_unexpected_iid(id); break; } n = _gvn.transform(n); // Rounding required? Check for argument reduction!
*** 1631,1651 **** --- 1631,1651 ---- // requires a special machine instruction to load it. Instead we'll try // the 'easy' case. If we really need the extra range +/- PI/2 we'll // probably do the math inside the SIN encoding. // Make the merge point - RegionNode* r = new (C) RegionNode(3); - Node* phi = new (C) PhiNode(r, Type::DOUBLE); // Flatten arg so we need only 1 test - Node *abs = _gvn.transform(new (C) AbsDNode(arg)); // Node for PI/4 constant Node *pi4 = makecon(TypeD::make(pi_4)); // Check PI/4 : abs(arg) - Node *cmp = _gvn.transform(new (C) CmpDNode(pi4,abs)); // Check: If PI/4 < abs(arg) then go slow - Node *bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::lt )); // Branch either way IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); set_control(opt_iff(r,iff)); // Set fast path result
*** 1669,1679 **** --- 1669,1679 ---- CAST_FROM_FN_PTR(address, SharedRuntime::dtan), "Tan", NULL, arg, top()); break; } assert(control()->in(0) == call, ""); - Node* slow_result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); r->init_req(1, control()); phi->init_req(1, slow_result); // Post-merge set_control(_gvn.transform(r));
*** 1689,1701 **** --- 1689,1701 ---- Node* LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) { //------------------- //result=(result.isNaN())? funcAddr():result; // Check: If isNaN() by checking result!=result? then either trap // or go to runtime - Node* cmpisnan = _gvn.transform(new (C) CmpDNode(result, result)); // Build the boolean node - Node* bolisnum = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::eq)); if (!too_many_traps(Deoptimization::Reason_intrinsic)) { { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT); // The pow or exp intrinsic returned a NaN, which requires a call // to the runtime. Recompile with the runtime call.
*** 1706,1734 **** --- 1706,1734 ---- } else { // If this inlining ever returned NaN in the past, we compile a call // to the runtime to properly handle corner cases IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform(new (C) IfFalseNode(iff)); - Node* if_fast = _gvn.transform(new (C) IfTrueNode(iff)); if (!if_slow->is_top()) { - RegionNode* result_region = new (C) RegionNode(3); - PhiNode* result_val = new (C) PhiNode(result_region, Type::DOUBLE); result_region->init_req(1, if_fast); result_val->init_req(1, result); set_control(if_slow); const TypePtr* no_memory_effects = NULL; Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, no_memory_effects, x, top(), y, y ? top() : NULL); - Node* value = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif result_region->init_req(2, control()); result_val->init_req(2, value);
*** 1743,1753 **** --- 1743,1753 ---- //------------------------------inline_exp------------------------------------- // Inline exp instructions, if possible. The Intel hardware only misses // really odd corner cases (+/- Infinity). Just uncommon-trap them. bool LibraryCallKit::inline_exp() { Node* arg = round_double_node(argument(0)); - Node* n = _gvn.transform(new (C) ExpDNode(C, control(), arg)); n = finish_pow_exp(n, arg, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP"); set_result(n); C->set_has_split_ifs(true); // Has chance for split-if optimization
*** 1782,1909 **** --- 1782,1909 ---- Node* y = round_double_node(argument(2)); Node* result = NULL; Node* const_two_node = makecon(TypeD::make(2.0)); - Node* cmp_node = _gvn.transform(new (C) CmpDNode(y, const_two_node)); - Node* bool_node = _gvn.transform(new (C) BoolNode(cmp_node, BoolTest::eq)); IfNode* if_node = create_and_xform_if(control(), bool_node, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); - Node* if_true = _gvn.transform(new (C) IfTrueNode(if_node)); - Node* if_false = _gvn.transform(new (C) IfFalseNode(if_node)); - RegionNode* region_node = new (C) RegionNode(3); region_node->init_req(1, if_true); - Node* phi_node = new (C) PhiNode(region_node, Type::DOUBLE); // special case for x^y where y == 2, we can convert it to x * x - phi_node->init_req(1, _gvn.transform(new (C) MulDNode(x, x))); // set control to if_false since we will now process the false branch set_control(if_false); if (!too_many_traps(Deoptimization::Reason_intrinsic)) { // Short form: skip the fancy tests and just check for NaN result. - result = _gvn.transform(new (C) PowDNode(C, control(), x, y)); } else { // If this inlining ever returned NaN in the past, include all // checks + call to the runtime. // Set the merge point for If node with condition of (x <= 0.0) // There are four possible paths to region node and phi node - RegionNode *r = new (C) RegionNode(4); - Node *phi = new (C) PhiNode(r, Type::DOUBLE); // Build the first if node: if (x <= 0.0) // Node for 0 constant Node *zeronode = makecon(TypeD::ZERO); // Check x:0 - Node *cmp = _gvn.transform(new (C) CmpDNode(x, zeronode)); // Check: If (x<=0) then go complex path - Node *bol1 = _gvn.transform(new (C) BoolNode( cmp, BoolTest::le )); // Branch either way IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); // Fast path taken; set region slot 3 - Node *fast_taken = _gvn.transform(new (C) IfFalseNode(if1)); r->init_req(3,fast_taken); // Capture fast-control // Fast path not-taken, i.e. slow path - Node *complex_path = _gvn.transform(new (C) IfTrueNode(if1)); // Set fast path result - Node *fast_result = _gvn.transform(new (C) PowDNode(C, control(), x, y)); phi->init_req(3, fast_result); // Complex path // Build the second if node (if y is long) // Node for (long)y - Node *longy = _gvn.transform(new (C) ConvD2LNode(y)); // Node for (double)((long) y) - Node *doublelongy= _gvn.transform(new (C) ConvL2DNode(longy)); // Check (double)((long) y) : y - Node *cmplongy= _gvn.transform(new (C) CmpDNode(doublelongy, y)); // Check if (y isn't long) then go to slow path - Node *bol2 = _gvn.transform(new (C) BoolNode( cmplongy, BoolTest::ne )); // Branch either way IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); - Node* ylong_path = _gvn.transform(new (C) IfFalseNode(if2)); - Node *slow_path = _gvn.transform(new (C) IfTrueNode(if2)); // Calculate DPow(abs(x), y)*(1 & (long)y) // Node for constant 1 Node *conone = longcon(1); // 1& (long)y - Node *signnode= _gvn.transform(new (C) AndLNode(conone, longy)); // A huge number is always even. Detect a huge number by checking // if y + 1 == y and set integer to be tested for parity to 0. // Required for corner case: // (long)9.223372036854776E18 = max_jlong // (double)(long)9.223372036854776E18 = 9.223372036854776E18 // max_jlong is odd but 9.223372036854776E18 is even - Node* yplus1 = _gvn.transform(new (C) AddDNode(y, makecon(TypeD::make(1)))); - Node *cmpyplus1= _gvn.transform(new (C) CmpDNode(yplus1, y)); - Node *bolyplus1 = _gvn.transform(new (C) BoolNode( cmpyplus1, BoolTest::eq )); Node* correctedsign = NULL; if (ConditionalMoveLimit != 0) { correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG)); } else { IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN); - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, TypeLong::LONG); - r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyplus1))); - r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyplus1))); phi->init_req(1, signnode); phi->init_req(2, longcon(0)); correctedsign = _gvn.transform(phi); ylong_path = _gvn.transform(r); record_for_igvn(r); } // zero node Node *conzero = longcon(0); // Check (1&(long)y)==0? - Node *cmpeq1 = _gvn.transform(new (C) CmpLNode(correctedsign, conzero)); // Check if (1&(long)y)!=0?, if so the result is negative - Node *bol3 = _gvn.transform(new (C) BoolNode( cmpeq1, BoolTest::ne )); // abs(x) - Node *absx=_gvn.transform(new (C) AbsDNode(x)); // abs(x)^y - Node *absxpowy = _gvn.transform(new (C) PowDNode(C, control(), absx, y)); // -abs(x)^y - Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy)); // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y) Node *signresult = NULL; if (ConditionalMoveLimit != 0) { signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE)); } else { IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN); - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, Type::DOUBLE); - r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyeven))); - r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyeven))); phi->init_req(1, absxpowy); phi->init_req(2, negabsxpowy); signresult = _gvn.transform(phi); ylong_path = _gvn.transform(r); record_for_igvn(r);
*** 1948,1960 **** --- 1948,1960 ---- const TypePtr* no_memory_effects = NULL; Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName, no_memory_effects, a, top(), b, b ? top() : NULL); - Node* value = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif set_result(value); return true;
*** 2010,2023 **** --- 2010,2023 ---- set_result(generate_min_max(id, argument(0), argument(1))); return true; } void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) { - Node* bol = _gvn.transform( new (C) BoolNode(test, BoolTest::overflow) ); IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); - Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); - Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); { PreserveJVMState pjvms(this); PreserveReexecuteState preexecs(this); jvms()->set_should_reexecute(true);
*** 2035,2047 **** --- 2035,2047 ---- template <typename OverflowOp> bool LibraryCallKit::inline_math_overflow(Node* arg1, Node* arg2) { typedef typename OverflowOp::MathOp MathOp; - MathOp* mathOp = new(C) MathOp(arg1, arg2); Node* operation = _gvn.transform( mathOp ); - Node* ofcheck = _gvn.transform( new(C) OverflowOp(arg1, arg2) ); inline_math_mathExact(operation, ofcheck); return true; } bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
*** 2105,2115 **** --- 2105,2115 ---- // and similar uses of System.arraycopy. // First, compute the normalized version of CmpI(x, y). int cmp_op = Op_CmpI; Node* xkey = xvalue; Node* ykey = yvalue; - Node* ideal_cmpxy = _gvn.transform(new(C) CmpINode(xkey, ykey)); if (ideal_cmpxy->is_Cmp()) { // E.g., if we have CmpI(length - offset, count), // it might idealize to CmpI(length, count + offset) cmp_op = ideal_cmpxy->Opcode(); xkey = ideal_cmpxy->in(1);
*** 2198,2208 **** --- 2198,2208 ---- Node* answer_if_false = NULL; switch (best_btest) { default: if (cmpxy == NULL) cmpxy = ideal_cmpxy; - best_bol = _gvn.transform(new(C) BoolNode(cmpxy, BoolTest::lt)); // and fall through: case BoolTest::lt: // x < y case BoolTest::le: // x <= y answer_if_true = (want_max ? yvalue : xvalue); answer_if_false = (want_max ? xvalue : yvalue);
*** 2258,2268 **** --- 2258,2268 ---- if (base_type == NULL) { // Unknown type. return Type::AnyPtr; } else if (base_type == TypePtr::NULL_PTR) { // Since this is a NULL+long form, we have to switch to a rawptr. - base = _gvn.transform(new (C) CastX2PNode(offset)); offset = MakeConX(0); return Type::RawPtr; } else if (base_type->base() == Type::RawPtr) { return Type::RawPtr; } else if (base_type->isa_oopptr()) {
*** 2311,2330 **** --- 2311,2330 ---- // inline long Long.reverseBytes(long) bool LibraryCallKit::inline_number_methods(vmIntrinsics::ID id) { Node* arg = argument(0); Node* n; switch (id) { - case vmIntrinsics::_numberOfLeadingZeros_i: n = new (C) CountLeadingZerosINode( arg); break; - case vmIntrinsics::_numberOfLeadingZeros_l: n = new (C) CountLeadingZerosLNode( arg); break; - case vmIntrinsics::_numberOfTrailingZeros_i: n = new (C) CountTrailingZerosINode(arg); break; - case vmIntrinsics::_numberOfTrailingZeros_l: n = new (C) CountTrailingZerosLNode(arg); break; - case vmIntrinsics::_bitCount_i: n = new (C) PopCountINode( arg); break; - case vmIntrinsics::_bitCount_l: n = new (C) PopCountLNode( arg); break; - case vmIntrinsics::_reverseBytes_c: n = new (C) ReverseBytesUSNode(0, arg); break; - case vmIntrinsics::_reverseBytes_s: n = new (C) ReverseBytesSNode( 0, arg); break; - case vmIntrinsics::_reverseBytes_i: n = new (C) ReverseBytesINode( 0, arg); break; - case vmIntrinsics::_reverseBytes_l: n = new (C) ReverseBytesLNode( 0, arg); break; default: fatal_unexpected_iid(id); break; } set_result(_gvn.transform(n)); return true; }
*** 2636,2646 **** --- 2636,2646 ---- insert_pre_barrier(heap_base_oop, offset, p, !(is_volatile || need_mem_bar)); } break; case T_ADDRESS: // Cast to an int type. - p = _gvn.transform(new (C) CastP2XNode(NULL, p)); p = ConvX2UL(p); break; default: fatal(err_msg_res("unexpected type %d: %s", type, type2name(type))); break;
*** 2657,2667 **** --- 2657,2667 ---- val = dstore_rounding(val); break; case T_ADDRESS: // Repackage the long as a pointer. val = ConvL2X(val); - val = _gvn.transform(new (C) CastX2PNode(val)); break; } MemNode::MemOrd mo = is_volatile ? MemNode::release : MemNode::unordered; if (type != T_OBJECT ) {
*** 2765,2777 **** --- 2765,2777 ---- } // Generate the read or write prefetch Node *prefetch; if (is_store) { - prefetch = new (C) PrefetchWriteNode(i_o(), adr); } else { - prefetch = new (C) PrefetchReadNode(i_o(), adr); } prefetch->init_req(0, control()); set_i_o(_gvn.transform(prefetch)); return true;
*** 2905,2930 **** --- 2905,2930 ---- // longs, and Object. Adding others should be straightforward. Node* load_store; switch(type) { case T_INT: if (kind == LS_xadd) { - load_store = _gvn.transform(new (C) GetAndAddINode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetINode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_cmpxchg) { - load_store = _gvn.transform(new (C) CompareAndSwapINode(control(), mem, adr, newval, oldval)); } else { ShouldNotReachHere(); } break; case T_LONG: if (kind == LS_xadd) { - load_store = _gvn.transform(new (C) GetAndAddLNode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetLNode(control(), mem, adr, newval, adr_type)); } else if (kind == LS_cmpxchg) { - load_store = _gvn.transform(new (C) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); } else { ShouldNotReachHere(); } break; case T_OBJECT:
*** 2957,2984 **** --- 2957,2984 ---- ShouldNotReachHere(); } #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr, newval_enc, adr_type, value_type->make_narrowoop())); } else { assert(kind == LS_cmpxchg, "wrong LoadStore operation"); - Node *oldval_enc = _gvn.transform(new (C) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop())); - load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr, newval_enc, oldval_enc)); } } else #endif { if (kind == LS_xchg) { - load_store = _gvn.transform(new (C) GetAndSetPNode(control(), mem, adr, newval, adr_type, value_type->is_oopptr())); } else { assert(kind == LS_cmpxchg, "wrong LoadStore operation"); - load_store = _gvn.transform(new (C) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); } } post_barrier(control(), load_store, base, adr, alias_idx, newval, T_OBJECT, true); break; default:
*** 2987,3003 **** --- 2987,3003 ---- } // SCMemProjNodes represent the memory state of a LoadStore. Their // main role is to prevent LoadStore nodes from being optimized away // when their results aren't used. - Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store)); set_memory(proj, alias_idx); if (type == T_OBJECT && kind == LS_xchg) { #ifdef _LP64 if (adr->bottom_type()->is_ptr_to_narrowoop()) { - load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); } #endif if (can_move_pre_barrier()) { // Don't need to load pre_val. The old value is returned by load_store. // The pre_barrier can execute after the xchg as long as no safepoint
*** 3135,3145 **** --- 3135,3145 ---- Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset())); // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler // can generate code to load it as unsigned byte. Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered); Node* bits = intcon(InstanceKlass::fully_initialized); - test = _gvn.transform(new (C) SubINode(inst, bits)); // The 'test' is non-zero if we need to take a slow path. } Node* obj = new_instance(kls, test); set_result(obj);
*** 3159,3171 **** --- 3159,3171 ---- kls = null_check(kls, T_OBJECT); ByteSize offset = TRACE_ID_OFFSET; Node* insp = basic_plus_adr(kls, in_bytes(offset)); Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered); Node* bits = longcon(~0x03l); // ignore bit 0 & 1 - Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits)); Node* clsused = longcon(0x01l); // set the class bit - Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused)); const TypePtr *adr_type = _gvn.type(insp)->isa_ptr(); store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered); set_result(andl); return true;
*** 3197,3209 **** --- 3197,3209 ---- // these have the same type and signature bool LibraryCallKit::inline_native_time_funcs(address funcAddr, const char* funcName) { const TypeFunc* tf = OptoRuntime::void_long_Type(); const TypePtr* no_memory_effects = NULL; Node* time = make_runtime_call(RC_LEAF, tf, funcAddr, funcName, no_memory_effects); - Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0)); #ifdef ASSERT - Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+1)); assert(value_top == top(), "second value must be top"); #endif set_result(value); return true; }
*** 3240,3298 **** --- 3240,3298 ---- // Ensure that it's not possible to move the load of TLS._osthread._interrupted flag // out of the function. insert_mem_bar(Op_MemBarCPUOrder); - RegionNode* result_rgn = new (C) RegionNode(PATH_LIMIT); - PhiNode* result_val = new (C) PhiNode(result_rgn, TypeInt::BOOL); - RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); // (a) Receiving thread must be the current thread. Node* rec_thr = argument(0); Node* tls_ptr = NULL; Node* cur_thr = generate_current_thread(tls_ptr); - Node* cmp_thr = _gvn.transform(new (C) CmpPNode(cur_thr, rec_thr)); - Node* bol_thr = _gvn.transform(new (C) BoolNode(cmp_thr, BoolTest::ne)); generate_slow_guard(bol_thr, slow_region); // (b) Interrupt bit on TLS must be false. Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset())); Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered); p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset())); // Set the control input on the field _interrupted read to prevent it floating up. Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered); - Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0))); - Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne)); IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); // First fast path: if (!TLS._interrupted) return false; - Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit)); result_rgn->init_req(no_int_result_path, false_bit); result_val->init_req(no_int_result_path, intcon(0)); // drop through to next case - set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); #ifndef TARGET_OS_FAMILY_windows // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. Node* clr_arg = argument(1); - Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); - Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); // Second fast path: ... else if (!clear_int) return true; - Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg)); result_rgn->init_req(no_clear_result_path, false_arg); result_val->init_req(no_clear_result_path, intcon(1)); // drop through to next case - set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); #else // To return true on Windows you must read the _interrupted field // and check the the event state i.e. take the slow path. #endif // TARGET_OS_FAMILY_windows
*** 3374,3386 **** --- 3374,3386 ---- // Like generate_guard, adds a new path onto the region. Node* modp = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset())); Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT, MemNode::unordered); Node* mask = intcon(modifier_mask); Node* bits = intcon(modifier_bits); - Node* mbit = _gvn.transform(new (C) AndINode(mods, mask)); - Node* cmp = _gvn.transform(new (C) CmpINode(mbit, bits)); - Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne)); return generate_fair_guard(bol, region); } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_access_flags_guard(kls, JVM_ACC_INTERFACE, 0, region); }
*** 3449,3461 **** --- 3449,3461 ---- } } #endif // Null-check the mirror, and the mirror's klass ptr (in case it is a primitive). - RegionNode* region = new (C) RegionNode(PATH_LIMIT); record_for_igvn(region); - PhiNode* phi = new (C) PhiNode(region, return_type); // The mirror will never be null of Reflection.getClassAccessFlags, however // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE // if it is. See bug 4774291.
*** 3593,3604 **** --- 3593,3604 ---- _ref_subtype_path, // {N,N} & subtype check wins => true _both_ref_path, // {N,N} & subtype check loses => false PATH_LIMIT }; - RegionNode* region = new (C) RegionNode(PATH_LIMIT); - Node* phi = new (C) PhiNode(region, TypeInt::BOOL); record_for_igvn(region); const TypePtr* adr_type = TypeRawPtr::BOTTOM; // memory type of loads const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL; int class_klass_offset = java_lang_Class::klass_offset_in_bytes();
*** 3641,3652 **** --- 3641,3652 ---- // we must return true when they are identical primitives. // It is convenient to test this after the first null klass check. set_control(region->in(_prim_0_path)); // go back to first null check if (!stopped()) { // Since superc is primitive, make a guard for the superc==subc case. - Node* cmp_eq = _gvn.transform(new (C) CmpPNode(args[0], args[1])); - Node* bol_eq = _gvn.transform(new (C) BoolNode(cmp_eq, BoolTest::eq)); generate_guard(bol_eq, region, PROB_FAIR); if (region->req() == PATH_LIMIT+1) { // A guard was added. If the added guard is taken, superc==subc. region->swap_edges(PATH_LIMIT, _prim_same_path); region->del_req(PATH_LIMIT);
*** 3707,3721 **** --- 3707,3721 ---- // Now test the correct condition. jint nval = (obj_array ? ((jint)Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift) : Klass::_lh_neutral_value); - Node* cmp = _gvn.transform(new(C) CmpINode(layout_val, intcon(nval))); BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array // invert the test if we are looking for a non-array if (not_array) btest = BoolTest(btest).negate(); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, btest)); return generate_fair_guard(bol, region); } //-----------------------inline_native_newArray--------------------------
*** 3727,3742 **** --- 3727,3740 ---- mirror = null_check(mirror); // If mirror or obj is dead, only null-path is taken. if (stopped()) return true; enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT }; - RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); ! PhiNode* result_val = new(C) PhiNode(result_reg, ! TypeInstPtr::NOTNULL); ! PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); ! PhiNode* result_val = new PhiNode(result_reg, TypeInstPtr::NOTNULL); ! PhiNode* result_io = new PhiNode(result_reg, Type::ABIO); ! PhiNode* result_mem = new PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check); Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null, result_reg, _slow_path); Node* normal_ctl = control();
*** 3839,3870 **** --- 3837,3868 ---- Node* orig_length = load_array_length(original); Node* klass_node = load_klass_from_mirror(array_type_mirror, false, NULL, 0); klass_node = null_check(klass_node); - RegionNode* bailout = new (C) RegionNode(1); record_for_igvn(bailout); // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc. // Bail out if that is so. Node* not_objArray = generate_non_objArray_guard(klass_node, bailout); if (not_objArray != NULL) { // Improve the klass node's type from the new optimistic assumption: ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); - Node* cast = new (C) CastPPNode(klass_node, akls); cast->init_req(0, control()); klass_node = _gvn.transform(cast); } // Bail out if either start or end is negative. generate_negative_guard(start, bailout, &start); generate_negative_guard(end, bailout, &end); Node* length = end; if (_gvn.type(start) != TypeInt::ZERO) { - length = _gvn.transform(new (C) SubINode(end, start)); } // Bail out if length is negative. // Without this the new_array would throw // NegativeArraySizeException but IllegalArgumentException is what
*** 3879,3889 **** --- 3877,3887 ---- } if (!stopped()) { // How many elements will we copy from the original? // The answer is MinI(orig_length - start, length). - Node* orig_tail = _gvn.transform(new (C) SubINode(orig_length, start)); Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); newcopy = new_array(klass_node, length, 0); // no argments to push // Generate a direct call to the right arraycopy function(s).
*** 3926,3937 **** --- 3924,3935 ---- // Compare the target method with the expected method (e.g., Object.hashCode). const TypePtr* native_call_addr = TypeMetadataPtr::make(method); Node* native_call = makecon(native_call_addr); - Node* chk_native = _gvn.transform(new(C) CmpPNode(target_call, native_call)); - Node* test_native = _gvn.transform(new(C) BoolNode(chk_native, BoolTest::ne)); return generate_slow_guard(test_native, slow_region); } //-----------------------generate_method_call----------------------------
*** 3952,3962 **** --- 3950,3960 ---- const TypeFunc* tf = TypeFunc::make(method); CallJavaNode* slow_call; if (is_static) { assert(!is_virtual, ""); - slow_call = new(C) CallStaticJavaNode(C, tf, SharedRuntime::get_resolve_static_call_stub(), method, bci()); } else if (is_virtual) { null_check_receiver(); int vtable_index = Method::invalid_vtable_index;
*** 3968,3983 **** --- 3966,3981 ---- // No need to use the linkResolver to get it. vtable_index = method->vtable_index(); assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, err_msg_res("bad index %d", vtable_index)); } - slow_call = new(C) CallDynamicJavaNode(tf, SharedRuntime::get_resolve_virtual_call_stub(), method, vtable_index, bci()); } else { // neither virtual nor static: opt_virtual null_check_receiver(); - slow_call = new(C) CallStaticJavaNode(C, tf, SharedRuntime::get_resolve_opt_virtual_call_stub(), method, bci()); slow_call->set_optimized_virtual(true); } set_arguments_for_java_call(slow_call);
*** 3992,4007 **** --- 3990,4003 ---- assert(is_static == callee()->is_static(), "correct intrinsic selection"); assert(!(is_virtual && is_static), "either virtual, special, or static"); enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT }; - RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); ! PhiNode* result_val = new(C) PhiNode(result_reg, ! TypeInt::INT); ! PhiNode* result_io = new(C) PhiNode(result_reg, Type::ABIO); PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); ! PhiNode* result_val = new PhiNode(result_reg, TypeInt::INT); ! PhiNode* result_io = new PhiNode(result_reg, Type::ABIO); ! PhiNode* result_mem = new PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); Node* obj = NULL; if (!is_static) { // Check for hashing null object obj = null_check_receiver(); if (stopped()) return true; // unconditionally null
*** 4031,4041 **** --- 4027,4037 ---- // This call may be virtual (invokevirtual) or bound (invokespecial). // For each case we generate slightly different code. // We only go to the fast case code if we pass a number of guards. The // paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); // If this is a virtual call, we generate a funny guard. We pull out // the vtable entry corresponding to hashCode() from the target object. // If the target method which we are calling happens to be the native
*** 4050,4083 **** --- 4046,4079 ---- Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); // Test the header to see if it is unlocked. Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); - Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); - Node *chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); - Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); generate_slow_guard(test_unlocked, slow_region); // Get the hash value and check to see that it has been properly assigned. // We depend on hash_mask being at most 32 bits and avoid the use of // hash_mask_in_place because it could be larger than 32 bits in a 64-bit // vm: see markOop.hpp. Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); - Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); // This hack lets the hash bits live anywhere in the mark object now, as long // as the shift drops the relevant bits into the low 32 bits. Note that // Java spec says that HashCode is an int so there's no point in capturing // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). hshifted_header = ConvX2I(hshifted_header); - Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); - Node *chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); - Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); generate_slow_guard(test_assigned, slow_region); Node* init_mem = reset_memory(); // fill in the rest of the null path:
*** 4212,4255 **** --- 4208,4251 ---- bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) { Node* arg = argument(0); Node* result; switch (id) { - case vmIntrinsics::_floatToRawIntBits: result = new (C) MoveF2INode(arg); break; - case vmIntrinsics::_intBitsToFloat: result = new (C) MoveI2FNode(arg); break; - case vmIntrinsics::_doubleToRawLongBits: result = new (C) MoveD2LNode(arg); break; - case vmIntrinsics::_longBitsToDouble: result = new (C) MoveL2DNode(arg); break; case vmIntrinsics::_doubleToLongBits: { // two paths (plus control) merge in a wood - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, TypeLong::LONG); - Node *cmpisnan = _gvn.transform(new (C) CmpDNode(arg, arg)); // Build the boolean node - Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne)); // Branch either way. // NaN case is less traveled, which makes all the difference. IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan)); set_control(iftrue); static const jlong nan_bits = CONST64(0x7ff8000000000000); Node *slow_result = longcon(nan_bits); // return NaN phi->init_req(1, _gvn.transform( slow_result )); r->init_req(1, iftrue); // Else fall through - Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan)); set_control(iffalse); - phi->init_req(2, _gvn.transform(new (C) MoveD2LNode(arg))); r->init_req(2, iffalse); // Post merge set_control(_gvn.transform(r)); record_for_igvn(r);
*** 4260,4296 **** --- 4256,4292 ---- break; } case vmIntrinsics::_floatToIntBits: { // two paths (plus control) merge in a wood - RegionNode *r = new (C) RegionNode(3); - Node *phi = new (C) PhiNode(r, TypeInt::INT); - Node *cmpisnan = _gvn.transform(new (C) CmpFNode(arg, arg)); // Build the boolean node - Node *bolisnan = _gvn.transform(new (C) BoolNode(cmpisnan, BoolTest::ne)); // Branch either way. // NaN case is less traveled, which makes all the difference. IfNode *ifisnan = create_and_xform_if(control(), bolisnan, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan)); set_control(iftrue); static const jint nan_bits = 0x7fc00000; Node *slow_result = makecon(TypeInt::make(nan_bits)); // return NaN phi->init_req(1, _gvn.transform( slow_result )); r->init_req(1, iftrue); // Else fall through - Node *iffalse = _gvn.transform(new (C) IfFalseNode(opt_ifisnan)); set_control(iffalse); - phi->init_req(2, _gvn.transform(new (C) MoveF2INode(arg))); r->init_req(2, iffalse); // Post merge set_control(_gvn.transform(r)); record_for_igvn(r);
*** 4402,4413 **** --- 4398,4409 ---- src = basic_plus_adr(src, base_off); dest = basic_plus_adr(dest, base_off); // Compute the length also, if needed: Node* countx = size; - countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(base_off))); - countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong) )); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; bool disjoint_bases = true; generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, src, NULL, dest, NULL, countx,
*** 4492,4507 **** --- 4488,4501 ---- _objArray_path, // plain array allocation, plus arrayof_oop_arraycopy _array_path, // plain array allocation, plus arrayof_long_arraycopy _instance_path, // plain instance allocation, plus arrayof_long_arraycopy PATH_LIMIT }; - RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT); ! result_val = new(C) PhiNode(result_reg, ! TypeInstPtr::NOTNULL); ! PhiNode* result_i_o = new(C) PhiNode(result_reg, Type::ABIO); PhiNode* result_mem = new(C) PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); ! result_val = new PhiNode(result_reg, TypeInstPtr::NOTNULL); ! PhiNode* result_i_o = new PhiNode(result_reg, Type::ABIO); ! PhiNode* result_mem = new PhiNode(result_reg, Type::MEMORY, TypePtr::BOTTOM); record_for_igvn(result_reg); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; int raw_adr_idx = Compile::AliasIdxRaw;
*** 4553,4563 **** --- 4547,4557 ---- } } // We only go to the instance fast case code if we pass a number of guards. // The paths which do not pass are accumulated in the slow_region. - RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); if (!stopped()) { // It's an instance (we did array above). Make the slow-path tests. // If this is a virtual call, we generate a funny guard. We grab // the vtable entry corresponding to clone() from the target object.
*** 4810,4820 **** --- 4804,4814 ---- // (6) length must not be negative. // (7) src_offset + length must not exceed length of src. // (8) dest_offset + length must not exceed length of dest. // (9) each element of an oop array must be assignable - RegionNode* slow_region = new (C) RegionNode(1); record_for_igvn(slow_region); // (3) operands must not be null // We currently perform our null checks with the null_check routine. // This means that the null exceptions will be reported in the caller
*** 4898,4908 **** --- 4892,4902 ---- bool disjoint_bases, bool length_never_negative, RegionNode* slow_region) { if (slow_region == NULL) { - slow_region = new(C) RegionNode(1); record_for_igvn(slow_region); } Node* original_dest = dest; AllocateArrayNode* alloc = NULL; // used for zeroing, if needed
*** 4946,4958 **** --- 4940,4952 ---- slow_call_path = 3, // something went wrong; call the VM zero_path = 4, // bypass when length of copy is zero bcopy_path = 5, // copy primitive array by 64-bit blocks PATH_LIMIT = 6 }; - RegionNode* result_region = new(C) RegionNode(PATH_LIMIT); - PhiNode* result_i_o = new(C) PhiNode(result_region, Type::ABIO); - PhiNode* result_memory = new(C) PhiNode(result_region, Type::MEMORY, adr_type); record_for_igvn(result_region); _gvn.set_type_bottom(result_i_o); _gvn.set_type_bottom(result_memory); assert(adr_type != TypePtr::BOTTOM, "must be RawMem or a T[] slice");
*** 5022,5033 **** --- 5016,5026 ---- // We have to initialize the *uncopied* part of the array to zero. // The copy destination is the slice dest[off..off+len]. The other slices // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length]. Node* dest_size = alloc->in(AllocateNode::AllocSize); Node* dest_length = alloc->in(AllocateNode::ALength); ! Node* dest_tail = _gvn.transform(new(C) AddINode(dest_offset, copy_length)); ! Node* dest_tail = _gvn.transform(new AddINode(dest_offset, copy_length)); // If there is a head section that needs zeroing, do it now. if (find_int_con(dest_offset, -1) != 0) { generate_clear_array(adr_type, dest, basic_elem_type, intcon(0), dest_offset,
*** 5039,5050 **** --- 5032,5043 ---- // There are two wins: Avoid generating the ClearArray // with its attendant messy index arithmetic, and upgrade // the copy to a more hardware-friendly word size of 64 bits. Node* tail_ctl = NULL; if (!stopped() && !dest_tail->eqv_uncast(dest_length)) { - Node* cmp_lt = _gvn.transform(new(C) CmpINode(dest_tail, dest_length)); - Node* bol_lt = _gvn.transform(new(C) BoolNode(cmp_lt, BoolTest::lt)); tail_ctl = generate_slow_guard(bol_lt, NULL); assert(tail_ctl != NULL || !stopped(), "must be an outcome"); } // At this point, let's assume there is no tail.
*** 5074,5085 **** --- 5067,5078 ---- generate_clear_array(adr_type, dest, basic_elem_type, dest_tail, NULL, dest_size); } else { // Make a local merge. - Node* done_ctl = new(C) RegionNode(3); - Node* done_mem = new(C) PhiNode(done_ctl, Type::MEMORY, adr_type); done_ctl->init_req(1, notail_ctl); done_mem->init_req(1, memory(adr_type)); generate_clear_array(adr_type, dest, basic_elem_type, dest_tail, NULL, dest_size);
*** 5170,5194 **** --- 5163,5187 ---- set_control(checked_control); if (!stopped()) { // Clean up after the checked call. // The returned value is either 0 or -1^K, // where K = number of partially transferred array elements. - Node* cmp = _gvn.transform(new(C) CmpINode(checked_value, intcon(0))); - Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq)); IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); // If it is 0, we are done, so transfer to the end. - Node* checks_done = _gvn.transform(new(C) IfTrueNode(iff)); result_region->init_req(checked_path, checks_done); result_i_o ->init_req(checked_path, checked_i_o); result_memory->init_req(checked_path, checked_mem); // If it is not zero, merge into the slow call. - set_control( _gvn.transform(new(C) IfFalseNode(iff) )); - RegionNode* slow_reg2 = new(C) RegionNode(3); - PhiNode* slow_i_o2 = new(C) PhiNode(slow_reg2, Type::ABIO); - PhiNode* slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type); record_for_igvn(slow_reg2); slow_reg2 ->init_req(1, slow_control); slow_i_o2 ->init_req(1, slow_i_o); slow_mem2 ->init_req(1, slow_mem); slow_reg2 ->init_req(2, control());
*** 5204,5223 **** --- 5197,5216 ---- // This can cause double writes, but that's OK since dest is brand new. // So we ignore the low 31 bits of the value returned from the stub. } else { // We must continue the copy exactly where it failed, or else // another thread might see the wrong number of writes to dest. - Node* checked_offset = _gvn.transform(new(C) XorINode(checked_value, intcon(-1))); - Node* slow_offset = new(C) PhiNode(slow_reg2, TypeInt::INT); slow_offset->init_req(1, intcon(0)); slow_offset->init_req(2, checked_offset); slow_offset = _gvn.transform(slow_offset); // Adjust the arguments by the conditionally incoming offset. - Node* src_off_plus = _gvn.transform(new(C) AddINode(src_offset, slow_offset)); - Node* dest_off_plus = _gvn.transform(new(C) AddINode(dest_offset, slow_offset)); - Node* length_minus = _gvn.transform(new(C) SubINode(copy_length, slow_offset)); // Tweak the node variables to adjust the code produced below: src_offset = src_off_plus; dest_offset = dest_off_plus; copy_length = length_minus;
*** 5434,5475 **** --- 5427,5468 ---- // End offset = round_up(abase + ((slice_idx_con + slice_len) << scale), 8) intptr_t end_base = abase + (slice_idx_con << scale); int end_round = (-1 << scale) & (BytesPerLong - 1); Node* end = ConvI2X(slice_len); if (scale != 0) - end = _gvn.transform(new(C) LShiftXNode(end, intcon(scale) )); end_base += end_round; - end = _gvn.transform(new(C) AddXNode(end, MakeConX(end_base))); - end = _gvn.transform(new(C) AndXNode(end, MakeConX(~end_round))); mem = ClearArrayNode::clear_memory(control(), mem, dest, start_con, end, &_gvn); } else if (start_con < 0 && dest_size != top()) { // Non-constant start, pre-rounded end after the tail of the array. // This is almost certainly a "round-to-end" operation. Node* start = slice_idx; start = ConvI2X(start); if (scale != 0) - start = _gvn.transform(new(C) LShiftXNode( start, intcon(scale) )); - start = _gvn.transform(new(C) AddXNode(start, MakeConX(abase))); if ((bump_bit | clear_low) != 0) { int to_clear = (bump_bit | clear_low); // Align up mod 8, then store a jint zero unconditionally // just before the mod-8 boundary. if (((abase + bump_bit) & ~to_clear) - bump_bit < arrayOopDesc::length_offset_in_bytes() + BytesPerInt) { bump_bit = 0; assert((abase & to_clear) == 0, "array base must be long-aligned"); } else { // Bump 'start' up to (or past) the next jint boundary: - start = _gvn.transform(new(C) AddXNode(start, MakeConX(bump_bit))); assert((abase & clear_low) == 0, "array base must be int-aligned"); } // Round bumped 'start' down to jlong boundary in body of array. - start = _gvn.transform(new(C) AndXNode(start, MakeConX(~to_clear))); if (bump_bit != 0) { // Store a zero to the immediately preceding jint: - Node* x1 = _gvn.transform(new(C) AddXNode(start, MakeConX(-bump_bit))); Node* p1 = basic_plus_adr(dest, x1); mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT, MemNode::unordered); mem = _gvn.transform(mem); } }
*** 5532,5543 **** --- 5525,5536 ---- // Do this copy by giant steps. Node* sptr = basic_plus_adr(src, src_off); Node* dptr = basic_plus_adr(dest, dest_off); Node* countx = dest_size; - countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(dest_off))); - countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong))); bool disjoint_bases = true; // since alloc != NULL generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases, sptr, NULL, dptr, NULL, countx, dest_uninitialized);
*** 5583,5593 **** --- 5576,5586 ---- // for the target array. This is an optimistic check. It will // look in each non-null element's class, at the desired klass's // super_check_offset, for the desired klass. int sco_offset = in_bytes(Klass::super_check_offset_offset()); Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); - Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr(), TypeInt::INT, MemNode::unordered); Node* check_offset = ConvI2X(_gvn.transform(n3)); Node* check_value = dest_elem_klass; Node* src_start = array_element_address(src, src_offset, T_OBJECT); Node* dest_start = array_element_address(dest, dest_offset, T_OBJECT);
*** 5601,5611 **** --- 5594,5604 ---- src_start, dest_start, copy_length XTOP, check_offset XTOP, check_value); - return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); } // Helper function; generates code for cases requiring runtime checks. Node*
*** 5623,5633 **** --- 5616,5626 ---- Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::generic_arraycopy_Type(), copyfunc_addr, "generic_arraycopy", adr_type, src, src_offset, dest, dest_offset, copy_length); - return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); } // Helper function; generates the fast out-of-line call to an arraycopy stub. void LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type,
*** 5690,5702 **** --- 5683,5695 ---- Node* dst_start = array_element_address(dst, dst_offset, dst_elem); // 'src_start' points to src array + scaled offset // 'dst_start' points to dst array + scaled offset const TypeAryPtr* mtype = TypeAryPtr::BYTES; - Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length); enc = _gvn.transform(enc); - Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc)); set_memory(res_mem, mtype); set_result(enc); return true; }
*** 5717,5738 **** --- 5710,5731 ---- * b = b ^ (c >>> 8); * crc = ~b; */ Node* M1 = intcon(-1); - crc = _gvn.transform(new (C) XorINode(crc, M1)); - Node* result = _gvn.transform(new (C) XorINode(crc, b)); - result = _gvn.transform(new (C) AndINode(result, intcon(0xFF))); Node* base = makecon(TypeRawPtr::make(StubRoutines::crc_table_addr())); - Node* offset = _gvn.transform(new (C) LShiftINode(result, intcon(0x2))); Node* adr = basic_plus_adr(top(), base, ConvI2X(offset)); result = make_load(control(), adr, TypeInt::INT, T_INT, MemNode::unordered); - crc = _gvn.transform(new (C) URShiftINode(crc, intcon(8))); - result = _gvn.transform(new (C) XorINode(crc, result)); - result = _gvn.transform(new (C) XorINode(result, M1)); set_result(result); return true; } /**
*** 5772,5782 **** --- 5765,5775 ---- const char *stubName = "updateBytesCRC32"; Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(), stubAddr, stubName, TypePtr::BOTTOM, crc, src_start, length); - Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); set_result(result); return true; } /**
*** 5791,5801 **** --- 5784,5794 ---- Node* src = argument(1); // type: long Node* offset = argument(3); // type: int Node* length = argument(4); // type: int src = ConvL2X(src); // adjust Java long to machine word - Node* base = _gvn.transform(new (C) CastX2PNode(src)); offset = ConvI2X(offset); // 'src_start' points to src array + scaled offset Node* src_start = basic_plus_adr(top(), base, offset);
*** 5804,5814 **** --- 5797,5807 ---- const char *stubName = "updateBytesCRC32"; Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(), stubAddr, stubName, TypePtr::BOTTOM, crc, src_start, length); - Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); set_result(result); return true; } //----------------------------inline_reference_get----------------------------
*** 6004,6014 **** --- 5997,6007 ---- if (!klass_AESCrypt->is_loaded()) return false; ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt); const TypeOopPtr* xtype = aklass->as_instance_type(); - Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype); aescrypt_object = _gvn.transform(aescrypt_object); // we need to get the start of the aescrypt_object's expanded key array Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object); if (k_start == NULL) return false;
*** 6037,6047 **** --- 6030,6040 ---- stubAddr, stubName, TypePtr::BOTTOM, src_start, dest_start, k_start, r_start, len); } // return cipher length (int) - Node* retvalue = _gvn.transform(new (C) ProjNode(cbcCrypt, TypeFunc::Parms)); set_result(retvalue); return true; } //------------------------------get_key_start_from_aescrypt_object-----------------------
*** 6101,6128 **** --- 6094,6121 ---- return ctrl; } ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass(); Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt))); - Node* cmp_instof = _gvn.transform(new (C) CmpINode(instof, intcon(1))); - Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne)); Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); // for encryption, we are done if (!decrypting) return instof_false; // even if it is NULL // for decryption, we need to add a further check to avoid // taking the intrinsic path when cipher and plain are the same // see the original java code for why. - RegionNode* region = new(C) RegionNode(3); region->init_req(1, instof_false); Node* src = argument(1); Node* dest = argument(4); - Node* cmp_src_dest = _gvn.transform(new (C) CmpPNode(src, dest)); - Node* bool_src_dest = _gvn.transform(new (C) BoolNode(cmp_src_dest, BoolTest::eq)); Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN); region->init_req(2, src_dest_conjoint); record_for_igvn(region); return _gvn.transform(region);

src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File