357 add_call_node(n->as_Call());
358 record_for_optimizer(n);
359 } else {
360 if (n->is_CallStaticJava()) {
361 const char* name = n->as_CallStaticJava()->_name;
362 if (name != NULL && strcmp(name, "uncommon_trap") == 0)
363 return; // Skip uncommon traps
364 }
365 // Don't mark as processed since call's arguments have to be processed.
366 delayed_worklist->push(n);
367 // Check if a call returns an object.
368 if ((n->as_Call()->returns_pointer() &&
369 n->as_Call()->proj_out(TypeFunc::Parms) != NULL) ||
370 (n->is_CallStaticJava() &&
371 n->as_CallStaticJava()->is_boxing_method())) {
372 add_call_node(n->as_Call());
373 } else if (n->as_Call()->tf()->returns_value_type_as_fields()) {
374 bool returns_oop = false;
375 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !returns_oop; i++) {
376 ProjNode* pn = n->fast_out(i)->as_Proj();
377 if (pn->_con >= TypeFunc::Parms && pn->bottom_type()->isa_oopptr()) {
378 returns_oop = true;
379 }
380 }
381 if (returns_oop) {
382 add_call_node(n->as_Call());
383 }
384 }
385 }
386 return;
387 }
388 // Put this check here to process call arguments since some call nodes
389 // point to phantom_obj.
390 if (n_ptn == phantom_obj || n_ptn == null_obj)
391 return; // Skip predefined nodes.
392
393 int opcode = n->Opcode();
394 switch (opcode) {
395 case Op_AddP: {
396 Node* base = get_addp_base(n);
397 PointsToNode* ptn_base = ptnode_adr(base->_idx);
469 // Produces Null or notNull and is used in only in CmpP so
470 // phantom_obj could be used.
471 map_ideal_node(n, phantom_obj); // Result is unknown
472 break;
473 }
474 case Op_Phi: {
475 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
476 // ThreadLocal has RawPtr type.
477 const Type* t = n->as_Phi()->type();
478 if (t->make_ptr() != NULL) {
479 add_local_var(n, PointsToNode::NoEscape);
480 // Do not add edges during first iteration because some could be
481 // not defined yet.
482 delayed_worklist->push(n);
483 }
484 break;
485 }
486 case Op_Proj: {
487 // we are only interested in the oop result projection from a call
488 if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() &&
489 (n->in(0)->as_Call()->returns_pointer() || n->bottom_type()->isa_oopptr())) {
490 assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) ||
491 n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?");
492 add_local_var_and_edge(n, PointsToNode::NoEscape,
493 n->in(0), delayed_worklist);
494 }
495 break;
496 }
497 case Op_Rethrow: // Exception object escapes
498 case Op_Return: {
499 if (n->req() > TypeFunc::Parms &&
500 igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
501 // Treat Return value as LocalVar with GlobalEscape escape state.
502 add_local_var_and_edge(n, PointsToNode::GlobalEscape,
503 n->in(TypeFunc::Parms), delayed_worklist);
504 }
505 break;
506 }
507 case Op_CompareAndExchangeP:
508 case Op_CompareAndExchangeN:
509 case Op_GetAndSetP:
678 const Type* t = n->as_Phi()->type();
679 if (t->make_ptr() != NULL) {
680 for (uint i = 1; i < n->req(); i++) {
681 Node* in = n->in(i);
682 if (in == NULL)
683 continue; // ignore NULL
684 Node* uncast_in = in->uncast();
685 if (uncast_in->is_top() || uncast_in == n)
686 continue; // ignore top or inputs which go back this node
687 PointsToNode* ptn = ptnode_adr(in->_idx);
688 assert(ptn != NULL, "node should be registered");
689 add_edge(n_ptn, ptn);
690 }
691 break;
692 }
693 ELSE_FAIL("Op_Phi");
694 }
695 case Op_Proj: {
696 // we are only interested in the oop result projection from a call
697 if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() &&
698 (n->in(0)->as_Call()->returns_pointer()|| n->bottom_type()->isa_oopptr())) {
699 assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) ||
700 n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?");
701 add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL);
702 break;
703 }
704 ELSE_FAIL("Op_Proj");
705 }
706 case Op_Rethrow: // Exception object escapes
707 case Op_Return: {
708 if (n->req() > TypeFunc::Parms &&
709 _igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
710 // Treat Return value as LocalVar with GlobalEscape escape state.
711 add_local_var_and_edge(n, PointsToNode::GlobalEscape,
712 n->in(TypeFunc::Parms), NULL);
713 break;
714 }
715 ELSE_FAIL("Op_Return");
716 }
717 case Op_StoreP:
718 case Op_StoreN:
|
357 add_call_node(n->as_Call());
358 record_for_optimizer(n);
359 } else {
360 if (n->is_CallStaticJava()) {
361 const char* name = n->as_CallStaticJava()->_name;
362 if (name != NULL && strcmp(name, "uncommon_trap") == 0)
363 return; // Skip uncommon traps
364 }
365 // Don't mark as processed since call's arguments have to be processed.
366 delayed_worklist->push(n);
367 // Check if a call returns an object.
368 if ((n->as_Call()->returns_pointer() &&
369 n->as_Call()->proj_out(TypeFunc::Parms) != NULL) ||
370 (n->is_CallStaticJava() &&
371 n->as_CallStaticJava()->is_boxing_method())) {
372 add_call_node(n->as_Call());
373 } else if (n->as_Call()->tf()->returns_value_type_as_fields()) {
374 bool returns_oop = false;
375 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !returns_oop; i++) {
376 ProjNode* pn = n->fast_out(i)->as_Proj();
377 if (pn->_con >= TypeFunc::Parms && pn->bottom_type()->isa_ptr()) {
378 returns_oop = true;
379 }
380 }
381 if (returns_oop) {
382 add_call_node(n->as_Call());
383 }
384 }
385 }
386 return;
387 }
388 // Put this check here to process call arguments since some call nodes
389 // point to phantom_obj.
390 if (n_ptn == phantom_obj || n_ptn == null_obj)
391 return; // Skip predefined nodes.
392
393 int opcode = n->Opcode();
394 switch (opcode) {
395 case Op_AddP: {
396 Node* base = get_addp_base(n);
397 PointsToNode* ptn_base = ptnode_adr(base->_idx);
469 // Produces Null or notNull and is used in only in CmpP so
470 // phantom_obj could be used.
471 map_ideal_node(n, phantom_obj); // Result is unknown
472 break;
473 }
474 case Op_Phi: {
475 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
476 // ThreadLocal has RawPtr type.
477 const Type* t = n->as_Phi()->type();
478 if (t->make_ptr() != NULL) {
479 add_local_var(n, PointsToNode::NoEscape);
480 // Do not add edges during first iteration because some could be
481 // not defined yet.
482 delayed_worklist->push(n);
483 }
484 break;
485 }
486 case Op_Proj: {
487 // we are only interested in the oop result projection from a call
488 if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() &&
489 (n->in(0)->as_Call()->returns_pointer() || n->bottom_type()->isa_ptr())) {
490 assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) ||
491 n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?");
492 add_local_var_and_edge(n, PointsToNode::NoEscape,
493 n->in(0), delayed_worklist);
494 }
495 break;
496 }
497 case Op_Rethrow: // Exception object escapes
498 case Op_Return: {
499 if (n->req() > TypeFunc::Parms &&
500 igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
501 // Treat Return value as LocalVar with GlobalEscape escape state.
502 add_local_var_and_edge(n, PointsToNode::GlobalEscape,
503 n->in(TypeFunc::Parms), delayed_worklist);
504 }
505 break;
506 }
507 case Op_CompareAndExchangeP:
508 case Op_CompareAndExchangeN:
509 case Op_GetAndSetP:
678 const Type* t = n->as_Phi()->type();
679 if (t->make_ptr() != NULL) {
680 for (uint i = 1; i < n->req(); i++) {
681 Node* in = n->in(i);
682 if (in == NULL)
683 continue; // ignore NULL
684 Node* uncast_in = in->uncast();
685 if (uncast_in->is_top() || uncast_in == n)
686 continue; // ignore top or inputs which go back this node
687 PointsToNode* ptn = ptnode_adr(in->_idx);
688 assert(ptn != NULL, "node should be registered");
689 add_edge(n_ptn, ptn);
690 }
691 break;
692 }
693 ELSE_FAIL("Op_Phi");
694 }
695 case Op_Proj: {
696 // we are only interested in the oop result projection from a call
697 if (n->as_Proj()->_con >= TypeFunc::Parms && n->in(0)->is_Call() &&
698 (n->in(0)->as_Call()->returns_pointer()|| n->bottom_type()->isa_ptr())) {
699 assert((n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->as_Call()->returns_pointer()) ||
700 n->in(0)->as_Call()->tf()->returns_value_type_as_fields(), "what kind of oop return is it?");
701 add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL);
702 break;
703 }
704 ELSE_FAIL("Op_Proj");
705 }
706 case Op_Rethrow: // Exception object escapes
707 case Op_Return: {
708 if (n->req() > TypeFunc::Parms &&
709 _igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
710 // Treat Return value as LocalVar with GlobalEscape escape state.
711 add_local_var_and_edge(n, PointsToNode::GlobalEscape,
712 n->in(TypeFunc::Parms), NULL);
713 break;
714 }
715 ELSE_FAIL("Op_Return");
716 }
717 case Op_StoreP:
718 case Op_StoreN:
|