comparison src/share/vm/opto/graphKit.cpp @ 12956:3213ba4d3dff

8024069: replace_in_map() should operate on parent maps Summary: type information gets lost because replace_in_map() doesn't update parent maps Reviewed-by: kvn, twisti
author roland
date Sat, 19 Oct 2013 12:16:43 +0200
parents f91a9a696e5e
children b2ee5dc63353
comparison
equal deleted inserted replaced
12955:252d541466ea 12956:3213ba4d3dff
637 debug_only(kit->verify_map()); 637 debug_only(kit->verify_map());
638 _kit = kit; 638 _kit = kit;
639 _map = kit->map(); // preserve the map 639 _map = kit->map(); // preserve the map
640 _sp = kit->sp(); 640 _sp = kit->sp();
641 kit->set_map(clone_map ? kit->clone_map() : NULL); 641 kit->set_map(clone_map ? kit->clone_map() : NULL);
642 Compile::current()->inc_preserve_jvm_state();
642 #ifdef ASSERT 643 #ifdef ASSERT
643 _bci = kit->bci(); 644 _bci = kit->bci();
644 Parse* parser = kit->is_Parse(); 645 Parse* parser = kit->is_Parse();
645 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo(); 646 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
646 _block = block; 647 _block = block;
654 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo(); 655 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
655 assert(block == _block, "block must not shift"); 656 assert(block == _block, "block must not shift");
656 #endif 657 #endif
657 kit->set_map(_map); 658 kit->set_map(_map);
658 kit->set_sp(_sp); 659 kit->set_sp(_sp);
660 Compile::current()->dec_preserve_jvm_state();
659 } 661 }
660 662
661 663
662 //-----------------------------BuildCutout------------------------------------- 664 //-----------------------------BuildCutout-------------------------------------
663 BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt) 665 BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt)
1371 } 1373 }
1372 1374
1373 1375
1374 //--------------------------replace_in_map------------------------------------- 1376 //--------------------------replace_in_map-------------------------------------
1375 void GraphKit::replace_in_map(Node* old, Node* neww) { 1377 void GraphKit::replace_in_map(Node* old, Node* neww) {
1376 this->map()->replace_edge(old, neww); 1378 if (old == neww) {
1379 return;
1380 }
1381
1382 map()->replace_edge(old, neww);
1377 1383
1378 // Note: This operation potentially replaces any edge 1384 // Note: This operation potentially replaces any edge
1379 // on the map. This includes locals, stack, and monitors 1385 // on the map. This includes locals, stack, and monitors
1380 // of the current (innermost) JVM state. 1386 // of the current (innermost) JVM state.
1381 1387
1382 // We can consider replacing in caller maps. 1388 if (!ReplaceInParentMaps) {
1383 // The idea would be that an inlined function's null checks 1389 return;
1384 // can be shared with the entire inlining tree. 1390 }
1385 // The expense of doing this is that the PreserveJVMState class 1391
1386 // would have to preserve caller states too, with a deep copy. 1392 // PreserveJVMState doesn't do a deep copy so we can't modify
1393 // parents
1394 if (Compile::current()->has_preserve_jvm_state()) {
1395 return;
1396 }
1397
1398 Parse* parser = is_Parse();
1399 bool progress = true;
1400 Node* ctrl = map()->in(0);
1401 // Follow the chain of parsers and see whether the update can be
1402 // done in the map of callers. We can do the replace for a caller if
1403 // the current control post dominates the control of a caller.
1404 while (parser != NULL && parser->caller() != NULL && progress) {
1405 progress = false;
1406 Node* parent_map = parser->caller()->map();
1407 assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch");
1408
1409 Node* parent_ctrl = parent_map->in(0);
1410
1411 while (parent_ctrl->is_Region()) {
1412 Node* n = parent_ctrl->as_Region()->is_copy();
1413 if (n == NULL) {
1414 break;
1415 }
1416 parent_ctrl = n;
1417 }
1418
1419 for (;;) {
1420 if (ctrl == parent_ctrl) {
1421 // update the map of the exits which is the one that will be
1422 // used when compilation resume after inlining
1423 parser->exits().map()->replace_edge(old, neww);
1424 progress = true;
1425 break;
1426 }
1427 if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
1428 ctrl = ctrl->in(0)->in(0);
1429 } else if (ctrl->is_Region()) {
1430 Node* n = ctrl->as_Region()->is_copy();
1431 if (n == NULL) {
1432 break;
1433 }
1434 ctrl = n;
1435 } else {
1436 break;
1437 }
1438 }
1439
1440 parser = parser->parent_parser();
1441 }
1387 } 1442 }
1388 1443
1389 1444
1390 //============================================================================= 1445 //=============================================================================
1391 //--------------------------------memory--------------------------------------- 1446 //--------------------------------memory---------------------------------------