Mercurial > hg > truffle
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--------------------------------------- |