comparison src/share/vm/opto/escape.cpp @ 6795:7eca5de9e0b6

7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement() Summary: use shorter instruction sequences for atomic add and atomic exchange when possible. Reviewed-by: kvn, jrose
author roland
date Thu, 20 Sep 2012 16:49:17 +0200
parents 6c5b7a6becc8
children 8e47bac5643a
comparison
equal deleted inserted replaced
6794:8ae8f9dd7099 6795:7eca5de9e0b6
280 #endif 280 #endif
281 } 281 }
282 return has_non_escaping_obj; 282 return has_non_escaping_obj;
283 } 283 }
284 284
285 // Utility function for nodes that load an object
286 void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
287 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
288 // ThreadLocal has RawPtr type.
289 const Type* t = _igvn->type(n);
290 if (t->make_ptr() != NULL) {
291 Node* adr = n->in(MemNode::Address);
292 #ifdef ASSERT
293 if (!adr->is_AddP()) {
294 assert(_igvn->type(adr)->isa_rawptr(), "sanity");
295 } else {
296 assert((ptnode_adr(adr->_idx) == NULL ||
297 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
298 }
299 #endif
300 add_local_var_and_edge(n, PointsToNode::NoEscape,
301 adr, delayed_worklist);
302 }
303 }
304
285 // Populate Connection Graph with PointsTo nodes and create simple 305 // Populate Connection Graph with PointsTo nodes and create simple
286 // connection graph edges. 306 // connection graph edges.
287 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) { 307 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
288 assert(!_verify, "this method sould not be called for verification"); 308 assert(!_verify, "this method sould not be called for verification");
289 PhaseGVN* igvn = _igvn; 309 PhaseGVN* igvn = _igvn;
385 break; 405 break;
386 } 406 }
387 case Op_LoadP: 407 case Op_LoadP:
388 case Op_LoadN: 408 case Op_LoadN:
389 case Op_LoadPLocked: { 409 case Op_LoadPLocked: {
390 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because 410 add_objload_to_connection_graph(n, delayed_worklist);
391 // ThreadLocal has RawPrt type.
392 const Type* t = igvn->type(n);
393 if (t->make_ptr() != NULL) {
394 Node* adr = n->in(MemNode::Address);
395 #ifdef ASSERT
396 if (!adr->is_AddP()) {
397 assert(igvn->type(adr)->isa_rawptr(), "sanity");
398 } else {
399 assert((ptnode_adr(adr->_idx) == NULL ||
400 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
401 }
402 #endif
403 add_local_var_and_edge(n, PointsToNode::NoEscape,
404 adr, delayed_worklist);
405 }
406 break; 411 break;
407 } 412 }
408 case Op_Parm: { 413 case Op_Parm: {
409 map_ideal_node(n, phantom_obj); 414 map_ideal_node(n, phantom_obj);
410 break; 415 break;
415 map_ideal_node(n, phantom_obj); // Result is unknown 420 map_ideal_node(n, phantom_obj); // Result is unknown
416 break; 421 break;
417 } 422 }
418 case Op_Phi: { 423 case Op_Phi: {
419 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because 424 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
420 // ThreadLocal has RawPrt type. 425 // ThreadLocal has RawPtr type.
421 const Type* t = n->as_Phi()->type(); 426 const Type* t = n->as_Phi()->type();
422 if (t->make_ptr() != NULL) { 427 if (t->make_ptr() != NULL) {
423 add_local_var(n, PointsToNode::NoEscape); 428 add_local_var(n, PointsToNode::NoEscape);
424 // Do not add edges during first iteration because some could be 429 // Do not add edges during first iteration because some could be
425 // not defined yet. 430 // not defined yet.
443 // Treat Return value as LocalVar with GlobalEscape escape state. 448 // Treat Return value as LocalVar with GlobalEscape escape state.
444 add_local_var_and_edge(n, PointsToNode::GlobalEscape, 449 add_local_var_and_edge(n, PointsToNode::GlobalEscape,
445 n->in(TypeFunc::Parms), delayed_worklist); 450 n->in(TypeFunc::Parms), delayed_worklist);
446 } 451 }
447 break; 452 break;
453 }
454 case Op_GetAndSetP:
455 case Op_GetAndSetN: {
456 add_objload_to_connection_graph(n, delayed_worklist);
457 // fallthrough
448 } 458 }
449 case Op_StoreP: 459 case Op_StoreP:
450 case Op_StoreN: 460 case Op_StoreN:
451 case Op_StorePConditional: 461 case Op_StorePConditional:
452 case Op_CompareAndSwapP: 462 case Op_CompareAndSwapP:
583 } 593 }
584 case Op_LoadP: 594 case Op_LoadP:
585 case Op_LoadN: 595 case Op_LoadN:
586 case Op_LoadPLocked: { 596 case Op_LoadPLocked: {
587 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because 597 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
588 // ThreadLocal has RawPrt type. 598 // ThreadLocal has RawPtr type.
589 const Type* t = _igvn->type(n); 599 const Type* t = _igvn->type(n);
590 if (t->make_ptr() != NULL) { 600 if (t->make_ptr() != NULL) {
591 Node* adr = n->in(MemNode::Address); 601 Node* adr = n->in(MemNode::Address);
592 add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); 602 add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
593 break; 603 break;
594 } 604 }
595 ELSE_FAIL("Op_LoadP"); 605 ELSE_FAIL("Op_LoadP");
596 } 606 }
597 case Op_Phi: { 607 case Op_Phi: {
598 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because 608 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
599 // ThreadLocal has RawPrt type. 609 // ThreadLocal has RawPtr type.
600 const Type* t = n->as_Phi()->type(); 610 const Type* t = n->as_Phi()->type();
601 if (t->make_ptr() != NULL) { 611 if (t->make_ptr() != NULL) {
602 for (uint i = 1; i < n->req(); i++) { 612 for (uint i = 1; i < n->req(); i++) {
603 Node* in = n->in(i); 613 Node* in = n->in(i);
604 if (in == NULL) 614 if (in == NULL)
636 } 646 }
637 case Op_StoreP: 647 case Op_StoreP:
638 case Op_StoreN: 648 case Op_StoreN:
639 case Op_StorePConditional: 649 case Op_StorePConditional:
640 case Op_CompareAndSwapP: 650 case Op_CompareAndSwapP:
641 case Op_CompareAndSwapN: { 651 case Op_CompareAndSwapN:
652 case Op_GetAndSetP:
653 case Op_GetAndSetN: {
642 Node* adr = n->in(MemNode::Address); 654 Node* adr = n->in(MemNode::Address);
655 if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
656 const Type* t = _igvn->type(n);
657 if (t->make_ptr() != NULL) {
658 add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
659 }
660 }
643 const Type *adr_type = _igvn->type(adr); 661 const Type *adr_type = _igvn->type(adr);
644 adr_type = adr_type->make_ptr(); 662 adr_type = adr_type->make_ptr();
645 if (adr_type->isa_oopptr() || 663 if (adr_type->isa_oopptr() ||
646 (opcode == Op_StoreP || opcode == Op_StoreN) && 664 (opcode == Op_StoreP || opcode == Op_StoreN) &&
647 (adr_type == TypeRawPtr::NOTNULL && 665 (adr_type == TypeRawPtr::NOTNULL &&