Esempio n. 1
0
uint32_t
FrontEnd::calculateSizeOfStackAtlas(
      bool encodeFourByteOffsets,
      uint32_t numberOfSlotsMapped,
      uint32_t bytesPerStackMap,
      TR::Compilation *comp)
   {
   TR::CodeGenerator *cg = comp->cg();
   TR::GCStackAtlas * stackAtlas = cg->getStackAtlas();

   // Calculate the size of each individual map in the atlas.  The fixed
   // portion of the map contains:
   //
   //    Low Code Offset (2 or 4)
   //    Stack map (depends on # of mapped parms/locals)
   //
   uint32_t sizeOfEncodedCodeOffsetInBytes = encodeFourByteOffsets ? 4 : 2;
   uint32_t sizeOfSingleEncodedMapInBytes = sizeOfEncodedCodeOffsetInBytes;
   sizeOfSingleEncodedMapInBytes += bytesPerStackMap;

   // Calculate the atlas size
   //
   uint32_t atlasSize = sizeof(OMR::StackAtlasPOD);

   ListIterator<TR_GCStackMap> mapIterator(&stackAtlas->getStackMapList());
   TR_GCStackMap *mapCursor = mapIterator.getFirst();

   while (mapCursor != NULL)
      {
      TR_GCStackMap *nextMapCursor = mapIterator.getNext();

      if (!mapsAreIdentical(mapCursor, nextMapCursor, stackAtlas, comp))
         {
         atlasSize += sizeOfSingleEncodedMapInBytes;
         }

      mapCursor = nextMapCursor;
      }

   return atlasSize;
   }
Esempio n. 2
0
uint8_t *
FrontEnd::createStackAtlas(
      bool encodeFourByteOffsets,
      uint32_t numberOfSlotsMapped,
      uint32_t bytesPerStackMap,
      uint8_t *encodedAtlasBaseAddress,
      uint32_t atlasSizeInBytes,
      TR::Compilation *comp)
   {
   TR::CodeGenerator *cg = comp->cg();
   TR::GCStackAtlas *stackAtlas = cg->getStackAtlas();

   stackAtlas->setAtlasBits(encodedAtlasBaseAddress);

   // Calculate the size of each individual map in the atlas.  The fixed
   // portion of the map contains:
   //
   //    Low Code Offset (2 or 4)
   //    Stack map (depends on # of mapped parms/locals)
   //
   uint32_t sizeOfEncodedCodeOffsetInBytes = encodeFourByteOffsets ? 4 : 2;

   uint32_t sizeOfSingleEncodedMapInBytes = sizeOfEncodedCodeOffsetInBytes;
   sizeOfSingleEncodedMapInBytes += bytesPerStackMap;

   // Encode the atlas
   //
   OMR::StackAtlasPOD *pyAtlas = (OMR::StackAtlasPOD *)encodedAtlasBaseAddress;
   pyAtlas->numberOfMaps = stackAtlas->getNumberOfMaps();
   pyAtlas->bytesPerStackMap = bytesPerStackMap;

   // Offset to the MAPPED pyFrameObject parameter
   //
   pyAtlas->frameObjectParmOffset = 0;

   // Lowest stack offset where MAPPED locals begin.
   //
   pyAtlas->localBaseOffset = stackAtlas->getLocalBaseOffset();

   // Abort if we have overflowed the fields in pyAtlas.
   //
   if (bytesPerStackMap > USHRT_MAX ||
       stackAtlas->getNumberOfMaps() > USHRT_MAX ||
       stackAtlas->getNumberOfParmSlotsMapped() > USHRT_MAX ||
       stackAtlas->getParmBaseOffset()  < SHRT_MIN || stackAtlas->getParmBaseOffset()  > SHRT_MAX ||
       stackAtlas->getLocalBaseOffset() < SHRT_MIN || stackAtlas->getLocalBaseOffset() > SHRT_MAX)
      {
      comp->failCompilation<TR::CompilationException>("Overflowed the fields in pyAtlas");
      }

   // Maps are in reverse order in list from what we want in the atlas
   // so advance to the address where the last map should go and start
   // building the maps moving back toward the beginning of the atlas.
   //
   uint8_t *cursorInEncodedAtlas = encodedAtlasBaseAddress + atlasSizeInBytes;

   ListIterator<TR_GCStackMap> mapIterator(&stackAtlas->getStackMapList());
   TR_GCStackMap *mapCursor = mapIterator.getFirst();

   while (mapCursor != NULL)
      {
      // Move back from the end of the atlas till the current map can be fit in,
      // then pass the cursor to the routine that actually creates and fills in
      // the stack map
      //
      TR_GCStackMap *nextMapCursor = mapIterator.getNext();

      if (!mapsAreIdentical(mapCursor, nextMapCursor, stackAtlas, comp))
         {
         cursorInEncodedAtlas -= sizeOfSingleEncodedMapInBytes;
         encodeStackMap(mapCursor, cursorInEncodedAtlas, encodeFourByteOffsets, bytesPerStackMap, comp);
         }

      mapCursor = nextMapCursor;
      }

   return encodedAtlasBaseAddress;
   }