Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Round maxRequiredSize to match romSize calculation #7104

Merged
merged 2 commits into from
Sep 19, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 9 additions & 37 deletions runtime/bcutil/ROMClassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,7 @@ ROMClassBuilder::prepareAndLaydown( BufferManager *bufferManager, ClassFileParse
if (isLambda) {
/* calculate the romSize to compare the ROM sizes in the compareROMClassForEquality method for lambda classes */
romSize = U_32(sizeInformation.rcWithOutUTF8sSize + sizeInformation.utf8sSize + sizeInformation.rawClassDataSize + sizeInformation.varHandleMethodTypeLookupTableSize);
/* round up to sizeof(U_64) */
romSize += (sizeof(U_64) - 1);
romSize &= ~(sizeof(U_64) - 1);
romSize = ROUND_UP_TO_POWEROF2(romSize, sizeof(U_64));
}

if ( context->shouldCompareROMClassForEquality() ) {
Expand Down Expand Up @@ -599,17 +597,13 @@ ROMClassBuilder::prepareAndLaydown( BufferManager *bufferManager, ClassFileParse
sizeRequirements.romClassMinimalSize =
U_32(sizeInformation.rcWithOutUTF8sSize
+ sizeInformation.utf8sSize + sizeInformation.rawClassDataSize + sizeInformation.varHandleMethodTypeLookupTableSize);
/* round up to sizeof(U_64) */
sizeRequirements.romClassMinimalSize += (sizeof(U_64) - 1);
sizeRequirements.romClassMinimalSize &= ~(sizeof(U_64) - 1);
sizeRequirements.romClassMinimalSize = ROUND_UP_TO_POWEROF2(sizeRequirements.romClassMinimalSize, sizeof(U_64));

sizeRequirements.romClassSizeFullSize =
U_32(sizeRequirements.romClassMinimalSize
+ sizeInformation.lineNumberSize
+ sizeInformation.variableInfoSize);
/* round up to sizeof(U_64) */
sizeRequirements.romClassSizeFullSize += (sizeof(U_64) - 1);
sizeRequirements.romClassSizeFullSize &= ~(sizeof(U_64)-1);
sizeRequirements.romClassSizeFullSize = ROUND_UP_TO_POWEROF2(sizeRequirements.romClassSizeFullSize, sizeof(U_64));


sizeRequirements.lineNumberTableSize = U_32(sizeInformation.lineNumberSize);
Expand Down Expand Up @@ -701,31 +695,11 @@ ROMClassBuilder::prepareAndLaydown( BufferManager *bufferManager, ClassFileParse
lineNumberBuffer = allocatedBuffers.lineNumberBuffer;
variableInfoBuffer = allocatedBuffers.variableInfoBuffer;
} else {
if (countDebugDataOutOfLine) {
/* Pad maxRequiredSize to the size to sizeof(U_64) in order to prevent memory corruption.
*
* In rare cases it is possible that maxRequiredSize is 2 bytes too small, due to
* counting the data 'out-of-line', and then writing the debug data 'in-line' with
* padding U_64 adjustments. The extra 2 bytes is a result of a switch from U_16
* alignment for debug data (when writing out of line), to U_32 alignment (when
* writing inline). It should also be noted that these extra 2 bytes are only
* visible when only one method with debug data exists. If there are more, then the removal
* of 'SRPs to debug data' from each method will hide the extra padding for in-line
* debug data.
*
* Without this padding any new segment returned by the below call to allocate could be
* too small to contain the rom class that is about to be written.
*
* Note: When the problem described above occurs maxRequiredSize will not be U_64 aligned
* until the below code runs.
*/
UDATA alignmentBits = (sizeof (U_64) - 1);
UDATA adjustedCount = (maxRequiredSize + alignmentBits) & ~alignmentBits;
UDATA bytesToPad = adjustedCount - maxRequiredSize;
if (0 != bytesToPad) {
maxRequiredSize += bytesToPad;
}
}
/* Pad maxRequiredSize to the size to sizeof(U_64) in order to prevent memory corruption.
* This mirrors ROM class padding in finishPrepareAndLaydown when the final ROM class size
* is calculated.
*/
maxRequiredSize = ROUND_UP_TO_POWEROF2(maxRequiredSize, sizeof(U_64));
romClassBuffer = context->allocationStrategy()->allocate(maxRequiredSize);
}
if ( romClassBuffer == NULL ) {
Expand Down Expand Up @@ -1041,9 +1015,7 @@ ROMClassBuilder::finishPrepareAndLaydown(
* Record the romSize as the final size of the ROMClass with interned strings space removed.
*/
U_32 romSize = U_32(sizeInformation->rcWithOutUTF8sSize + sizeInformation->utf8sSize + sizeInformation->rawClassDataSize + sizeInformation->varHandleMethodTypeLookupTableSize);
/* round up to sizeof(U_64) */
romSize += (sizeof(U_64) - 1);
romSize &= ~(sizeof(U_64) - 1);
romSize = ROUND_UP_TO_POWEROF2(romSize, sizeof(U_64));

/*
* update the SRP Offset Table with the base addresses for main ROMClass section (RC_TAG),
Expand Down