< prev index next >

src/share/vm/ci/bcEscapeAnalyzer.cpp

Print this page
rev 9028 : 8218201: Failures when vmIntrinsics::_getClass is not inlined
Summary: Fix BCEscapeAnalyzer to correctly handle _getClass intrinsic.
Reviewed-by: kvn, dlong, redestad, neliasso


1153           int ex_end = b->ex_limit_bci();
1154           if ((ex_start >= blk_start && ex_start < blk_end) ||
1155               (ex_end > blk_start && ex_end <= blk_end)) {
1156             successors.push(b);
1157           }
1158           DEBUG_ONLY(handler_count++;)
1159         }
1160       }
1161       assert(handler_count > 0, "must find at least one handler");
1162     }
1163     // merge computed variable state with successors
1164     while(successors.length() > 0) {
1165       ciBlock *succ = successors.pop();
1166       merge_block_states(blockstates, succ, &state);
1167       if (!succ->processed())
1168         worklist.push(succ);
1169     }
1170   }
1171 }
1172 
1173 bool BCEscapeAnalyzer::do_analysis() {
1174   Arena* arena = CURRENT_ENV->arena();
1175   // identify basic blocks
1176   _methodBlocks = _method->get_method_blocks();
1177 
1178   iterate_blocks(arena);
1179   // TEMPORARY
1180   return true;
1181 }
1182 
1183 vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() {
1184   vmIntrinsics::ID iid = method()->intrinsic_id();
1185 
1186   if (iid == vmIntrinsics::_getClass ||
1187       iid ==  vmIntrinsics::_fillInStackTrace ||
1188       iid == vmIntrinsics::_hashCode)
1189     return iid;
1190   else
1191     return vmIntrinsics::_none;

1192 }
1193 
1194 bool BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) {
1195   ArgumentMap arg;
1196   arg.clear();
1197   switch (iid) {
1198   case vmIntrinsics::_getClass:
1199     _return_local = false;

1200     break;
1201   case vmIntrinsics::_fillInStackTrace:
1202     arg.set(0); // 'this'
1203     set_returned(arg);
1204     break;
1205   case vmIntrinsics::_hashCode:
1206     // initialized state is correct
1207     break;
1208   default:
1209     assert(false, "unexpected intrinsic");
1210   }
1211   return true;
1212 }
1213 
1214 void BCEscapeAnalyzer::initialize() {
1215   int i;
1216 
1217   // clear escape information (method may have been deoptimized)
1218   methodData()->clear_escape_info();
1219 
1220   // initialize escape state of object parameters
1221   ciSignature* sig = method()->signature();
1222   int j = 0;
1223   if (!method()->is_static()) {
1224     _arg_local.set(0);
1225     _arg_stack.set(0);
1226     j++;
1227   }
1228   for (i = 0; i < sig->count(); i++) {
1229     ciType* t = sig->type_at(i);
1230     if (!t->is_primitive_type()) {
1231       _arg_local.set(j);


1295                       _level, (int) MaxBCEAEstimateLevel);
1296       else if (method()->code_size() > MaxBCEAEstimateSize)
1297         tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize (%d).",
1298                       method()->code_size(), (int) MaxBCEAEstimateSize);
1299       else
1300         ShouldNotReachHere();
1301     }
1302     clear_escape_info();
1303 
1304     return;
1305   }
1306 
1307   if (BCEATraceLevel >= 1) {
1308     tty->print("[EA] estimating escape information for");
1309     if (iid != vmIntrinsics::_none)
1310       tty->print(" intrinsic");
1311     method()->print_short_name();
1312     tty->print_cr(" (%d bytes)", method()->code_size());
1313   }
1314 
1315   bool success;
1316 
1317   initialize();
1318 
1319   // Do not scan method if it has no object parameters and
1320   // does not returns an object (_return_allocated is set in initialize()).
1321   if (_arg_local.Size() == 0 && !_return_allocated) {
1322     // Clear all info since method's bytecode was not analysed and
1323     // set pessimistic escape information.
1324     clear_escape_info();
1325     methodData()->set_eflag(MethodData::allocated_escapes);
1326     methodData()->set_eflag(MethodData::unknown_modified);
1327     methodData()->set_eflag(MethodData::estimated);
1328     return;
1329   }
1330 
1331   if (iid != vmIntrinsics::_none)
1332     success = compute_escape_for_intrinsic(iid);
1333   else {
1334     success = do_analysis();
1335   }
1336 
1337   // don't store interprocedural escape information if it introduces
1338   // dependencies or if method data is empty
1339   //
1340   if (!has_dependencies() && !methodData()->is_empty()) {
1341     for (i = 0; i < _arg_size; i++) {
1342       if (_arg_local.test(i)) {
1343         assert(_arg_stack.test(i), "inconsistent escape info");
1344         methodData()->set_arg_local(i);
1345         methodData()->set_arg_stack(i);
1346       } else if (_arg_stack.test(i)) {
1347         methodData()->set_arg_stack(i);
1348       }
1349       if (_arg_returned.test(i)) {
1350         methodData()->set_arg_returned(i);
1351       }
1352       methodData()->set_arg_modified(i, _arg_modified[i]);
1353     }
1354     if (_return_local) {




1153           int ex_end = b->ex_limit_bci();
1154           if ((ex_start >= blk_start && ex_start < blk_end) ||
1155               (ex_end > blk_start && ex_end <= blk_end)) {
1156             successors.push(b);
1157           }
1158           DEBUG_ONLY(handler_count++;)
1159         }
1160       }
1161       assert(handler_count > 0, "must find at least one handler");
1162     }
1163     // merge computed variable state with successors
1164     while(successors.length() > 0) {
1165       ciBlock *succ = successors.pop();
1166       merge_block_states(blockstates, succ, &state);
1167       if (!succ->processed())
1168         worklist.push(succ);
1169     }
1170   }
1171 }
1172 
1173 void BCEscapeAnalyzer::do_analysis() {
1174   Arena* arena = CURRENT_ENV->arena();
1175   // identify basic blocks
1176   _methodBlocks = _method->get_method_blocks();
1177 
1178   iterate_blocks(arena);


1179 }
1180 
1181 vmIntrinsics::ID BCEscapeAnalyzer::known_intrinsic() {
1182   vmIntrinsics::ID iid = method()->intrinsic_id();

1183   if (iid == vmIntrinsics::_getClass ||
1184       iid ==  vmIntrinsics::_fillInStackTrace ||
1185       iid == vmIntrinsics::_hashCode) {
1186     return iid;
1187   } else {
1188     return vmIntrinsics::_none;
1189   }
1190 }
1191 
1192 void BCEscapeAnalyzer::compute_escape_for_intrinsic(vmIntrinsics::ID iid) {
1193   ArgumentMap arg;
1194   arg.clear();
1195   switch (iid) {
1196     case vmIntrinsics::_getClass:
1197       _return_local = false;
1198       _return_allocated = false;
1199       break;
1200     case vmIntrinsics::_fillInStackTrace:
1201       arg.set(0); // 'this'
1202       set_returned(arg);
1203       break;
1204     case vmIntrinsics::_hashCode:
1205       // initialized state is correct
1206       break;
1207   default:
1208     assert(false, "unexpected intrinsic");
1209   }

1210 }
1211 
1212 void BCEscapeAnalyzer::initialize() {
1213   int i;
1214 
1215   // clear escape information (method may have been deoptimized)
1216   methodData()->clear_escape_info();
1217 
1218   // initialize escape state of object parameters
1219   ciSignature* sig = method()->signature();
1220   int j = 0;
1221   if (!method()->is_static()) {
1222     _arg_local.set(0);
1223     _arg_stack.set(0);
1224     j++;
1225   }
1226   for (i = 0; i < sig->count(); i++) {
1227     ciType* t = sig->type_at(i);
1228     if (!t->is_primitive_type()) {
1229       _arg_local.set(j);


1293                       _level, (int) MaxBCEAEstimateLevel);
1294       else if (method()->code_size() > MaxBCEAEstimateSize)
1295         tty->print_cr("code size (%d) exceeds MaxBCEAEstimateSize (%d).",
1296                       method()->code_size(), (int) MaxBCEAEstimateSize);
1297       else
1298         ShouldNotReachHere();
1299     }
1300     clear_escape_info();
1301 
1302     return;
1303   }
1304 
1305   if (BCEATraceLevel >= 1) {
1306     tty->print("[EA] estimating escape information for");
1307     if (iid != vmIntrinsics::_none)
1308       tty->print(" intrinsic");
1309     method()->print_short_name();
1310     tty->print_cr(" (%d bytes)", method()->code_size());
1311   }
1312 


1313   initialize();
1314 
1315   // Do not scan method if it has no object parameters and
1316   // does not returns an object (_return_allocated is set in initialize()).
1317   if (_arg_local.Size() == 0 && !_return_allocated) {
1318     // Clear all info since method's bytecode was not analysed and
1319     // set pessimistic escape information.
1320     clear_escape_info();
1321     methodData()->set_eflag(MethodData::allocated_escapes);
1322     methodData()->set_eflag(MethodData::unknown_modified);
1323     methodData()->set_eflag(MethodData::estimated);
1324     return;
1325   }
1326 
1327   if (iid != vmIntrinsics::_none)
1328     compute_escape_for_intrinsic(iid);
1329   else {
1330     do_analysis();
1331   }
1332 
1333   // don't store interprocedural escape information if it introduces
1334   // dependencies or if method data is empty
1335   //
1336   if (!has_dependencies() && !methodData()->is_empty()) {
1337     for (i = 0; i < _arg_size; i++) {
1338       if (_arg_local.test(i)) {
1339         assert(_arg_stack.test(i), "inconsistent escape info");
1340         methodData()->set_arg_local(i);
1341         methodData()->set_arg_stack(i);
1342       } else if (_arg_stack.test(i)) {
1343         methodData()->set_arg_stack(i);
1344       }
1345       if (_arg_returned.test(i)) {
1346         methodData()->set_arg_returned(i);
1347       }
1348       methodData()->set_arg_modified(i, _arg_modified[i]);
1349     }
1350     if (_return_local) {


< prev index next >