1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/opto/callnode.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,1311 @@ 1.4 +/* 1.5 + * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// Portions of code courtesy of Clifford Click 1.29 + 1.30 +// Optimization - Graph Style 1.31 + 1.32 +#include "incls/_precompiled.incl" 1.33 +#include "incls/_callnode.cpp.incl" 1.34 + 1.35 +//============================================================================= 1.36 +uint StartNode::size_of() const { return sizeof(*this); } 1.37 +uint StartNode::cmp( const Node &n ) const 1.38 +{ return _domain == ((StartNode&)n)._domain; } 1.39 +const Type *StartNode::bottom_type() const { return _domain; } 1.40 +const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; } 1.41 +#ifndef PRODUCT 1.42 +void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);} 1.43 +#endif 1.44 + 1.45 +//------------------------------Ideal------------------------------------------ 1.46 +Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){ 1.47 + return remove_dead_region(phase, can_reshape) ? this : NULL; 1.48 +} 1.49 + 1.50 +//------------------------------calling_convention----------------------------- 1.51 +void StartNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { 1.52 + Matcher::calling_convention( sig_bt, parm_regs, argcnt, false ); 1.53 +} 1.54 + 1.55 +//------------------------------Registers-------------------------------------- 1.56 +const RegMask &StartNode::in_RegMask(uint) const { 1.57 + return RegMask::Empty; 1.58 +} 1.59 + 1.60 +//------------------------------match------------------------------------------ 1.61 +// Construct projections for incoming parameters, and their RegMask info 1.62 +Node *StartNode::match( const ProjNode *proj, const Matcher *match ) { 1.63 + switch (proj->_con) { 1.64 + case TypeFunc::Control: 1.65 + case TypeFunc::I_O: 1.66 + case TypeFunc::Memory: 1.67 + return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); 1.68 + case TypeFunc::FramePtr: 1.69 + return new (match->C, 1) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP); 1.70 + case TypeFunc::ReturnAdr: 1.71 + return new (match->C, 1) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP); 1.72 + case TypeFunc::Parms: 1.73 + default: { 1.74 + uint parm_num = proj->_con - TypeFunc::Parms; 1.75 + const Type *t = _domain->field_at(proj->_con); 1.76 + if (t->base() == Type::Half) // 2nd half of Longs and Doubles 1.77 + return new (match->C, 1) ConNode(Type::TOP); 1.78 + uint ideal_reg = Matcher::base2reg[t->base()]; 1.79 + RegMask &rm = match->_calling_convention_mask[parm_num]; 1.80 + return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg); 1.81 + } 1.82 + } 1.83 + return NULL; 1.84 +} 1.85 + 1.86 +//------------------------------StartOSRNode---------------------------------- 1.87 +// The method start node for an on stack replacement adapter 1.88 + 1.89 +//------------------------------osr_domain----------------------------- 1.90 +const TypeTuple *StartOSRNode::osr_domain() { 1.91 + const Type **fields = TypeTuple::fields(2); 1.92 + fields[TypeFunc::Parms+0] = TypeRawPtr::BOTTOM; // address of osr buffer 1.93 + 1.94 + return TypeTuple::make(TypeFunc::Parms+1, fields); 1.95 +} 1.96 + 1.97 +//============================================================================= 1.98 +const char * const ParmNode::names[TypeFunc::Parms+1] = { 1.99 + "Control", "I_O", "Memory", "FramePtr", "ReturnAdr", "Parms" 1.100 +}; 1.101 + 1.102 +#ifndef PRODUCT 1.103 +void ParmNode::dump_spec(outputStream *st) const { 1.104 + if( _con < TypeFunc::Parms ) { 1.105 + st->print(names[_con]); 1.106 + } else { 1.107 + st->print("Parm%d: ",_con-TypeFunc::Parms); 1.108 + // Verbose and WizardMode dump bottom_type for all nodes 1.109 + if( !Verbose && !WizardMode ) bottom_type()->dump_on(st); 1.110 + } 1.111 +} 1.112 +#endif 1.113 + 1.114 +uint ParmNode::ideal_reg() const { 1.115 + switch( _con ) { 1.116 + case TypeFunc::Control : // fall through 1.117 + case TypeFunc::I_O : // fall through 1.118 + case TypeFunc::Memory : return 0; 1.119 + case TypeFunc::FramePtr : // fall through 1.120 + case TypeFunc::ReturnAdr: return Op_RegP; 1.121 + default : assert( _con > TypeFunc::Parms, "" ); 1.122 + // fall through 1.123 + case TypeFunc::Parms : { 1.124 + // Type of argument being passed 1.125 + const Type *t = in(0)->as_Start()->_domain->field_at(_con); 1.126 + return Matcher::base2reg[t->base()]; 1.127 + } 1.128 + } 1.129 + ShouldNotReachHere(); 1.130 + return 0; 1.131 +} 1.132 + 1.133 +//============================================================================= 1.134 +ReturnNode::ReturnNode(uint edges, Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr ) : Node(edges) { 1.135 + init_req(TypeFunc::Control,cntrl); 1.136 + init_req(TypeFunc::I_O,i_o); 1.137 + init_req(TypeFunc::Memory,memory); 1.138 + init_req(TypeFunc::FramePtr,frameptr); 1.139 + init_req(TypeFunc::ReturnAdr,retadr); 1.140 +} 1.141 + 1.142 +Node *ReturnNode::Ideal(PhaseGVN *phase, bool can_reshape){ 1.143 + return remove_dead_region(phase, can_reshape) ? this : NULL; 1.144 +} 1.145 + 1.146 +const Type *ReturnNode::Value( PhaseTransform *phase ) const { 1.147 + return ( phase->type(in(TypeFunc::Control)) == Type::TOP) 1.148 + ? Type::TOP 1.149 + : Type::BOTTOM; 1.150 +} 1.151 + 1.152 +// Do we Match on this edge index or not? No edges on return nodes 1.153 +uint ReturnNode::match_edge(uint idx) const { 1.154 + return 0; 1.155 +} 1.156 + 1.157 + 1.158 +#ifndef PRODUCT 1.159 +void ReturnNode::dump_req() const { 1.160 + // Dump the required inputs, enclosed in '(' and ')' 1.161 + uint i; // Exit value of loop 1.162 + for( i=0; i<req(); i++ ) { // For all required inputs 1.163 + if( i == TypeFunc::Parms ) tty->print("returns"); 1.164 + if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx); 1.165 + else tty->print("_ "); 1.166 + } 1.167 +} 1.168 +#endif 1.169 + 1.170 +//============================================================================= 1.171 +RethrowNode::RethrowNode( 1.172 + Node* cntrl, 1.173 + Node* i_o, 1.174 + Node* memory, 1.175 + Node* frameptr, 1.176 + Node* ret_adr, 1.177 + Node* exception 1.178 +) : Node(TypeFunc::Parms + 1) { 1.179 + init_req(TypeFunc::Control , cntrl ); 1.180 + init_req(TypeFunc::I_O , i_o ); 1.181 + init_req(TypeFunc::Memory , memory ); 1.182 + init_req(TypeFunc::FramePtr , frameptr ); 1.183 + init_req(TypeFunc::ReturnAdr, ret_adr); 1.184 + init_req(TypeFunc::Parms , exception); 1.185 +} 1.186 + 1.187 +Node *RethrowNode::Ideal(PhaseGVN *phase, bool can_reshape){ 1.188 + return remove_dead_region(phase, can_reshape) ? this : NULL; 1.189 +} 1.190 + 1.191 +const Type *RethrowNode::Value( PhaseTransform *phase ) const { 1.192 + return (phase->type(in(TypeFunc::Control)) == Type::TOP) 1.193 + ? Type::TOP 1.194 + : Type::BOTTOM; 1.195 +} 1.196 + 1.197 +uint RethrowNode::match_edge(uint idx) const { 1.198 + return 0; 1.199 +} 1.200 + 1.201 +#ifndef PRODUCT 1.202 +void RethrowNode::dump_req() const { 1.203 + // Dump the required inputs, enclosed in '(' and ')' 1.204 + uint i; // Exit value of loop 1.205 + for( i=0; i<req(); i++ ) { // For all required inputs 1.206 + if( i == TypeFunc::Parms ) tty->print("exception"); 1.207 + if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx); 1.208 + else tty->print("_ "); 1.209 + } 1.210 +} 1.211 +#endif 1.212 + 1.213 +//============================================================================= 1.214 +// Do we Match on this edge index or not? Match only target address & method 1.215 +uint TailCallNode::match_edge(uint idx) const { 1.216 + return TypeFunc::Parms <= idx && idx <= TypeFunc::Parms+1; 1.217 +} 1.218 + 1.219 +//============================================================================= 1.220 +// Do we Match on this edge index or not? Match only target address & oop 1.221 +uint TailJumpNode::match_edge(uint idx) const { 1.222 + return TypeFunc::Parms <= idx && idx <= TypeFunc::Parms+1; 1.223 +} 1.224 + 1.225 +//============================================================================= 1.226 +JVMState::JVMState(ciMethod* method, JVMState* caller) { 1.227 + assert(method != NULL, "must be valid call site"); 1.228 + _method = method; 1.229 + debug_only(_bci = -99); // random garbage value 1.230 + debug_only(_map = (SafePointNode*)-1); 1.231 + _caller = caller; 1.232 + _depth = 1 + (caller == NULL ? 0 : caller->depth()); 1.233 + _locoff = TypeFunc::Parms; 1.234 + _stkoff = _locoff + _method->max_locals(); 1.235 + _monoff = _stkoff + _method->max_stack(); 1.236 + _endoff = _monoff; 1.237 + _sp = 0; 1.238 +} 1.239 +JVMState::JVMState(int stack_size) { 1.240 + _method = NULL; 1.241 + _bci = InvocationEntryBci; 1.242 + debug_only(_map = (SafePointNode*)-1); 1.243 + _caller = NULL; 1.244 + _depth = 1; 1.245 + _locoff = TypeFunc::Parms; 1.246 + _stkoff = _locoff; 1.247 + _monoff = _stkoff + stack_size; 1.248 + _endoff = _monoff; 1.249 + _sp = 0; 1.250 +} 1.251 + 1.252 +//--------------------------------of_depth------------------------------------- 1.253 +JVMState* JVMState::of_depth(int d) const { 1.254 + const JVMState* jvmp = this; 1.255 + assert(0 < d && (uint)d <= depth(), "oob"); 1.256 + for (int skip = depth() - d; skip > 0; skip--) { 1.257 + jvmp = jvmp->caller(); 1.258 + } 1.259 + assert(jvmp->depth() == (uint)d, "found the right one"); 1.260 + return (JVMState*)jvmp; 1.261 +} 1.262 + 1.263 +//-----------------------------same_calls_as----------------------------------- 1.264 +bool JVMState::same_calls_as(const JVMState* that) const { 1.265 + if (this == that) return true; 1.266 + if (this->depth() != that->depth()) return false; 1.267 + const JVMState* p = this; 1.268 + const JVMState* q = that; 1.269 + for (;;) { 1.270 + if (p->_method != q->_method) return false; 1.271 + if (p->_method == NULL) return true; // bci is irrelevant 1.272 + if (p->_bci != q->_bci) return false; 1.273 + p = p->caller(); 1.274 + q = q->caller(); 1.275 + if (p == q) return true; 1.276 + assert(p != NULL && q != NULL, "depth check ensures we don't run off end"); 1.277 + } 1.278 +} 1.279 + 1.280 +//------------------------------debug_start------------------------------------ 1.281 +uint JVMState::debug_start() const { 1.282 + debug_only(JVMState* jvmroot = of_depth(1)); 1.283 + assert(jvmroot->locoff() <= this->locoff(), "youngest JVMState must be last"); 1.284 + return of_depth(1)->locoff(); 1.285 +} 1.286 + 1.287 +//-------------------------------debug_end------------------------------------- 1.288 +uint JVMState::debug_end() const { 1.289 + debug_only(JVMState* jvmroot = of_depth(1)); 1.290 + assert(jvmroot->endoff() <= this->endoff(), "youngest JVMState must be last"); 1.291 + return endoff(); 1.292 +} 1.293 + 1.294 +//------------------------------debug_depth------------------------------------ 1.295 +uint JVMState::debug_depth() const { 1.296 + uint total = 0; 1.297 + for (const JVMState* jvmp = this; jvmp != NULL; jvmp = jvmp->caller()) { 1.298 + total += jvmp->debug_size(); 1.299 + } 1.300 + return total; 1.301 +} 1.302 + 1.303 +//------------------------------format_helper---------------------------------- 1.304 +// Given an allocation (a Chaitin object) and a Node decide if the Node carries 1.305 +// any defined value or not. If it does, print out the register or constant. 1.306 +#ifndef PRODUCT 1.307 +static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i ) { 1.308 + if (n == NULL) { st->print(" NULL"); return; } 1.309 + if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined 1.310 + char buf[50]; 1.311 + regalloc->dump_register(n,buf); 1.312 + st->print(" %s%d]=%s",msg,i,buf); 1.313 + } else { // No register, but might be constant 1.314 + const Type *t = n->bottom_type(); 1.315 + switch (t->base()) { 1.316 + case Type::Int: 1.317 + st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con()); 1.318 + break; 1.319 + case Type::AnyPtr: 1.320 + assert( t == TypePtr::NULL_PTR, "" ); 1.321 + st->print(" %s%d]=#NULL",msg,i); 1.322 + break; 1.323 + case Type::AryPtr: 1.324 + case Type::KlassPtr: 1.325 + case Type::InstPtr: 1.326 + st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop()); 1.327 + break; 1.328 + case Type::RawPtr: 1.329 + st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr()); 1.330 + break; 1.331 + case Type::DoubleCon: 1.332 + st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d); 1.333 + break; 1.334 + case Type::FloatCon: 1.335 + st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f); 1.336 + break; 1.337 + case Type::Long: 1.338 + st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con()); 1.339 + break; 1.340 + case Type::Half: 1.341 + case Type::Top: 1.342 + st->print(" %s%d]=_",msg,i); 1.343 + break; 1.344 + default: ShouldNotReachHere(); 1.345 + } 1.346 + } 1.347 +} 1.348 +#endif 1.349 + 1.350 +//------------------------------format----------------------------------------- 1.351 +#ifndef PRODUCT 1.352 +void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const { 1.353 + st->print(" #"); 1.354 + if( _method ) { 1.355 + _method->print_short_name(st); 1.356 + st->print(" @ bci:%d ",_bci); 1.357 + } else { 1.358 + st->print_cr(" runtime stub "); 1.359 + return; 1.360 + } 1.361 + if (n->is_MachSafePoint()) { 1.362 + MachSafePointNode *mcall = n->as_MachSafePoint(); 1.363 + uint i; 1.364 + // Print locals 1.365 + for( i = 0; i < (uint)loc_size(); i++ ) 1.366 + format_helper( regalloc, st, mcall->local(this, i), "L[", i ); 1.367 + // Print stack 1.368 + for (i = 0; i < (uint)stk_size(); i++) { 1.369 + if ((uint)(_stkoff + i) >= mcall->len()) 1.370 + st->print(" oob "); 1.371 + else 1.372 + format_helper( regalloc, st, mcall->stack(this, i), "STK[", i ); 1.373 + } 1.374 + for (i = 0; (int)i < nof_monitors(); i++) { 1.375 + Node *box = mcall->monitor_box(this, i); 1.376 + Node *obj = mcall->monitor_obj(this, i); 1.377 + if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) { 1.378 + while( !box->is_BoxLock() ) box = box->in(1); 1.379 + format_helper( regalloc, st, box, "MON-BOX[", i ); 1.380 + } else { 1.381 + OptoReg::Name box_reg = BoxLockNode::stack_slot(box); 1.382 + st->print(" MON-BOX%d=%s+%d", 1.383 + i, 1.384 + OptoReg::regname(OptoReg::c_frame_pointer), 1.385 + regalloc->reg2offset(box_reg)); 1.386 + } 1.387 + format_helper( regalloc, st, obj, "MON-OBJ[", i ); 1.388 + } 1.389 + } 1.390 + st->print_cr(""); 1.391 + if (caller() != NULL) caller()->format(regalloc, n, st); 1.392 +} 1.393 +#endif 1.394 + 1.395 +#ifndef PRODUCT 1.396 +void JVMState::dump_spec(outputStream *st) const { 1.397 + if (_method != NULL) { 1.398 + bool printed = false; 1.399 + if (!Verbose) { 1.400 + // The JVMS dumps make really, really long lines. 1.401 + // Take out the most boring parts, which are the package prefixes. 1.402 + char buf[500]; 1.403 + stringStream namest(buf, sizeof(buf)); 1.404 + _method->print_short_name(&namest); 1.405 + if (namest.count() < sizeof(buf)) { 1.406 + const char* name = namest.base(); 1.407 + if (name[0] == ' ') ++name; 1.408 + const char* endcn = strchr(name, ':'); // end of class name 1.409 + if (endcn == NULL) endcn = strchr(name, '('); 1.410 + if (endcn == NULL) endcn = name + strlen(name); 1.411 + while (endcn > name && endcn[-1] != '.' && endcn[-1] != '/') 1.412 + --endcn; 1.413 + st->print(" %s", endcn); 1.414 + printed = true; 1.415 + } 1.416 + } 1.417 + if (!printed) 1.418 + _method->print_short_name(st); 1.419 + st->print(" @ bci:%d",_bci); 1.420 + } else { 1.421 + st->print(" runtime stub"); 1.422 + } 1.423 + if (caller() != NULL) caller()->dump_spec(st); 1.424 +} 1.425 +#endif 1.426 + 1.427 +#ifndef PRODUCT 1.428 +void JVMState::dump_on(outputStream* st) const { 1.429 + if (_map && !((uintptr_t)_map & 1)) { 1.430 + if (_map->len() > _map->req()) { // _map->has_exceptions() 1.431 + Node* ex = _map->in(_map->req()); // _map->next_exception() 1.432 + // skip the first one; it's already being printed 1.433 + while (ex != NULL && ex->len() > ex->req()) { 1.434 + ex = ex->in(ex->req()); // ex->next_exception() 1.435 + ex->dump(1); 1.436 + } 1.437 + } 1.438 + _map->dump(2); 1.439 + } 1.440 + st->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=", 1.441 + depth(), locoff(), stkoff(), monoff(), endoff(), monitor_depth(), sp(), bci()); 1.442 + if (_method == NULL) { 1.443 + st->print_cr("(none)"); 1.444 + } else { 1.445 + _method->print_name(st); 1.446 + st->cr(); 1.447 + if (bci() >= 0 && bci() < _method->code_size()) { 1.448 + st->print(" bc: "); 1.449 + _method->print_codes_on(bci(), bci()+1, st); 1.450 + } 1.451 + } 1.452 + if (caller() != NULL) { 1.453 + caller()->dump_on(st); 1.454 + } 1.455 +} 1.456 + 1.457 +// Extra way to dump a jvms from the debugger, 1.458 +// to avoid a bug with C++ member function calls. 1.459 +void dump_jvms(JVMState* jvms) { 1.460 + jvms->dump(); 1.461 +} 1.462 +#endif 1.463 + 1.464 +//--------------------------clone_shallow-------------------------------------- 1.465 +JVMState* JVMState::clone_shallow(Compile* C) const { 1.466 + JVMState* n = has_method() ? new (C) JVMState(_method, _caller) : new (C) JVMState(0); 1.467 + n->set_bci(_bci); 1.468 + n->set_locoff(_locoff); 1.469 + n->set_stkoff(_stkoff); 1.470 + n->set_monoff(_monoff); 1.471 + n->set_endoff(_endoff); 1.472 + n->set_sp(_sp); 1.473 + n->set_map(_map); 1.474 + return n; 1.475 +} 1.476 + 1.477 +//---------------------------clone_deep---------------------------------------- 1.478 +JVMState* JVMState::clone_deep(Compile* C) const { 1.479 + JVMState* n = clone_shallow(C); 1.480 + for (JVMState* p = n; p->_caller != NULL; p = p->_caller) { 1.481 + p->_caller = p->_caller->clone_shallow(C); 1.482 + } 1.483 + assert(n->depth() == depth(), "sanity"); 1.484 + assert(n->debug_depth() == debug_depth(), "sanity"); 1.485 + return n; 1.486 +} 1.487 + 1.488 +//============================================================================= 1.489 +uint CallNode::cmp( const Node &n ) const 1.490 +{ return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; } 1.491 +#ifndef PRODUCT 1.492 +void CallNode::dump_req() const { 1.493 + // Dump the required inputs, enclosed in '(' and ')' 1.494 + uint i; // Exit value of loop 1.495 + for( i=0; i<req(); i++ ) { // For all required inputs 1.496 + if( i == TypeFunc::Parms ) tty->print("("); 1.497 + if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx); 1.498 + else tty->print("_ "); 1.499 + } 1.500 + tty->print(")"); 1.501 +} 1.502 + 1.503 +void CallNode::dump_spec(outputStream *st) const { 1.504 + st->print(" "); 1.505 + tf()->dump_on(st); 1.506 + if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); 1.507 + if (jvms() != NULL) jvms()->dump_spec(st); 1.508 +} 1.509 +#endif 1.510 + 1.511 +const Type *CallNode::bottom_type() const { return tf()->range(); } 1.512 +const Type *CallNode::Value(PhaseTransform *phase) const { 1.513 + if (phase->type(in(0)) == Type::TOP) return Type::TOP; 1.514 + return tf()->range(); 1.515 +} 1.516 + 1.517 +//------------------------------calling_convention----------------------------- 1.518 +void CallNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { 1.519 + // Use the standard compiler calling convention 1.520 + Matcher::calling_convention( sig_bt, parm_regs, argcnt, true ); 1.521 +} 1.522 + 1.523 + 1.524 +//------------------------------match------------------------------------------ 1.525 +// Construct projections for control, I/O, memory-fields, ..., and 1.526 +// return result(s) along with their RegMask info 1.527 +Node *CallNode::match( const ProjNode *proj, const Matcher *match ) { 1.528 + switch (proj->_con) { 1.529 + case TypeFunc::Control: 1.530 + case TypeFunc::I_O: 1.531 + case TypeFunc::Memory: 1.532 + return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); 1.533 + 1.534 + case TypeFunc::Parms+1: // For LONG & DOUBLE returns 1.535 + assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, ""); 1.536 + // 2nd half of doubles and longs 1.537 + return new (match->C, 1) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad); 1.538 + 1.539 + case TypeFunc::Parms: { // Normal returns 1.540 + uint ideal_reg = Matcher::base2reg[tf()->range()->field_at(TypeFunc::Parms)->base()]; 1.541 + OptoRegPair regs = is_CallRuntime() 1.542 + ? match->c_return_value(ideal_reg,true) // Calls into C runtime 1.543 + : match-> return_value(ideal_reg,true); // Calls into compiled Java code 1.544 + RegMask rm = RegMask(regs.first()); 1.545 + if( OptoReg::is_valid(regs.second()) ) 1.546 + rm.Insert( regs.second() ); 1.547 + return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg); 1.548 + } 1.549 + 1.550 + case TypeFunc::ReturnAdr: 1.551 + case TypeFunc::FramePtr: 1.552 + default: 1.553 + ShouldNotReachHere(); 1.554 + } 1.555 + return NULL; 1.556 +} 1.557 + 1.558 +// Do we Match on this edge index or not? Match no edges 1.559 +uint CallNode::match_edge(uint idx) const { 1.560 + return 0; 1.561 +} 1.562 + 1.563 +//============================================================================= 1.564 +uint CallJavaNode::size_of() const { return sizeof(*this); } 1.565 +uint CallJavaNode::cmp( const Node &n ) const { 1.566 + CallJavaNode &call = (CallJavaNode&)n; 1.567 + return CallNode::cmp(call) && _method == call._method; 1.568 +} 1.569 +#ifndef PRODUCT 1.570 +void CallJavaNode::dump_spec(outputStream *st) const { 1.571 + if( _method ) _method->print_short_name(st); 1.572 + CallNode::dump_spec(st); 1.573 +} 1.574 +#endif 1.575 + 1.576 +//============================================================================= 1.577 +uint CallStaticJavaNode::size_of() const { return sizeof(*this); } 1.578 +uint CallStaticJavaNode::cmp( const Node &n ) const { 1.579 + CallStaticJavaNode &call = (CallStaticJavaNode&)n; 1.580 + return CallJavaNode::cmp(call); 1.581 +} 1.582 + 1.583 +//----------------------------uncommon_trap_request---------------------------- 1.584 +// If this is an uncommon trap, return the request code, else zero. 1.585 +int CallStaticJavaNode::uncommon_trap_request() const { 1.586 + if (_name != NULL && !strcmp(_name, "uncommon_trap")) { 1.587 + return extract_uncommon_trap_request(this); 1.588 + } 1.589 + return 0; 1.590 +} 1.591 +int CallStaticJavaNode::extract_uncommon_trap_request(const Node* call) { 1.592 +#ifndef PRODUCT 1.593 + if (!(call->req() > TypeFunc::Parms && 1.594 + call->in(TypeFunc::Parms) != NULL && 1.595 + call->in(TypeFunc::Parms)->is_Con())) { 1.596 + assert(_in_dump_cnt != 0, "OK if dumping"); 1.597 + tty->print("[bad uncommon trap]"); 1.598 + return 0; 1.599 + } 1.600 +#endif 1.601 + return call->in(TypeFunc::Parms)->bottom_type()->is_int()->get_con(); 1.602 +} 1.603 + 1.604 +#ifndef PRODUCT 1.605 +void CallStaticJavaNode::dump_spec(outputStream *st) const { 1.606 + st->print("# Static "); 1.607 + if (_name != NULL) { 1.608 + st->print("%s", _name); 1.609 + int trap_req = uncommon_trap_request(); 1.610 + if (trap_req != 0) { 1.611 + char buf[100]; 1.612 + st->print("(%s)", 1.613 + Deoptimization::format_trap_request(buf, sizeof(buf), 1.614 + trap_req)); 1.615 + } 1.616 + st->print(" "); 1.617 + } 1.618 + CallJavaNode::dump_spec(st); 1.619 +} 1.620 +#endif 1.621 + 1.622 +//============================================================================= 1.623 +uint CallDynamicJavaNode::size_of() const { return sizeof(*this); } 1.624 +uint CallDynamicJavaNode::cmp( const Node &n ) const { 1.625 + CallDynamicJavaNode &call = (CallDynamicJavaNode&)n; 1.626 + return CallJavaNode::cmp(call); 1.627 +} 1.628 +#ifndef PRODUCT 1.629 +void CallDynamicJavaNode::dump_spec(outputStream *st) const { 1.630 + st->print("# Dynamic "); 1.631 + CallJavaNode::dump_spec(st); 1.632 +} 1.633 +#endif 1.634 + 1.635 +//============================================================================= 1.636 +uint CallRuntimeNode::size_of() const { return sizeof(*this); } 1.637 +uint CallRuntimeNode::cmp( const Node &n ) const { 1.638 + CallRuntimeNode &call = (CallRuntimeNode&)n; 1.639 + return CallNode::cmp(call) && !strcmp(_name,call._name); 1.640 +} 1.641 +#ifndef PRODUCT 1.642 +void CallRuntimeNode::dump_spec(outputStream *st) const { 1.643 + st->print("# "); 1.644 + st->print(_name); 1.645 + CallNode::dump_spec(st); 1.646 +} 1.647 +#endif 1.648 + 1.649 +//------------------------------calling_convention----------------------------- 1.650 +void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { 1.651 + Matcher::c_calling_convention( sig_bt, parm_regs, argcnt ); 1.652 +} 1.653 + 1.654 +//============================================================================= 1.655 +//------------------------------calling_convention----------------------------- 1.656 + 1.657 + 1.658 +//============================================================================= 1.659 +#ifndef PRODUCT 1.660 +void CallLeafNode::dump_spec(outputStream *st) const { 1.661 + st->print("# "); 1.662 + st->print(_name); 1.663 + CallNode::dump_spec(st); 1.664 +} 1.665 +#endif 1.666 + 1.667 +//============================================================================= 1.668 + 1.669 +void SafePointNode::set_local(JVMState* jvms, uint idx, Node *c) { 1.670 + assert(verify_jvms(jvms), "jvms must match"); 1.671 + int loc = jvms->locoff() + idx; 1.672 + if (in(loc)->is_top() && idx > 0 && !c->is_top() ) { 1.673 + // If current local idx is top then local idx - 1 could 1.674 + // be a long/double that needs to be killed since top could 1.675 + // represent the 2nd half ofthe long/double. 1.676 + uint ideal = in(loc -1)->ideal_reg(); 1.677 + if (ideal == Op_RegD || ideal == Op_RegL) { 1.678 + // set other (low index) half to top 1.679 + set_req(loc - 1, in(loc)); 1.680 + } 1.681 + } 1.682 + set_req(loc, c); 1.683 +} 1.684 + 1.685 +uint SafePointNode::size_of() const { return sizeof(*this); } 1.686 +uint SafePointNode::cmp( const Node &n ) const { 1.687 + return (&n == this); // Always fail except on self 1.688 +} 1.689 + 1.690 +//-------------------------set_next_exception---------------------------------- 1.691 +void SafePointNode::set_next_exception(SafePointNode* n) { 1.692 + assert(n == NULL || n->Opcode() == Op_SafePoint, "correct value for next_exception"); 1.693 + if (len() == req()) { 1.694 + if (n != NULL) add_prec(n); 1.695 + } else { 1.696 + set_prec(req(), n); 1.697 + } 1.698 +} 1.699 + 1.700 + 1.701 +//----------------------------next_exception----------------------------------- 1.702 +SafePointNode* SafePointNode::next_exception() const { 1.703 + if (len() == req()) { 1.704 + return NULL; 1.705 + } else { 1.706 + Node* n = in(req()); 1.707 + assert(n == NULL || n->Opcode() == Op_SafePoint, "no other uses of prec edges"); 1.708 + return (SafePointNode*) n; 1.709 + } 1.710 +} 1.711 + 1.712 + 1.713 +//------------------------------Ideal------------------------------------------ 1.714 +// Skip over any collapsed Regions 1.715 +Node *SafePointNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.716 + if (remove_dead_region(phase, can_reshape)) return this; 1.717 + 1.718 + return NULL; 1.719 +} 1.720 + 1.721 +//------------------------------Identity--------------------------------------- 1.722 +// Remove obviously duplicate safepoints 1.723 +Node *SafePointNode::Identity( PhaseTransform *phase ) { 1.724 + 1.725 + // If you have back to back safepoints, remove one 1.726 + if( in(TypeFunc::Control)->is_SafePoint() ) 1.727 + return in(TypeFunc::Control); 1.728 + 1.729 + if( in(0)->is_Proj() ) { 1.730 + Node *n0 = in(0)->in(0); 1.731 + // Check if he is a call projection (except Leaf Call) 1.732 + if( n0->is_Catch() ) { 1.733 + n0 = n0->in(0)->in(0); 1.734 + assert( n0->is_Call(), "expect a call here" ); 1.735 + } 1.736 + if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) { 1.737 + // Useless Safepoint, so remove it 1.738 + return in(TypeFunc::Control); 1.739 + } 1.740 + } 1.741 + 1.742 + return this; 1.743 +} 1.744 + 1.745 +//------------------------------Value------------------------------------------ 1.746 +const Type *SafePointNode::Value( PhaseTransform *phase ) const { 1.747 + if( phase->type(in(0)) == Type::TOP ) return Type::TOP; 1.748 + if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop 1.749 + return Type::CONTROL; 1.750 +} 1.751 + 1.752 +#ifndef PRODUCT 1.753 +void SafePointNode::dump_spec(outputStream *st) const { 1.754 + st->print(" SafePoint "); 1.755 +} 1.756 +#endif 1.757 + 1.758 +const RegMask &SafePointNode::in_RegMask(uint idx) const { 1.759 + if( idx < TypeFunc::Parms ) return RegMask::Empty; 1.760 + // Values outside the domain represent debug info 1.761 + return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]); 1.762 +} 1.763 +const RegMask &SafePointNode::out_RegMask() const { 1.764 + return RegMask::Empty; 1.765 +} 1.766 + 1.767 + 1.768 +void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { 1.769 + assert((int)grow_by > 0, "sanity"); 1.770 + int monoff = jvms->monoff(); 1.771 + int endoff = jvms->endoff(); 1.772 + assert(endoff == (int)req(), "no other states or debug info after me"); 1.773 + Node* top = Compile::current()->top(); 1.774 + for (uint i = 0; i < grow_by; i++) { 1.775 + ins_req(monoff, top); 1.776 + } 1.777 + jvms->set_monoff(monoff + grow_by); 1.778 + jvms->set_endoff(endoff + grow_by); 1.779 +} 1.780 + 1.781 +void SafePointNode::push_monitor(const FastLockNode *lock) { 1.782 + // Add a LockNode, which points to both the original BoxLockNode (the 1.783 + // stack space for the monitor) and the Object being locked. 1.784 + const int MonitorEdges = 2; 1.785 + assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); 1.786 + assert(req() == jvms()->endoff(), "correct sizing"); 1.787 + if (GenerateSynchronizationCode) { 1.788 + add_req(lock->box_node()); 1.789 + add_req(lock->obj_node()); 1.790 + } else { 1.791 + add_req(NULL); 1.792 + add_req(NULL); 1.793 + } 1.794 + jvms()->set_endoff(req()); 1.795 +} 1.796 + 1.797 +void SafePointNode::pop_monitor() { 1.798 + // Delete last monitor from debug info 1.799 + debug_only(int num_before_pop = jvms()->nof_monitors()); 1.800 + const int MonitorEdges = (1<<JVMState::logMonitorEdges); 1.801 + int endoff = jvms()->endoff(); 1.802 + int new_endoff = endoff - MonitorEdges; 1.803 + jvms()->set_endoff(new_endoff); 1.804 + while (endoff > new_endoff) del_req(--endoff); 1.805 + assert(jvms()->nof_monitors() == num_before_pop-1, ""); 1.806 +} 1.807 + 1.808 +Node *SafePointNode::peek_monitor_box() const { 1.809 + int mon = jvms()->nof_monitors() - 1; 1.810 + assert(mon >= 0, "most have a monitor"); 1.811 + return monitor_box(jvms(), mon); 1.812 +} 1.813 + 1.814 +Node *SafePointNode::peek_monitor_obj() const { 1.815 + int mon = jvms()->nof_monitors() - 1; 1.816 + assert(mon >= 0, "most have a monitor"); 1.817 + return monitor_obj(jvms(), mon); 1.818 +} 1.819 + 1.820 +// Do we Match on this edge index or not? Match no edges 1.821 +uint SafePointNode::match_edge(uint idx) const { 1.822 + if( !needs_polling_address_input() ) 1.823 + return 0; 1.824 + 1.825 + return (TypeFunc::Parms == idx); 1.826 +} 1.827 + 1.828 +//============================================================================= 1.829 +uint AllocateNode::size_of() const { return sizeof(*this); } 1.830 + 1.831 +AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype, 1.832 + Node *ctrl, Node *mem, Node *abio, 1.833 + Node *size, Node *klass_node, Node *initial_test) 1.834 + : CallNode(atype, NULL, TypeRawPtr::BOTTOM) 1.835 +{ 1.836 + init_class_id(Class_Allocate); 1.837 + init_flags(Flag_is_macro); 1.838 + Node *topnode = C->top(); 1.839 + 1.840 + init_req( TypeFunc::Control , ctrl ); 1.841 + init_req( TypeFunc::I_O , abio ); 1.842 + init_req( TypeFunc::Memory , mem ); 1.843 + init_req( TypeFunc::ReturnAdr, topnode ); 1.844 + init_req( TypeFunc::FramePtr , topnode ); 1.845 + init_req( AllocSize , size); 1.846 + init_req( KlassNode , klass_node); 1.847 + init_req( InitialTest , initial_test); 1.848 + init_req( ALength , topnode); 1.849 + C->add_macro_node(this); 1.850 +} 1.851 + 1.852 +//============================================================================= 1.853 +uint AllocateArrayNode::size_of() const { return sizeof(*this); } 1.854 + 1.855 +//============================================================================= 1.856 +uint LockNode::size_of() const { return sizeof(*this); } 1.857 + 1.858 +// Redundant lock elimination 1.859 +// 1.860 +// There are various patterns of locking where we release and 1.861 +// immediately reacquire a lock in a piece of code where no operations 1.862 +// occur in between that would be observable. In those cases we can 1.863 +// skip releasing and reacquiring the lock without violating any 1.864 +// fairness requirements. Doing this around a loop could cause a lock 1.865 +// to be held for a very long time so we concentrate on non-looping 1.866 +// control flow. We also require that the operations are fully 1.867 +// redundant meaning that we don't introduce new lock operations on 1.868 +// some paths so to be able to eliminate it on others ala PRE. This 1.869 +// would probably require some more extensive graph manipulation to 1.870 +// guarantee that the memory edges were all handled correctly. 1.871 +// 1.872 +// Assuming p is a simple predicate which can't trap in any way and s 1.873 +// is a synchronized method consider this code: 1.874 +// 1.875 +// s(); 1.876 +// if (p) 1.877 +// s(); 1.878 +// else 1.879 +// s(); 1.880 +// s(); 1.881 +// 1.882 +// 1. The unlocks of the first call to s can be eliminated if the 1.883 +// locks inside the then and else branches are eliminated. 1.884 +// 1.885 +// 2. The unlocks of the then and else branches can be eliminated if 1.886 +// the lock of the final call to s is eliminated. 1.887 +// 1.888 +// Either of these cases subsumes the simple case of sequential control flow 1.889 +// 1.890 +// Addtionally we can eliminate versions without the else case: 1.891 +// 1.892 +// s(); 1.893 +// if (p) 1.894 +// s(); 1.895 +// s(); 1.896 +// 1.897 +// 3. In this case we eliminate the unlock of the first s, the lock 1.898 +// and unlock in the then case and the lock in the final s. 1.899 +// 1.900 +// Note also that in all these cases the then/else pieces don't have 1.901 +// to be trivial as long as they begin and end with synchronization 1.902 +// operations. 1.903 +// 1.904 +// s(); 1.905 +// if (p) 1.906 +// s(); 1.907 +// f(); 1.908 +// s(); 1.909 +// s(); 1.910 +// 1.911 +// The code will work properly for this case, leaving in the unlock 1.912 +// before the call to f and the relock after it. 1.913 +// 1.914 +// A potentially interesting case which isn't handled here is when the 1.915 +// locking is partially redundant. 1.916 +// 1.917 +// s(); 1.918 +// if (p) 1.919 +// s(); 1.920 +// 1.921 +// This could be eliminated putting unlocking on the else case and 1.922 +// eliminating the first unlock and the lock in the then side. 1.923 +// Alternatively the unlock could be moved out of the then side so it 1.924 +// was after the merge and the first unlock and second lock 1.925 +// eliminated. This might require less manipulation of the memory 1.926 +// state to get correct. 1.927 +// 1.928 +// Additionally we might allow work between a unlock and lock before 1.929 +// giving up eliminating the locks. The current code disallows any 1.930 +// conditional control flow between these operations. A formulation 1.931 +// similar to partial redundancy elimination computing the 1.932 +// availability of unlocking and the anticipatability of locking at a 1.933 +// program point would allow detection of fully redundant locking with 1.934 +// some amount of work in between. I'm not sure how often I really 1.935 +// think that would occur though. Most of the cases I've seen 1.936 +// indicate it's likely non-trivial work would occur in between. 1.937 +// There may be other more complicated constructs where we could 1.938 +// eliminate locking but I haven't seen any others appear as hot or 1.939 +// interesting. 1.940 +// 1.941 +// Locking and unlocking have a canonical form in ideal that looks 1.942 +// roughly like this: 1.943 +// 1.944 +// <obj> 1.945 +// | \\------+ 1.946 +// | \ \ 1.947 +// | BoxLock \ 1.948 +// | | | \ 1.949 +// | | \ \ 1.950 +// | | FastLock 1.951 +// | | / 1.952 +// | | / 1.953 +// | | | 1.954 +// 1.955 +// Lock 1.956 +// | 1.957 +// Proj #0 1.958 +// | 1.959 +// MembarAcquire 1.960 +// | 1.961 +// Proj #0 1.962 +// 1.963 +// MembarRelease 1.964 +// | 1.965 +// Proj #0 1.966 +// | 1.967 +// Unlock 1.968 +// | 1.969 +// Proj #0 1.970 +// 1.971 +// 1.972 +// This code proceeds by processing Lock nodes during PhaseIterGVN 1.973 +// and searching back through its control for the proper code 1.974 +// patterns. Once it finds a set of lock and unlock operations to 1.975 +// eliminate they are marked as eliminatable which causes the 1.976 +// expansion of the Lock and Unlock macro nodes to make the operation a NOP 1.977 +// 1.978 +//============================================================================= 1.979 + 1.980 +// 1.981 +// Utility function to skip over uninteresting control nodes. Nodes skipped are: 1.982 +// - copy regions. (These may not have been optimized away yet.) 1.983 +// - eliminated locking nodes 1.984 +// 1.985 +static Node *next_control(Node *ctrl) { 1.986 + if (ctrl == NULL) 1.987 + return NULL; 1.988 + while (1) { 1.989 + if (ctrl->is_Region()) { 1.990 + RegionNode *r = ctrl->as_Region(); 1.991 + Node *n = r->is_copy(); 1.992 + if (n == NULL) 1.993 + break; // hit a region, return it 1.994 + else 1.995 + ctrl = n; 1.996 + } else if (ctrl->is_Proj()) { 1.997 + Node *in0 = ctrl->in(0); 1.998 + if (in0->is_AbstractLock() && in0->as_AbstractLock()->is_eliminated()) { 1.999 + ctrl = in0->in(0); 1.1000 + } else { 1.1001 + break; 1.1002 + } 1.1003 + } else { 1.1004 + break; // found an interesting control 1.1005 + } 1.1006 + } 1.1007 + return ctrl; 1.1008 +} 1.1009 +// 1.1010 +// Given a control, see if it's the control projection of an Unlock which 1.1011 +// operating on the same object as lock. 1.1012 +// 1.1013 +bool AbstractLockNode::find_matching_unlock(const Node* ctrl, LockNode* lock, 1.1014 + GrowableArray<AbstractLockNode*> &lock_ops) { 1.1015 + ProjNode *ctrl_proj = (ctrl->is_Proj()) ? ctrl->as_Proj() : NULL; 1.1016 + if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) { 1.1017 + Node *n = ctrl_proj->in(0); 1.1018 + if (n != NULL && n->is_Unlock()) { 1.1019 + UnlockNode *unlock = n->as_Unlock(); 1.1020 + if ((lock->obj_node() == unlock->obj_node()) && 1.1021 + (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) { 1.1022 + lock_ops.append(unlock); 1.1023 + return true; 1.1024 + } 1.1025 + } 1.1026 + } 1.1027 + return false; 1.1028 +} 1.1029 + 1.1030 +// 1.1031 +// Find the lock matching an unlock. Returns null if a safepoint 1.1032 +// or complicated control is encountered first. 1.1033 +LockNode *AbstractLockNode::find_matching_lock(UnlockNode* unlock) { 1.1034 + LockNode *lock_result = NULL; 1.1035 + // find the matching lock, or an intervening safepoint 1.1036 + Node *ctrl = next_control(unlock->in(0)); 1.1037 + while (1) { 1.1038 + assert(ctrl != NULL, "invalid control graph"); 1.1039 + assert(!ctrl->is_Start(), "missing lock for unlock"); 1.1040 + if (ctrl->is_top()) break; // dead control path 1.1041 + if (ctrl->is_Proj()) ctrl = ctrl->in(0); 1.1042 + if (ctrl->is_SafePoint()) { 1.1043 + break; // found a safepoint (may be the lock we are searching for) 1.1044 + } else if (ctrl->is_Region()) { 1.1045 + // Check for a simple diamond pattern. Punt on anything more complicated 1.1046 + if (ctrl->req() == 3 && ctrl->in(1) != NULL && ctrl->in(2) != NULL) { 1.1047 + Node *in1 = next_control(ctrl->in(1)); 1.1048 + Node *in2 = next_control(ctrl->in(2)); 1.1049 + if (((in1->is_IfTrue() && in2->is_IfFalse()) || 1.1050 + (in2->is_IfTrue() && in1->is_IfFalse())) && (in1->in(0) == in2->in(0))) { 1.1051 + ctrl = next_control(in1->in(0)->in(0)); 1.1052 + } else { 1.1053 + break; 1.1054 + } 1.1055 + } else { 1.1056 + break; 1.1057 + } 1.1058 + } else { 1.1059 + ctrl = next_control(ctrl->in(0)); // keep searching 1.1060 + } 1.1061 + } 1.1062 + if (ctrl->is_Lock()) { 1.1063 + LockNode *lock = ctrl->as_Lock(); 1.1064 + if ((lock->obj_node() == unlock->obj_node()) && 1.1065 + (lock->box_node() == unlock->box_node())) { 1.1066 + lock_result = lock; 1.1067 + } 1.1068 + } 1.1069 + return lock_result; 1.1070 +} 1.1071 + 1.1072 +// This code corresponds to case 3 above. 1.1073 + 1.1074 +bool AbstractLockNode::find_lock_and_unlock_through_if(Node* node, LockNode* lock, 1.1075 + GrowableArray<AbstractLockNode*> &lock_ops) { 1.1076 + Node* if_node = node->in(0); 1.1077 + bool if_true = node->is_IfTrue(); 1.1078 + 1.1079 + if (if_node->is_If() && if_node->outcnt() == 2 && (if_true || node->is_IfFalse())) { 1.1080 + Node *lock_ctrl = next_control(if_node->in(0)); 1.1081 + if (find_matching_unlock(lock_ctrl, lock, lock_ops)) { 1.1082 + Node* lock1_node = NULL; 1.1083 + ProjNode* proj = if_node->as_If()->proj_out(!if_true); 1.1084 + if (if_true) { 1.1085 + if (proj->is_IfFalse() && proj->outcnt() == 1) { 1.1086 + lock1_node = proj->unique_out(); 1.1087 + } 1.1088 + } else { 1.1089 + if (proj->is_IfTrue() && proj->outcnt() == 1) { 1.1090 + lock1_node = proj->unique_out(); 1.1091 + } 1.1092 + } 1.1093 + if (lock1_node != NULL && lock1_node->is_Lock()) { 1.1094 + LockNode *lock1 = lock1_node->as_Lock(); 1.1095 + if ((lock->obj_node() == lock1->obj_node()) && 1.1096 + (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) { 1.1097 + lock_ops.append(lock1); 1.1098 + return true; 1.1099 + } 1.1100 + } 1.1101 + } 1.1102 + } 1.1103 + 1.1104 + lock_ops.trunc_to(0); 1.1105 + return false; 1.1106 +} 1.1107 + 1.1108 +bool AbstractLockNode::find_unlocks_for_region(const RegionNode* region, LockNode* lock, 1.1109 + GrowableArray<AbstractLockNode*> &lock_ops) { 1.1110 + // check each control merging at this point for a matching unlock. 1.1111 + // in(0) should be self edge so skip it. 1.1112 + for (int i = 1; i < (int)region->req(); i++) { 1.1113 + Node *in_node = next_control(region->in(i)); 1.1114 + if (in_node != NULL) { 1.1115 + if (find_matching_unlock(in_node, lock, lock_ops)) { 1.1116 + // found a match so keep on checking. 1.1117 + continue; 1.1118 + } else if (find_lock_and_unlock_through_if(in_node, lock, lock_ops)) { 1.1119 + continue; 1.1120 + } 1.1121 + 1.1122 + // If we fall through to here then it was some kind of node we 1.1123 + // don't understand or there wasn't a matching unlock, so give 1.1124 + // up trying to merge locks. 1.1125 + lock_ops.trunc_to(0); 1.1126 + return false; 1.1127 + } 1.1128 + } 1.1129 + return true; 1.1130 + 1.1131 +} 1.1132 + 1.1133 +#ifndef PRODUCT 1.1134 +// 1.1135 +// Create a counter which counts the number of times this lock is acquired 1.1136 +// 1.1137 +void AbstractLockNode::create_lock_counter(JVMState* state) { 1.1138 + _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter); 1.1139 +} 1.1140 +#endif 1.1141 + 1.1142 +void AbstractLockNode::set_eliminated() { 1.1143 + _eliminate = true; 1.1144 +#ifndef PRODUCT 1.1145 + if (_counter) { 1.1146 + // Update the counter to indicate that this lock was eliminated. 1.1147 + // The counter update code will stay around even though the 1.1148 + // optimizer will eliminate the lock operation itself. 1.1149 + _counter->set_tag(NamedCounter::EliminatedLockCounter); 1.1150 + } 1.1151 +#endif 1.1152 +} 1.1153 + 1.1154 +//============================================================================= 1.1155 +Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.1156 + 1.1157 + // perform any generic optimizations first 1.1158 + Node *result = SafePointNode::Ideal(phase, can_reshape); 1.1159 + 1.1160 + // Now see if we can optimize away this lock. We don't actually 1.1161 + // remove the locking here, we simply set the _eliminate flag which 1.1162 + // prevents macro expansion from expanding the lock. Since we don't 1.1163 + // modify the graph, the value returned from this function is the 1.1164 + // one computed above. 1.1165 + if (EliminateLocks && !is_eliminated()) { 1.1166 + // 1.1167 + // Try lock coarsening 1.1168 + // 1.1169 + PhaseIterGVN* iter = phase->is_IterGVN(); 1.1170 + if (iter != NULL) { 1.1171 + 1.1172 + GrowableArray<AbstractLockNode*> lock_ops; 1.1173 + 1.1174 + Node *ctrl = next_control(in(0)); 1.1175 + 1.1176 + // now search back for a matching Unlock 1.1177 + if (find_matching_unlock(ctrl, this, lock_ops)) { 1.1178 + // found an unlock directly preceding this lock. This is the 1.1179 + // case of single unlock directly control dependent on a 1.1180 + // single lock which is the trivial version of case 1 or 2. 1.1181 + } else if (ctrl->is_Region() ) { 1.1182 + if (find_unlocks_for_region(ctrl->as_Region(), this, lock_ops)) { 1.1183 + // found lock preceded by multiple unlocks along all paths 1.1184 + // joining at this point which is case 3 in description above. 1.1185 + } 1.1186 + } else { 1.1187 + // see if this lock comes from either half of an if and the 1.1188 + // predecessors merges unlocks and the other half of the if 1.1189 + // performs a lock. 1.1190 + if (find_lock_and_unlock_through_if(ctrl, this, lock_ops)) { 1.1191 + // found unlock splitting to an if with locks on both branches. 1.1192 + } 1.1193 + } 1.1194 + 1.1195 + if (lock_ops.length() > 0) { 1.1196 + // add ourselves to the list of locks to be eliminated. 1.1197 + lock_ops.append(this); 1.1198 + 1.1199 + #ifndef PRODUCT 1.1200 + if (PrintEliminateLocks) { 1.1201 + int locks = 0; 1.1202 + int unlocks = 0; 1.1203 + for (int i = 0; i < lock_ops.length(); i++) { 1.1204 + AbstractLockNode* lock = lock_ops.at(i); 1.1205 + if (lock->Opcode() == Op_Lock) locks++; 1.1206 + else unlocks++; 1.1207 + if (Verbose) { 1.1208 + lock->dump(1); 1.1209 + } 1.1210 + } 1.1211 + tty->print_cr("***Eliminated %d unlocks and %d locks", unlocks, locks); 1.1212 + } 1.1213 + #endif 1.1214 + 1.1215 + // for each of the identified locks, mark them 1.1216 + // as eliminatable 1.1217 + for (int i = 0; i < lock_ops.length(); i++) { 1.1218 + AbstractLockNode* lock = lock_ops.at(i); 1.1219 + 1.1220 + // Mark it eliminated to update any counters 1.1221 + lock->set_eliminated(); 1.1222 + } 1.1223 + } else if (result != NULL && ctrl->is_Region() && 1.1224 + iter->_worklist.member(ctrl)) { 1.1225 + // We weren't able to find any opportunities but the region this 1.1226 + // lock is control dependent on hasn't been processed yet so put 1.1227 + // this lock back on the worklist so we can check again once any 1.1228 + // region simplification has occurred. 1.1229 + iter->_worklist.push(this); 1.1230 + } 1.1231 + } 1.1232 + } 1.1233 + 1.1234 + return result; 1.1235 +} 1.1236 + 1.1237 +//============================================================================= 1.1238 +uint UnlockNode::size_of() const { return sizeof(*this); } 1.1239 + 1.1240 +//============================================================================= 1.1241 +Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.1242 + 1.1243 + // perform any generic optimizations first 1.1244 + Node * result = SafePointNode::Ideal(phase, can_reshape); 1.1245 + 1.1246 + // Now see if we can optimize away this unlock. We don't actually 1.1247 + // remove the unlocking here, we simply set the _eliminate flag which 1.1248 + // prevents macro expansion from expanding the unlock. Since we don't 1.1249 + // modify the graph, the value returned from this function is the 1.1250 + // one computed above. 1.1251 + if (EliminateLocks && !is_eliminated()) { 1.1252 + // 1.1253 + // If we are unlocking an unescaped object, the lock/unlock is unnecessary 1.1254 + // We can eliminate them if there are no safepoints in the locked region. 1.1255 + // 1.1256 + ConnectionGraph *cgr = Compile::current()->congraph(); 1.1257 + if (cgr != NULL && cgr->escape_state(obj_node(), phase) == PointsToNode::NoEscape) { 1.1258 + GrowableArray<AbstractLockNode*> lock_ops; 1.1259 + LockNode *lock = find_matching_lock(this); 1.1260 + if (lock != NULL) { 1.1261 + lock_ops.append(this); 1.1262 + lock_ops.append(lock); 1.1263 + // find other unlocks which pair with the lock we found and add them 1.1264 + // to the list 1.1265 + Node * box = box_node(); 1.1266 + 1.1267 + for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) { 1.1268 + Node *use = box->fast_out(i); 1.1269 + if (use->is_Unlock() && use != this) { 1.1270 + UnlockNode *unlock1 = use->as_Unlock(); 1.1271 + if (!unlock1->is_eliminated()) { 1.1272 + LockNode *lock1 = find_matching_lock(unlock1); 1.1273 + if (lock == lock1) 1.1274 + lock_ops.append(unlock1); 1.1275 + else if (lock1 == NULL) { 1.1276 + // we can't find a matching lock, we must assume the worst 1.1277 + lock_ops.trunc_to(0); 1.1278 + break; 1.1279 + } 1.1280 + } 1.1281 + } 1.1282 + } 1.1283 + if (lock_ops.length() > 0) { 1.1284 + 1.1285 + #ifndef PRODUCT 1.1286 + if (PrintEliminateLocks) { 1.1287 + int locks = 0; 1.1288 + int unlocks = 0; 1.1289 + for (int i = 0; i < lock_ops.length(); i++) { 1.1290 + AbstractLockNode* lock = lock_ops.at(i); 1.1291 + if (lock->Opcode() == Op_Lock) locks++; 1.1292 + else unlocks++; 1.1293 + if (Verbose) { 1.1294 + lock->dump(1); 1.1295 + } 1.1296 + } 1.1297 + tty->print_cr("***Eliminated %d unescaped unlocks and %d unescaped locks", unlocks, locks); 1.1298 + } 1.1299 + #endif 1.1300 + 1.1301 + // for each of the identified locks, mark them 1.1302 + // as eliminatable 1.1303 + for (int i = 0; i < lock_ops.length(); i++) { 1.1304 + AbstractLockNode* lock = lock_ops.at(i); 1.1305 + 1.1306 + // Mark it eliminated to update any counters 1.1307 + lock->set_eliminated(); 1.1308 + } 1.1309 + } 1.1310 + } 1.1311 + } 1.1312 + } 1.1313 + return result; 1.1314 +}