1.1 --- a/src/share/vm/opto/callnode.cpp Thu Mar 13 05:40:44 2008 -0700 1.2 +++ b/src/share/vm/opto/callnode.cpp Thu Mar 13 16:06:34 2008 -0700 1.3 @@ -230,6 +230,7 @@ 1.4 _locoff = TypeFunc::Parms; 1.5 _stkoff = _locoff + _method->max_locals(); 1.6 _monoff = _stkoff + _method->max_stack(); 1.7 + _scloff = _monoff; 1.8 _endoff = _monoff; 1.9 _sp = 0; 1.10 } 1.11 @@ -242,6 +243,7 @@ 1.12 _locoff = TypeFunc::Parms; 1.13 _stkoff = _locoff; 1.14 _monoff = _stkoff + stack_size; 1.15 + _scloff = _monoff; 1.16 _endoff = _monoff; 1.17 _sp = 0; 1.18 } 1.19 @@ -297,12 +299,22 @@ 1.20 return total; 1.21 } 1.22 1.23 +#ifndef PRODUCT 1.24 + 1.25 //------------------------------format_helper---------------------------------- 1.26 // Given an allocation (a Chaitin object) and a Node decide if the Node carries 1.27 // any defined value or not. If it does, print out the register or constant. 1.28 -#ifndef PRODUCT 1.29 -static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i ) { 1.30 +static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i, GrowableArray<SafePointScalarObjectNode*> *scobjs ) { 1.31 if (n == NULL) { st->print(" NULL"); return; } 1.32 + if (n->is_SafePointScalarObject()) { 1.33 + // Scalar replacement. 1.34 + SafePointScalarObjectNode* spobj = n->as_SafePointScalarObject(); 1.35 + scobjs->append_if_missing(spobj); 1.36 + int sco_n = scobjs->find(spobj); 1.37 + assert(sco_n >= 0, ""); 1.38 + st->print(" %s%d]=#ScObj" INT32_FORMAT, msg, i, sco_n); 1.39 + return; 1.40 + } 1.41 if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined 1.42 char buf[50]; 1.43 regalloc->dump_register(n,buf); 1.44 @@ -342,10 +354,8 @@ 1.45 } 1.46 } 1.47 } 1.48 -#endif 1.49 1.50 //------------------------------format----------------------------------------- 1.51 -#ifndef PRODUCT 1.52 void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const { 1.53 st->print(" #"); 1.54 if( _method ) { 1.55 @@ -356,24 +366,25 @@ 1.56 return; 1.57 } 1.58 if (n->is_MachSafePoint()) { 1.59 + GrowableArray<SafePointScalarObjectNode*> scobjs; 1.60 MachSafePointNode *mcall = n->as_MachSafePoint(); 1.61 uint i; 1.62 // Print locals 1.63 for( i = 0; i < (uint)loc_size(); i++ ) 1.64 - format_helper( regalloc, st, mcall->local(this, i), "L[", i ); 1.65 + format_helper( regalloc, st, mcall->local(this, i), "L[", i, &scobjs ); 1.66 // Print stack 1.67 for (i = 0; i < (uint)stk_size(); i++) { 1.68 if ((uint)(_stkoff + i) >= mcall->len()) 1.69 st->print(" oob "); 1.70 else 1.71 - format_helper( regalloc, st, mcall->stack(this, i), "STK[", i ); 1.72 + format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs ); 1.73 } 1.74 for (i = 0; (int)i < nof_monitors(); i++) { 1.75 Node *box = mcall->monitor_box(this, i); 1.76 Node *obj = mcall->monitor_obj(this, i); 1.77 if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) { 1.78 while( !box->is_BoxLock() ) box = box->in(1); 1.79 - format_helper( regalloc, st, box, "MON-BOX[", i ); 1.80 + format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs ); 1.81 } else { 1.82 OptoReg::Name box_reg = BoxLockNode::stack_slot(box); 1.83 st->print(" MON-BOX%d=%s+%d", 1.84 @@ -381,15 +392,71 @@ 1.85 OptoReg::regname(OptoReg::c_frame_pointer), 1.86 regalloc->reg2offset(box_reg)); 1.87 } 1.88 - format_helper( regalloc, st, obj, "MON-OBJ[", i ); 1.89 + format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs ); 1.90 + } 1.91 + 1.92 + for (i = 0; i < (uint)scobjs.length(); i++) { 1.93 + // Scalar replaced objects. 1.94 + st->print_cr(""); 1.95 + st->print(" # ScObj" INT32_FORMAT " ", i); 1.96 + SafePointScalarObjectNode* spobj = scobjs.at(i); 1.97 + ciKlass* cik = spobj->bottom_type()->is_oopptr()->klass(); 1.98 + assert(cik->is_instance_klass() || 1.99 + cik->is_array_klass(), "Not supported allocation."); 1.100 + ciInstanceKlass *iklass = NULL; 1.101 + if (cik->is_instance_klass()) { 1.102 + cik->print_name_on(st); 1.103 + iklass = cik->as_instance_klass(); 1.104 + } else if (cik->is_type_array_klass()) { 1.105 + cik->as_array_klass()->base_element_type()->print_name_on(st); 1.106 + st->print("[%d]=", spobj->n_fields()); 1.107 + } else if (cik->is_obj_array_klass()) { 1.108 + ciType* cie = cik->as_array_klass()->base_element_type(); 1.109 + int ndim = 1; 1.110 + while (cie->is_obj_array_klass()) { 1.111 + ndim += 1; 1.112 + cie = cie->as_array_klass()->base_element_type(); 1.113 + } 1.114 + cie->print_name_on(st); 1.115 + while (ndim-- > 0) { 1.116 + st->print("[]"); 1.117 + } 1.118 + st->print("[%d]=", spobj->n_fields()); 1.119 + } 1.120 + st->print("{"); 1.121 + uint nf = spobj->n_fields(); 1.122 + if (nf > 0) { 1.123 + uint first_ind = spobj->first_index(); 1.124 + Node* fld_node = mcall->in(first_ind); 1.125 + ciField* cifield; 1.126 + if (iklass != NULL) { 1.127 + st->print(" ["); 1.128 + cifield = iklass->nonstatic_field_at(0); 1.129 + cifield->print_name_on(st); 1.130 + format_helper( regalloc, st, fld_node, ":", 0, &scobjs ); 1.131 + } else { 1.132 + format_helper( regalloc, st, fld_node, "[", 0, &scobjs ); 1.133 + } 1.134 + for (uint j = 1; j < nf; j++) { 1.135 + fld_node = mcall->in(first_ind+j); 1.136 + if (iklass != NULL) { 1.137 + st->print(", ["); 1.138 + cifield = iklass->nonstatic_field_at(j); 1.139 + cifield->print_name_on(st); 1.140 + format_helper( regalloc, st, fld_node, ":", j, &scobjs ); 1.141 + } else { 1.142 + format_helper( regalloc, st, fld_node, ", [", j, &scobjs ); 1.143 + } 1.144 + } 1.145 + } 1.146 + st->print(" }"); 1.147 } 1.148 } 1.149 st->print_cr(""); 1.150 if (caller() != NULL) caller()->format(regalloc, n, st); 1.151 } 1.152 -#endif 1.153 1.154 -#ifndef PRODUCT 1.155 + 1.156 void JVMState::dump_spec(outputStream *st) const { 1.157 if (_method != NULL) { 1.158 bool printed = false; 1.159 @@ -419,9 +486,8 @@ 1.160 } 1.161 if (caller() != NULL) caller()->dump_spec(st); 1.162 } 1.163 -#endif 1.164 1.165 -#ifndef PRODUCT 1.166 + 1.167 void JVMState::dump_on(outputStream* st) const { 1.168 if (_map && !((uintptr_t)_map & 1)) { 1.169 if (_map->len() > _map->req()) { // _map->has_exceptions() 1.170 @@ -434,8 +500,8 @@ 1.171 } 1.172 _map->dump(2); 1.173 } 1.174 - st->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=", 1.175 - depth(), locoff(), stkoff(), monoff(), endoff(), monitor_depth(), sp(), bci()); 1.176 + st->print("JVMS depth=%d loc=%d stk=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d method=", 1.177 + depth(), locoff(), stkoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci()); 1.178 if (_method == NULL) { 1.179 st->print_cr("(none)"); 1.180 } else { 1.181 @@ -465,6 +531,7 @@ 1.182 n->set_locoff(_locoff); 1.183 n->set_stkoff(_stkoff); 1.184 n->set_monoff(_monoff); 1.185 + n->set_scloff(_scloff); 1.186 n->set_endoff(_endoff); 1.187 n->set_sp(_sp); 1.188 n->set_map(_map); 1.189 @@ -765,6 +832,7 @@ 1.190 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) { 1.191 assert((int)grow_by > 0, "sanity"); 1.192 int monoff = jvms->monoff(); 1.193 + int scloff = jvms->scloff(); 1.194 int endoff = jvms->endoff(); 1.195 assert(endoff == (int)req(), "no other states or debug info after me"); 1.196 Node* top = Compile::current()->top(); 1.197 @@ -772,6 +840,7 @@ 1.198 ins_req(monoff, top); 1.199 } 1.200 jvms->set_monoff(monoff + grow_by); 1.201 + jvms->set_scloff(scloff + grow_by); 1.202 jvms->set_endoff(endoff + grow_by); 1.203 } 1.204 1.205 @@ -781,6 +850,7 @@ 1.206 const int MonitorEdges = 2; 1.207 assert(JVMState::logMonitorEdges == exact_log2(MonitorEdges), "correct MonitorEdges"); 1.208 assert(req() == jvms()->endoff(), "correct sizing"); 1.209 + int nextmon = jvms()->scloff(); 1.210 if (GenerateSynchronizationCode) { 1.211 add_req(lock->box_node()); 1.212 add_req(lock->obj_node()); 1.213 @@ -788,6 +858,7 @@ 1.214 add_req(NULL); 1.215 add_req(NULL); 1.216 } 1.217 + jvms()->set_scloff(nextmon+MonitorEdges); 1.218 jvms()->set_endoff(req()); 1.219 } 1.220 1.221 @@ -795,10 +866,13 @@ 1.222 // Delete last monitor from debug info 1.223 debug_only(int num_before_pop = jvms()->nof_monitors()); 1.224 const int MonitorEdges = (1<<JVMState::logMonitorEdges); 1.225 + int scloff = jvms()->scloff(); 1.226 int endoff = jvms()->endoff(); 1.227 + int new_scloff = scloff - MonitorEdges; 1.228 int new_endoff = endoff - MonitorEdges; 1.229 + jvms()->set_scloff(new_scloff); 1.230 jvms()->set_endoff(new_endoff); 1.231 - while (endoff > new_endoff) del_req(--endoff); 1.232 + while (scloff > new_scloff) del_req(--scloff); 1.233 assert(jvms()->nof_monitors() == num_before_pop-1, ""); 1.234 } 1.235 1.236 @@ -822,6 +896,63 @@ 1.237 return (TypeFunc::Parms == idx); 1.238 } 1.239 1.240 +//============== SafePointScalarObjectNode ============== 1.241 + 1.242 +SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp, 1.243 +#ifdef ASSERT 1.244 + AllocateNode* alloc, 1.245 +#endif 1.246 + uint first_index, 1.247 + uint n_fields) : 1.248 + TypeNode(tp, 1), // 1 control input -- seems required. Get from root. 1.249 +#ifdef ASSERT 1.250 + _alloc(alloc), 1.251 +#endif 1.252 + _first_index(first_index), 1.253 + _n_fields(n_fields) 1.254 +{ 1.255 + init_class_id(Class_SafePointScalarObject); 1.256 +} 1.257 + 1.258 + 1.259 +uint SafePointScalarObjectNode::ideal_reg() const { 1.260 + return 0; // No matching to machine instruction 1.261 +} 1.262 + 1.263 +const RegMask &SafePointScalarObjectNode::in_RegMask(uint idx) const { 1.264 + return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]); 1.265 +} 1.266 + 1.267 +const RegMask &SafePointScalarObjectNode::out_RegMask() const { 1.268 + return RegMask::Empty; 1.269 +} 1.270 + 1.271 +uint SafePointScalarObjectNode::match_edge(uint idx) const { 1.272 + return 0; 1.273 +} 1.274 + 1.275 +SafePointScalarObjectNode* 1.276 +SafePointScalarObjectNode::clone(int jvms_adj, Dict* sosn_map) const { 1.277 + void* cached = (*sosn_map)[(void*)this]; 1.278 + if (cached != NULL) { 1.279 + return (SafePointScalarObjectNode*)cached; 1.280 + } 1.281 + Compile* C = Compile::current(); 1.282 + SafePointScalarObjectNode* res = (SafePointScalarObjectNode*)Node::clone(); 1.283 + res->_first_index += jvms_adj; 1.284 + sosn_map->Insert((void*)this, (void*)res); 1.285 + return res; 1.286 +} 1.287 + 1.288 + 1.289 +#ifndef PRODUCT 1.290 +void SafePointScalarObjectNode::dump_spec(outputStream *st) const { 1.291 + st->print(" # fields@[%d..%d]", first_index(), 1.292 + first_index() + n_fields() - 1); 1.293 +} 1.294 + 1.295 +#endif 1.296 + 1.297 //============================================================================= 1.298 uint AllocateNode::size_of() const { return sizeof(*this); } 1.299