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; }
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; }