Пример #1
0
static bool methodCanBeCompiled(OMR::FrontEnd *fe, TR_ResolvedMethod &method, TR_FilterBST *&filter, TR_Memory *trMemory)
   {
   if (!method.isCompilable(trMemory))
      return false;

   if (!TR::Options::getDebug())
      return true;

   return TR::Options::getDebug()->methodCanBeCompiled(trMemory, &method, filter);
   }
Пример #2
0
TR_BitVector *
addVeryRefinedCallAliasSets(TR::ResolvedMethodSymbol * methodSymbol, TR_BitVector * aliases, List<void> * methodsPeeked)
   {
   TR::Compilation *comp = TR::comp();

   void * methodId = methodSymbol->getResolvedMethod()->getPersistentIdentifier();
   if (methodsPeeked->find(methodId))
      {
      // This can't be allocated into the alias region as it must be accessed across optimizations
      TR_BitVector *heapAliases = new (comp->trHeapMemory()) TR_BitVector(comp->getSymRefCount(), comp->trMemory(), heapAlloc, growable);
      *heapAliases |= *aliases;
      return heapAliases;
      }

   // stop if the peek is getting very deep
   //
   if (methodsPeeked->getSize() >= PEEK_THRESHOLD)
      return 0;

   methodsPeeked->add(methodId);

   dumpOptDetails(comp, "O^O REFINING ALIASES: Peeking into the IL to refine aliases \n");

   if (!methodSymbol->getResolvedMethod()->genMethodILForPeeking(methodSymbol, comp, true))
      return 0;

   TR::SymbolReferenceTable * symRefTab = comp->getSymRefTab();
   for (TR::TreeTop * tt = methodSymbol->getFirstTreeTop(); tt; tt = tt->getNextTreeTop())
      {
	   TR::Node *node = tt->getNode();
      if (node->getOpCode().isResolveCheck())
         return 0;

      if ((node->getOpCodeValue() == TR::treetop) ||
          (node->getOpCodeValue() == TR::compressedRefs) ||
          node->getOpCode().isCheck())
         node = node->getFirstChild();

      if (node->getOpCode().isStore())
         {
         TR::SymbolReference * symRefInCallee = node->getSymbolReference(), * symRefInCaller;
         TR::Symbol * symInCallee = symRefInCallee->getSymbol();
         TR::DataType type = symInCallee->getDataType();
         if (symInCallee->isShadow())
            {
            if (symInCallee->isArrayShadowSymbol())
               symRefInCaller = symRefTab->getSymRef(symRefTab->getArrayShadowIndex(type));

            else if (symInCallee->isArrayletShadowSymbol())
               symRefInCaller = symRefTab->getSymRef(symRefTab->getArrayletShadowIndex(type));

            else
               symRefInCaller = symRefTab->findShadowSymbol(symRefInCallee->getOwningMethod(comp), symRefInCallee->getCPIndex(), type);

            if (symRefInCaller)
               {
               if (symRefInCaller->reallySharesSymbol(comp))
                  symRefInCaller->setSharedShadowAliases(aliases, symRefTab);

               aliases->set(symRefInCaller->getReferenceNumber());
               }

            }
         else if (symInCallee->isStatic())
            {
            symRefInCaller = symRefTab->findStaticSymbol(symRefInCallee->getOwningMethod(comp), symRefInCallee->getCPIndex(), type);
            if (symRefInCaller)
               {
               if (symRefInCaller->reallySharesSymbol(comp))
                  symRefInCaller->setSharedStaticAliases(aliases, symRefTab);
               else
                  aliases->set(symRefInCaller->getReferenceNumber());
               }
            }
         }
      else if (node->getOpCode().isCall())
         {
         if (node->getOpCode().isCallIndirect())
            return 0;
         TR::ResolvedMethodSymbol * calleeSymbol = node->getSymbol()->getResolvedMethodSymbol();
         if (!calleeSymbol)
            return 0;
         TR_ResolvedMethod * calleeMethod = calleeSymbol->getResolvedMethod();
         if (!calleeMethod->isCompilable(comp->trMemory()) || calleeMethod->isJNINative())
            return 0;

         if (!addVeryRefinedCallAliasSets(calleeSymbol, aliases, methodsPeeked))
            return 0;
         }
      else if (node->getOpCodeValue() == TR::monent)
         return 0;
      }

   // This can't be allocated into the alias region as it must be accessed across optimizations
   TR_BitVector *heapAliases = new (comp->trHeapMemory()) TR_BitVector(comp->getSymRefCount(), comp->trMemory(), heapAlloc, growable);
   *heapAliases |= *aliases;
   return heapAliases;
   }
Пример #3
0
TR_BitVector *
OMR::SymbolReference::getUseDefAliasesBV(bool isDirectCall, bool includeGCSafePoint)
   {
   TR::Compilation *comp = TR::comp();
   TR::Region &aliasRegion = comp->aliasRegion();
   int32_t bvInitialSize = comp->getSymRefCount();
   TR_BitVectorGrowable growability = growable;

   // allow more than one shadow for an array type.  Used by LoopAliasRefiner
   const bool supportArrayRefinement=true;

   int32_t kind = _symbol->getKind();
   TR::SymbolReferenceTable * symRefTab = comp->getSymRefTab();

   // !!! NOTE !!!
   // THERE IS A COPY OF THIS LOGIC IN sharesSymbol
   //
   if (!self()->reallySharesSymbol(comp))
      {
      switch (kind)
         {
         case TR::Symbol::IsShadow:
         case TR::Symbol::IsStatic:
            {
            // For unresolved constant dynamic, we need to invoke a Java bootstrap method,
            // which can have arbitrary side effects, so the aliasing should be conservative here.
            // isConstObjectRef now returns true for condy, so we add an explicit condition,
            // more like a short-circuit, to say if we are unresolved and not isConstObjectRef
            // (this is the same as before), or if we are unresolved and condy
            // (this is the extra condition added), we would return conservative aliases.
            if ((self()->isUnresolved() && (_symbol->isConstantDynamic() || !_symbol->isConstObjectRef())) ||
	        _symbol->isVolatile() || self()->isLiteralPoolAddress() ||
                self()->isFromLiteralPool() || _symbol->isUnsafeShadowSymbol() ||
                (_symbol->isArrayShadowSymbol() && comp->getMethodSymbol()->hasVeryRefinedAliasSets()))
               {
               // getUseDefAliases might not return NULL
               }
            else if (!symRefTab->aliasBuilder.mutableGenericIntShadowHasBeenCreated())
               {
               // getUseDefAliases must return NULL
               return NULL;
               }
            else if (kind == TR::Symbol::IsStatic && !symRefTab->aliasBuilder.litPoolGenericIntShadowHasBeenCreated())
               {
               // getUseDefAliases must return NULL
               return NULL;
               }
            break;
            }
         }
      }

   // now do stuff for various kinds of symbols
   //
   switch (kind)
      {
      case TR::Symbol::IsMethod:
         {
         TR::MethodSymbol * methodSymbol = _symbol->castToMethodSymbol();

         if (!methodSymbol->isHelper())
            return symRefTab->aliasBuilder.methodAliases(self());

         if (symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::arraySetSymbol) ||
             symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::osrFearPointHelperSymbol) ||
             symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::potentialOSRPointHelperSymbol))
            {
            return &symRefTab->aliasBuilder.defaultMethodDefAliases();
            }

         if (symRefTab->isNonHelper(self(), TR::SymbolReferenceTable::arrayCmpSymbol))
            return 0;

         switch (self()->getReferenceNumber())
            {
            case TR_methodTypeCheck:
            case TR_nullCheck:
               return &symRefTab->aliasBuilder.defaultMethodDefAliasesWithoutImmutable();

            case TR_arrayBoundsCheck:
            case TR_checkCast:
            case TR_divCheck:
            case TR_typeCheckArrayStore:
            case TR_arrayStoreException:
            case TR_incompatibleReceiver:
            case TR_IncompatibleClassChangeError:
            case TR_reportFinalFieldModified:
            case TR_reportMethodEnter:
            case TR_reportStaticMethodEnter:
            case TR_reportMethodExit:
            case TR_acquireVMAccess:
            case TR_instanceOf:
            case TR_checkAssignable:
            case TR_throwCurrentException:
            case TR_releaseVMAccess:
            case TR_stackOverflow:
            case TR_writeBarrierStore:
            case TR_writeBarrierBatchStore:
            case TR_jitProfileAddress:
            case TR_jitProfileWarmCompilePICAddress:
            case TR_jitProfileValue:
            case TR_jitProfileLongValue:
            case TR_jitProfileBigDecimalValue:
            case TR_jitProfileParseBuffer:

               return 0;

            case TR_asyncCheck:
            case TR_writeBarrierClassStoreRealTimeGC:
            case TR_writeBarrierStoreRealTimeGC:
            case TR_aNewArray:
            case TR_newObject:
            case TR_newObjectNoZeroInit:
            case TR_newArray:
            case TR_multiANewArray:
               if ((comp->generateArraylets() || comp->isDLT()) && includeGCSafePoint)
                  return &symRefTab->aliasBuilder.gcSafePointSymRefNumbers();
               else
                  return 0;

            case TR_aThrow:
               return 0;

            // The monitor exit symbol needs to be aliased with all fields in the
            // current class to ensure that all references to fields are evaluated
            // before the monitor exit
            case TR_monitorExit:
            case TR_monitorEntry:
            case TR_transactionExit:
            case TR_transactionEntry:

            default:
               // The following is the place to check for
               // a use of killsAllMethodSymbolRef... However,
               // it looks like the default action is sufficient.
               //if (symRefTab->findKillsAllMethodSymbolRef() == self())
               //   {
               //   }
               return &symRefTab->aliasBuilder.defaultMethodDefAliases();
            }
         }
      case TR::Symbol::IsResolvedMethod:
         {
         TR::ResolvedMethodSymbol * resolvedMethodSymbol = _symbol->castToResolvedMethodSymbol();

         if (!comp->getOption(TR_EnableHCR))
            {
            switch (resolvedMethodSymbol->getRecognizedMethod())
               {
#ifdef J9_PROJECT_SPECIFIC
               case TR::java_lang_System_arraycopy:
                  {
                  TR_BitVector * aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
                  *aliases |= symRefTab->aliasBuilder.arrayElementSymRefs();
                  if (comp->generateArraylets())
                     *aliases |= symRefTab->aliasBuilder.arrayletElementSymRefs();
                  return aliases;
                  }

                  if (resolvedMethodSymbol->isPureFunction())
                      return NULL;

               case TR::java_lang_Double_longBitsToDouble:
               case TR::java_lang_Double_doubleToLongBits:
               case TR::java_lang_Float_intBitsToFloat:
               case TR::java_lang_Float_floatToIntBits:
               case TR::java_lang_Double_doubleToRawLongBits:
               case TR::java_lang_Float_floatToRawIntBits:
               case TR::java_lang_Math_sqrt:
               case TR::java_lang_StrictMath_sqrt:
               case TR::java_lang_Math_sin:
               case TR::java_lang_StrictMath_sin:
               case TR::java_lang_Math_cos:
               case TR::java_lang_StrictMath_cos:
               case TR::java_lang_Math_max_I:
               case TR::java_lang_Math_min_I:
               case TR::java_lang_Math_max_L:
               case TR::java_lang_Math_min_L:
               case TR::java_lang_Math_abs_I:
               case TR::java_lang_Math_abs_L:
               case TR::java_lang_Math_abs_F:
               case TR::java_lang_Math_abs_D:
               case TR::java_lang_Math_pow:
               case TR::java_lang_StrictMath_pow:
               case TR::java_lang_Math_exp:
               case TR::java_lang_StrictMath_exp:
               case TR::java_lang_Math_log:
               case TR::java_lang_StrictMath_log:
               case TR::java_lang_Math_floor:
               case TR::java_lang_Math_ceil:
               case TR::java_lang_Math_copySign_F:
               case TR::java_lang_Math_copySign_D:
               case TR::java_lang_StrictMath_floor:
               case TR::java_lang_StrictMath_ceil:
               case TR::java_lang_StrictMath_copySign_F:
               case TR::java_lang_StrictMath_copySign_D:
               case TR::com_ibm_Compiler_Internal__TR_Prefetch:
               case TR::java_nio_Bits_keepAlive:
                  if ((comp->generateArraylets() || comp->isDLT()) && includeGCSafePoint)
                     return &symRefTab->aliasBuilder.gcSafePointSymRefNumbers();
                  else
                     return 0;

               // no aliasing on DFP dummy stubs
               case TR::java_math_BigDecimal_DFPPerformHysteresis:
               case TR::java_math_BigDecimal_DFPUseDFP:
               case TR::java_math_BigDecimal_DFPHWAvailable:
               case TR::java_math_BigDecimal_DFPCompareTo:
               case TR::java_math_BigDecimal_DFPUnscaledValue:
               case TR::com_ibm_dataaccess_DecimalData_DFPFacilityAvailable:
               case TR::com_ibm_dataaccess_DecimalData_DFPUseDFP:
               case TR::com_ibm_dataaccess_DecimalData_DFPConvertPackedToDFP:
               case TR::com_ibm_dataaccess_DecimalData_DFPConvertDFPToPacked:
               case TR::com_ibm_dataaccess_DecimalData_createZeroBigDecimal:
               case TR::com_ibm_dataaccess_DecimalData_getlaside:
               case TR::com_ibm_dataaccess_DecimalData_setlaside:
               case TR::com_ibm_dataaccess_DecimalData_getflags:
               case TR::com_ibm_dataaccess_DecimalData_setflags:
                  if (!(
#ifdef TR_TARGET_S390
                     TR::Compiler->target.cpu.getS390SupportsDFP() ||
#endif
                      TR::Compiler->target.cpu.supportsDecimalFloatingPoint()) ||
                      comp->getOption(TR_DisableDFP))
                     return NULL;
#endif //J9_PROJECT_SPECIFIC
               default:
               	break;
               }
            }

#ifdef J9_PROJECT_SPECIFIC
         TR_ResolvedMethod * method = resolvedMethodSymbol->getResolvedMethod();
         TR_PersistentMethodInfo * methodInfo = TR_PersistentMethodInfo::get(method);
         if (methodInfo && (methodInfo->hasRefinedAliasSets() ||
                            comp->getMethodHotness() >= veryHot ||
                            resolvedMethodSymbol->hasVeryRefinedAliasSets()) &&
             (method->isStatic() || method->isFinal() || isDirectCall))
            {
            TR_BitVector * aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            if ((comp->generateArraylets() || comp->isDLT()) && includeGCSafePoint)
               *aliases |= symRefTab->aliasBuilder.gcSafePointSymRefNumbers();

            if (methodInfo->doesntKillAnything() && !comp->getOption(TR_DisableRefinedAliases))
               return aliases;

            if ((resolvedMethodSymbol->hasVeryRefinedAliasSets() || comp->getMethodHotness() >= hot) &&
                !debug("disableVeryRefinedCallAliasSets"))
               {
               TR_BitVector * exactAliases = 0;

               if (resolvedMethodSymbol->hasVeryRefinedAliasSets())
                  exactAliases = symRefTab->aliasBuilder.getVeryRefinedCallAliasSets(resolvedMethodSymbol);
               else
                  {
                  resolvedMethodSymbol->setHasVeryRefinedAliasSets(true);
                  List<void> methodsPeeked(comp->trMemory());
                  exactAliases = addVeryRefinedCallAliasSets(resolvedMethodSymbol, aliases, &methodsPeeked);
                  symRefTab->aliasBuilder.setVeryRefinedCallAliasSets(resolvedMethodSymbol, exactAliases);
                  }
               if (exactAliases)
                  {
                  return exactAliases;
                  }
               }

            // From here on, we're just checking refined alias info.
            // If refined aliases are disabled, return the conservative answer
            // we would have returned had we never attempted to use refined
            // aliases at all.
            //
            if (comp->getOption(TR_DisableRefinedAliases))
               return symRefTab->aliasBuilder.methodAliases(self());

            if (!methodInfo->doesntKillAddressArrayShadows())
               {

               symRefTab->aliasBuilder.addAddressArrayShadows(aliases);

               if (comp->generateArraylets())
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Address));
               }

            if (!methodInfo->doesntKillIntArrayShadows())
               {

               symRefTab->aliasBuilder.addIntArrayShadows(aliases);

               if (comp->generateArraylets())
                  {
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Int32));
                  }
               }

            if (!methodInfo->doesntKillNonIntPrimitiveArrayShadows())
               {

               symRefTab->aliasBuilder.addNonIntPrimitiveArrayShadows(aliases);

               if (comp->generateArraylets())
                  {
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Int8));
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Int16));
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Int32));
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Int64));
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Float));
                  aliases->set(symRefTab->getArrayletShadowIndex(TR::Double));
                  }
               }

            if (!methodInfo->doesntKillAddressFields())
               *aliases |= symRefTab->aliasBuilder.addressShadowSymRefs();

            if (!methodInfo->doesntKillIntFields())
               *aliases |= symRefTab->aliasBuilder.intShadowSymRefs();

            if (!methodInfo->doesntKillNonIntPrimitiveFields())
               *aliases |= symRefTab->aliasBuilder.nonIntPrimitiveShadowSymRefs();

            if (!methodInfo->doesntKillAddressStatics())
               *aliases |= symRefTab->aliasBuilder.addressStaticSymRefs();

            if (!methodInfo->doesntKillIntStatics())
               *aliases |= symRefTab->aliasBuilder.intStaticSymRefs();

            if (!methodInfo->doesntKillNonIntPrimitiveStatics())
               *aliases |= symRefTab->aliasBuilder.nonIntPrimitiveStaticSymRefs();

            TR_BitVector *methodAliases = symRefTab->aliasBuilder.methodAliases(self());
            *aliases &= *methodAliases;
            return aliases;
            }
#endif

         return symRefTab->aliasBuilder.methodAliases(self());
         }
      case TR::Symbol::IsShadow:
         {
         if ((self()->isUnresolved() && !_symbol->isConstObjectRef()) || _symbol->isVolatile() || self()->isLiteralPoolAddress() || self()->isFromLiteralPool() ||
             (_symbol->isUnsafeShadowSymbol() && !self()->reallySharesSymbol()))
            {
            if (symRefTab->aliasBuilder.unsafeArrayElementSymRefs().get(self()->getReferenceNumber()))
               {
               TR_BitVector *aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
               *aliases |= comp->getSymRefTab()->aliasBuilder.defaultMethodDefAliasesWithoutImmutable();
               *aliases -= symRefTab->aliasBuilder.cpSymRefs();
               return aliases;
               }
            else
               return &comp->getSymRefTab()->aliasBuilder.defaultMethodDefAliasesWithoutImmutable();
            }

         TR_BitVector *aliases = NULL;
         if (_symbol == symRefTab->findGenericIntShadowSymbol())
            {
            aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            *aliases |= symRefTab->aliasBuilder.arrayElementSymRefs();
            if (comp->generateArraylets())
               *aliases |= symRefTab->aliasBuilder.arrayletElementSymRefs();
            *aliases |= symRefTab->aliasBuilder.genericIntShadowSymRefs();
            *aliases |= symRefTab->aliasBuilder.genericIntArrayShadowSymRefs();
            *aliases |= symRefTab->aliasBuilder.genericIntNonArrayShadowSymRefs();
            *aliases |= symRefTab->aliasBuilder.unsafeSymRefNumbers();
#ifdef J9_PROJECT_SPECIFIC
            *aliases |= symRefTab->aliasBuilder.unresolvedShadowSymRefs();
#endif
            if (symRefTab->aliasBuilder.conservativeGenericIntShadowAliasing())
               {
               *aliases |= symRefTab->aliasBuilder.addressShadowSymRefs();
               *aliases |= symRefTab->aliasBuilder.intShadowSymRefs();
               *aliases |= symRefTab->aliasBuilder.nonIntPrimitiveShadowSymRefs();
               }
            aliases->set(self()->getReferenceNumber());
            return aliases;
            }

         if (self()->reallySharesSymbol(comp))
            {
            aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            self()->setSharedShadowAliases(aliases, symRefTab);
            }

         if (symRefTab->findGenericIntShadowSymbol())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            self()->setLiteralPoolAliases(aliases, symRefTab);

            if (symRefTab->aliasBuilder.conservativeGenericIntShadowAliasing() || self()->isUnresolved())
               {
               *aliases |= symRefTab->aliasBuilder.genericIntShadowSymRefs();
               *aliases |= symRefTab->aliasBuilder.genericIntArrayShadowSymRefs();
               *aliases |= symRefTab->aliasBuilder.genericIntNonArrayShadowSymRefs();
               }
            }

         if (_symbol->isArrayShadowSymbol() &&
             symRefTab->findGenericIntShadowSymbol())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            *aliases |= symRefTab->aliasBuilder.genericIntShadowSymRefs();
            *aliases |= symRefTab->aliasBuilder.genericIntArrayShadowSymRefs();

            if (supportArrayRefinement && self()->getIndependentSymRefs())
               *aliases -= *self()->getIndependentSymRefs();
            }

#ifdef J9_PROJECT_SPECIFIC
         // make TR::PackedDecimal aliased with TR::Int8(byte)
         if (_symbol->isArrayShadowSymbol() && _symbol->getDataType() == TR::PackedDecimal)
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            aliases->set(symRefTab->getArrayShadowIndex(TR::Int8));
            }
         //the other way around.
         if (_symbol->isArrayShadowSymbol() && _symbol->getDataType() == TR::Int8)
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            aliases->set(symRefTab->getArrayShadowIndex(TR::PackedDecimal));
            }
#endif

         // alias vector arrays shadows  with corresponding scalar array shadows
         if (_symbol->isArrayShadowSymbol() && _symbol->getDataType().isVector())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            aliases->set(symRefTab->getArrayShadowIndex(_symbol->getDataType().vectorToScalar()));
            }
         // the other way around
         if (_symbol->isArrayShadowSymbol() && !_symbol->getDataType().isVector())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            aliases->set(symRefTab->getArrayShadowIndex(_symbol->getDataType().scalarToVector()));
            }

         if (_symbol->isArrayShadowSymbol() &&
             !symRefTab->aliasBuilder.immutableArrayElementSymRefs().isEmpty())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);

            TR::DataType type = _symbol->getDataType();
            TR_BitVectorIterator bvi(symRefTab->aliasBuilder.arrayElementSymRefs());
            int32_t symRefNum;
            while (bvi.hasMoreElements())
               {
               symRefNum = bvi.getNextElement();
               if (symRefTab->getSymRef(symRefNum)->getSymbol()->getDataType() == type)
                  aliases->set(symRefNum);
               }
            }

         if (_symbol->isArrayShadowSymbol() &&
             supportArrayRefinement &&
             comp->getMethodSymbol()->hasVeryRefinedAliasSets())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);

            TR::DataType type = _symbol->getDataType();
            TR_BitVectorIterator bvi(symRefTab->aliasBuilder.arrayElementSymRefs());
            int32_t symRefNum;
            while (bvi.hasMoreElements())
               {
               symRefNum = bvi.getNextElement();
               if (symRefTab->getSymRef(symRefNum)->getSymbol()->getDataType() == type)
                  aliases->set(symRefNum);
               }

            if (self()->getIndependentSymRefs())
               *aliases -= *self()->getIndependentSymRefs();

            return aliases;
            }

         if (aliases)
            aliases->set(self()->getReferenceNumber());

         if (symRefTab->aliasBuilder.unsafeArrayElementSymRefs().get(self()->getReferenceNumber()))
            *aliases -= symRefTab->aliasBuilder.cpSymRefs();
         else if (symRefTab->aliasBuilder.cpSymRefs().get(self()->getReferenceNumber()))
            *aliases -= symRefTab->aliasBuilder.unsafeArrayElementSymRefs();

         return aliases;
         }
      case TR::Symbol::IsStatic:
         {
         // For unresolved constant dynamic, we need to invoke a Java bootstrap method,
         // which can have arbitrary side effects, so the aliasing should be conservative here.
         // isConstObjectRef now returns true for condy, so we add an explicit condition,
         // more like a short-circuit, to say if we are unresolved and not isConstObjectRef
         // (this is the same as before), or if we are unresolved and condy
         // (this is the extra condition added), we would return conservative aliases.
         if ((self()->isUnresolved() && (_symbol->isConstantDynamic() || !_symbol->isConstObjectRef())) ||
	     self()->isLiteralPoolAddress() || self()->isFromLiteralPool() || _symbol->isVolatile())
            {
            return &comp->getSymRefTab()->aliasBuilder.defaultMethodDefAliases();
            }

         TR_BitVector *aliases = NULL;
         if (self()->reallySharesSymbol(comp))
            {
            aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            self()->setSharedStaticAliases(aliases, symRefTab);
            }

         if (symRefTab->findGenericIntShadowSymbol())
            {
            if (!aliases)
               aliases = new (aliasRegion) TR_BitVector(bvInitialSize, aliasRegion, growability);
            self()->setLiteralPoolAliases(aliases, symRefTab);
            }

         if (aliases)
            aliases->set(self()->getReferenceNumber());

         return aliases;
         }
      case TR::Symbol::IsMethodMetaData:
         {
         TR_BitVector *aliases = NULL;
         return aliases;
         }
      default:
         //TR_ASSERT(0, "getUseDefAliasing called for non method");
         if (comp->generateArraylets() && comp->getSymRefTab()->aliasBuilder.gcSafePointSymRefNumbers().get(self()->getReferenceNumber()) && includeGCSafePoint)
            return &comp->getSymRefTab()->aliasBuilder.gcSafePointSymRefNumbers();
         else
            return 0;


      }
   }
Пример #4
0
static int cacheStringAppend(TR::ValuePropagation *vp,TR::Node *node)
   {
   return 0;

   if (!vp->lastTimeThrough())
     return 0;

   TR::TreeTop *tt = vp->_curTree;
   TR::TreeTop *newTree   = tt;
   TR::TreeTop *startTree = 0;
   TR::TreeTop *exitTree  =  vp->_curBlock->getExit();
   TR::Node    *newBuffer;

   if(node->getNumChildren() >= 1)
      newBuffer = node->getFirstChild();
      else
         return 0;

   enum {MAX_STRINGS = 2};
   int        initWithString = 0;
   bool       initWithInteger = false;
   TR::TreeTop *appendTree[MAX_STRINGS+1];
   TR::Node    *appendedString[MAX_STRINGS+1];
   char       pattern[MAX_STRINGS+1];
   int        stringCount = 0;
   bool useStringBuffer=false;
   TR::SymbolReference *valueOfSymRef[MAX_STRINGS+1];
   bool success = false;
   char *sigBuffer="java/lang/StringBuffer.<init>(";
   char *sigBuilder = "java/lang/StringBuilder.<init>(";
   char *sigInit = "java/lang/String.<init>(";


  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   if (checkMethodSignature(vp,node->getSymbolReference(), sigInit))
    {
	  TR::Symbol *symbol =node->getSymbolReference()->getSymbol();
      TR_ResolvedMethod *m = symbol->castToResolvedMethodSymbol()->getResolvedMethod();
      if (strncmp(m->signatureChars(), "(Ljava/lang/String;Ljava/lang/String;)V", m->signatureLength())==0)
        {
	      vp->_cachedStringPeepHolesVcalls.add(new (vp->comp()->trStackMemory()) TR::ValuePropagation::VPTreeTopPair(tt,tt->getPrevRealTreeTop()));
		}
    }
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   if (checkMethodSignature(vp,node->getSymbolReference(), sigBuffer))
      {
         useStringBuffer=true;
         success = true;
      }
   else if (checkMethodSignature(vp,node->getSymbolReference(), sigBuilder))
      {
         success = true;
	     useStringBuffer=false;
      }
	  else
	  {
	     return 0;
	  }


	if (success)
      {
      TR::Symbol *symbol =node->getSymbolReference()->getSymbol();
      TR_ResolvedMethod *m = symbol->castToResolvedMethodSymbol()->getResolvedMethod();
      if (strncmp(m->signatureChars(), "()V", m->signatureLength())==0)
        {
             // Diagnostics
		}else
        {
      	  return 0;
        }
      }
      else // <init> not found (could be unresolved)
      {
         return 0;
      }


   // now search for StringBuffer.append calls that are chained to one another
   TR::TreeTop *lastAppendTree = 0; // updated when we find an append
   TR::Node    *child = newBuffer;

   while (1)
      {
      startTree = tt->getNextRealTreeTop();
	  appendedString[stringCount] = 0;
      int visitCount = 0;
      if (useStringBuffer)
         tt = searchForStringAppend(vp,"java/lang/StringBuffer.append(",
                                    startTree, exitTree, TR::acall, child, visitCount,
                                    appendedString + stringCount);
      else
         tt = searchForStringAppend(vp,"java/lang/StringBuilder.append(",
                                    startTree, exitTree, TR::acall, child, visitCount,
                                    appendedString + stringCount);

	  if (appendedString[stringCount]) // we found it
         {
         appendTree[stringCount] = tt;

         // we could exit here if too many appends are chained
         if (stringCount >= MAX_STRINGS)
            return 0;

         // see which type of append we have
         TR::Symbol *symbol = tt->getNode()->getFirstChild()->getSymbolReference()->getSymbol();
         TR_ASSERT(symbol->isResolvedMethod(), "assertion failure");
         TR::ResolvedMethodSymbol *method = symbol->castToResolvedMethodSymbol();
         TR_ASSERT(method, "assertion failure");
         TR_ResolvedMethod *m = method->getResolvedMethod();
         if (strncmp(m->signatureChars(), "(Ljava/lang/String;)", 20)==0)
            {
            pattern[stringCount] = 'S';
            valueOfSymRef[stringCount] = 0; // don't need conversion to string
            }
         else // appending something that needs conversion using valueOf
            {
            TR::SymbolReference *symRefForValueOf = 0;
            // In the following we can vp->compare only (C) because we know that
            // StringBuffer.append returns a StringBuffer.
            //s
            char *sigBuffer = m->signatureChars();
            TR_ASSERT(m->signatureLength() >= 3, "The minimum signature length should be 3 for ()V");
            }
         stringCount++;
         }
      else // the chain of appends is broken
         {
         appendTree[stringCount] = 0;
         pattern[stringCount] = 0; // string terminator
         break;
         }
      lastAppendTree = tt;
      child = tt->getNode()->getFirstChild(); // the first node is a NULLCHK and its child is the call
      } // end while

   if (stringCount < 2)
      return 0; // cannot apply StringPeepholes
   if (stringCount > MAX_STRINGS)
      return 0;
   if (stringCount == 3)
      return 0; // same as above

   TR_ASSERT(lastAppendTree, "If stringCount <=2 then we must have found an append");

   // now look for the toString call
     TR::TreeTop *toStringTree = 0;
   //visitCount = vp->comp()->incVisitCount();

   int visitCount=0;
   tt = searchForToStringCall(vp,lastAppendTree->getNextRealTreeTop(), exitTree,
                              lastAppendTree->getNode()->getFirstChild(),
                              visitCount, &toStringTree, useStringBuffer);
   if (!toStringTree)
      return 0;

   vp->_cachedStringBufferVcalls.add(new (vp->comp()->trStackMemory()) TR::ValuePropagation::VPStringCached(appendTree[0],appendTree[1],appendedString[0],appendedString[1],newTree,toStringTree));
}