Skip to content

Commit

Permalink
Merge pull request #16000 from dylanjtuttle/add-validation-record-for…
Browse files Browse the repository at this point in the history
…-isClassVisible

Add validation record for isClassVisible
  • Loading branch information
dsouzai committed Oct 7, 2022
2 parents f24a7b1 + fa168b8 commit f5a608a
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 41 deletions.
29 changes: 29 additions & 0 deletions runtime/compiler/codegen/J9AheadOfTimeCompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,18 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal
}
break;

case TR_ValidateIsClassVisible:
{
TR_RelocationRecordValidateIsClassVisible *icvRecord = reinterpret_cast<TR_RelocationRecordValidateIsClassVisible *>(reloRecord);

TR::IsClassVisibleRecord *svmRecord = reinterpret_cast<TR::IsClassVisibleRecord *>(relocation->getTargetAddress());

icvRecord->setSourceClassID(reloTarget, symValManager->getSymbolIDFromValue(svmRecord->_sourceClass));
icvRecord->setDestClassID(reloTarget, symValManager->getSymbolIDFromValue(svmRecord->_destClass));
icvRecord->setIsVisible(reloTarget, svmRecord->_isVisible);
}
break;

default:
TR_ASSERT(false, "Unknown relo type %d!\n", kind);
comp->failCompilation<J9::AOTRelocationRecordGenerationFailure>("Unknown relo type %d!\n", kind);
Expand Down Expand Up @@ -2218,6 +2230,23 @@ J9::AheadOfTimeCompile::dumpRelocationHeaderData(uint8_t *cursor, bool isVerbose
}
break;

case TR_ValidateIsClassVisible:
{
TR_RelocationRecordValidateIsClassVisible *icvRecord = reinterpret_cast<TR_RelocationRecordValidateIsClassVisible *>(reloRecord);

self()->traceRelocationOffsets(startOfOffsets, offsetSize, endOfCurrentRecord, orderedPair);
if (isVerbose)
{
traceMsg(
self()->comp(),
"\n Validate Is Class Visible: sourceClassID=%d, destClassID=%d, isVisible=%s ",
(uint32_t)icvRecord->sourceClassID(reloTarget),
(uint32_t)icvRecord->destClassID(reloTarget),
icvRecord->isVisible(reloTarget) ? "true" : "false");
}
}
break;

default:
TR_ASSERT_FATAL(false, "dumpRelocationHeaderData: unknown relo kind %d\n", kind);
}
Expand Down
8 changes: 3 additions & 5 deletions runtime/compiler/env/VMJ9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8426,21 +8426,19 @@ TR_J9SharedCacheVM::isClassVisible(TR_OpaqueClassBlock * sourceClass, TR_OpaqueC
TR_ASSERT(comp, "Should be called only within a compilation");

bool validated = false;
bool isVisible = TR_J9VMBase::isClassVisible(sourceClass, destClass);

if (comp->getOption(TR_UseSymbolValidationManager))
{
TR::SymbolValidationManager *svm = comp->getSymbolValidationManager();
SVM_ASSERT_ALREADY_VALIDATED(svm, sourceClass);
SVM_ASSERT_ALREADY_VALIDATED(svm, destClass);
validated = true;
validated = comp->getSymbolValidationManager()->addIsClassVisibleRecord(sourceClass, destClass, isVisible);
}
else
{
validated = ((TR_ResolvedRelocatableJ9Method *) comp->getCurrentMethod())->validateArbitraryClass(comp, (J9Class *) sourceClass) &&
((TR_ResolvedRelocatableJ9Method *) comp->getCurrentMethod())->validateArbitraryClass(comp, (J9Class *) destClass);
}

return (validated ? TR_J9VMBase::isClassVisible(sourceClass, destClass) : false);
return (validated ? isVisible : false);
}

bool
Expand Down
71 changes: 71 additions & 0 deletions runtime/compiler/runtime/RelocationRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,13 @@ struct TR_RelocationRecordValidateJ2IThunkFromMethodBinaryTemplate : public TR_R
uint16_t _methodID;
};

struct TR_RelocationRecordValidateIsClassVisibleBinaryTemplate : public TR_RelocationRecordBinaryTemplate
{
uint16_t _sourceClassID;
uint16_t _destClassID;
uint8_t _isVisible;
};

// END OF BINARY TEMPLATES

uint8_t
Expand Down Expand Up @@ -854,6 +861,9 @@ TR_RelocationRecord::create(TR_RelocationRecord *storage, TR_RelocationRuntime *
case TR_StaticDefaultValueInstance:
reloRecord = new (storage) TR_RelocationRecordStaticDefaultValueInstance(reloRuntime, record);
break;
case TR_ValidateIsClassVisible:
reloRecord = new (storage) TR_RelocationRecordValidateIsClassVisible(reloRuntime, record);
break;
default:
// TODO: error condition
printf("Unexpected relo record: %d\n", reloType);fflush(stdout);
Expand Down Expand Up @@ -6369,6 +6379,66 @@ TR_RelocationRecordValidateJ2IThunkFromMethod::methodID(TR_RelocationTarget *rel
return reloTarget->loadUnsigned16b((uint8_t *) &((TR_RelocationRecordValidateJ2IThunkFromMethodBinaryTemplate *)_record)->_methodID);
}

TR_RelocationErrorCode
TR_RelocationRecordValidateIsClassVisible::applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation)
{
uint16_t sourceClassID = this->sourceClassID(reloTarget);
uint16_t destClassID = this->destClassID(reloTarget);
bool isVisible = this->isVisible(reloTarget);

if (reloRuntime->comp()->getSymbolValidationManager()->validateIsClassVisibleRecord(sourceClassID, destClassID, isVisible))
return TR_RelocationErrorCode::relocationOK;
else
return TR_RelocationErrorCode::isClassVisibleValidationFailure;
}

void
TR_RelocationRecordValidateIsClassVisible::print(TR_RelocationRuntime *reloRuntime)
{
TR_RelocationTarget *reloTarget = reloRuntime->reloTarget();
TR_RelocationRuntimeLogger *reloLogger = reloRuntime->reloLogger();
TR_RelocationRecord::print(reloRuntime);
reloLogger->printf("\tsourceClassID %d\n", sourceClassID(reloTarget));
reloLogger->printf("\tdestClassID %d\n", destClassID(reloTarget));
reloLogger->printf("\tisVisible %s\n", isVisible(reloTarget) ? "true" : "false");
}

void
TR_RelocationRecordValidateIsClassVisible::setSourceClassID(TR_RelocationTarget *reloTarget, uint16_t sourceClassID)
{
reloTarget->storeUnsigned16b(sourceClassID, (uint8_t *) &((TR_RelocationRecordValidateIsClassVisibleBinaryTemplate *)_record)->_sourceClassID);
}

uint16_t
TR_RelocationRecordValidateIsClassVisible::sourceClassID(TR_RelocationTarget *reloTarget)
{
return reloTarget->loadUnsigned16b((uint8_t *) &((TR_RelocationRecordValidateIsClassVisibleBinaryTemplate *)_record)->_sourceClassID);
}

void
TR_RelocationRecordValidateIsClassVisible::setDestClassID(TR_RelocationTarget *reloTarget, uint16_t destClassID)
{
reloTarget->storeUnsigned16b(destClassID, (uint8_t *) &((TR_RelocationRecordValidateIsClassVisibleBinaryTemplate *)_record)->_destClassID);
}

uint16_t
TR_RelocationRecordValidateIsClassVisible::destClassID(TR_RelocationTarget *reloTarget)
{
return reloTarget->loadUnsigned16b((uint8_t *) &((TR_RelocationRecordValidateIsClassVisibleBinaryTemplate *)_record)->_destClassID);
}

void
TR_RelocationRecordValidateIsClassVisible::setIsVisible(TR_RelocationTarget *reloTarget, bool isVisible)
{
reloTarget->storeUnsigned8b((uint8_t)isVisible, (uint8_t *) &((TR_RelocationRecordValidateIsClassVisibleBinaryTemplate *)_record)->_isVisible);
}

bool
TR_RelocationRecordValidateIsClassVisible::isVisible(TR_RelocationTarget *reloTarget)
{
return (bool)reloTarget->loadUnsigned8b((uint8_t *) &((TR_RelocationRecordValidateIsClassVisibleBinaryTemplate *)_record)->_isVisible);
}


char *
TR_RelocationRecordStaticDefaultValueInstance::name()
Expand Down Expand Up @@ -6528,5 +6598,6 @@ uint32_t TR_RelocationRecord::_relocationRecordHeaderSizeTable[TR_NumExternalRel
0, // TR_VMINLMethod = 109
sizeof(TR_RelocationRecordValidateJ2IThunkFromMethodBinaryTemplate), // TR_ValidateJ2IThunkFromMethod = 110
sizeof(TR_RelocationRecordConstantPoolWithIndexBinaryTemplate), // TR_StaticDefaultValueInstance = 111
sizeof(TR_RelocationRecordValidateIsClassVisibleBinaryTemplate), // TR_ValidateIsClassVisible = 112
};
// The _relocationRecordHeaderSizeTable table should be the last thing in this file
22 changes: 22 additions & 0 deletions runtime/compiler/runtime/RelocationRecord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1929,5 +1929,27 @@ class TR_RelocationRecordStaticDefaultValueInstance : public TR_RelocationRecord
virtual TR_RelocationErrorCode applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocationHigh, uint8_t *reloLocationLow);
};

class TR_RelocationRecordValidateIsClassVisible : public TR_RelocationRecord
{
public:
TR_RelocationRecordValidateIsClassVisible() {}
TR_RelocationRecordValidateIsClassVisible(TR_RelocationRuntime *reloRuntime, TR_RelocationRecordBinaryTemplate *record) : TR_RelocationRecord(reloRuntime, record) {}
virtual bool isValidationRecord() { return true; }
virtual char *name() { return "TR_RelocationRecordValidateIsClassVisible"; }
virtual void preparePrivateData(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget) {}
virtual TR_RelocationErrorCode applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation);

virtual void print(TR_RelocationRuntime *reloRuntime);

void setSourceClassID(TR_RelocationTarget *reloTarget, uint16_t sourceClassID);
uint16_t sourceClassID(TR_RelocationTarget *reloTarget);

void setDestClassID(TR_RelocationTarget *reloTarget, uint16_t destClassID);
uint16_t destClassID(TR_RelocationTarget *reloTarget);

void setIsVisible(TR_RelocationTarget *reloTarget, bool isVisible);
bool isVisible(TR_RelocationTarget *reloTarget);
};

#endif // RELOCATION_RECORD_INCL

35 changes: 18 additions & 17 deletions runtime/compiler/runtime/RelocationRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,24 @@ char *TR_RelocationRuntime::_reloErrorCodeNames[] =
"methodFromSingleInterfaceImplValidationFailure", // 41
"methodFromSingleAbstractImplValidationFailure", // 42
"j2iThunkFromMethodValidationFailure", // 43
"svmValidationFailure", // 44
"wkcValidationFailure", // 45

"classAddressRelocationFailure", // 46
"inlinedMethodRelocationFailure", // 47
"symbolFromManagerRelocationFailure", // 48
"thunkRelocationFailure", // 49
"trampolineRelocationFailure", // 50
"picTrampolineRelocationFailure", // 51
"cacheFullRelocationFailure", // 52
"blockFrequencyRelocationFailure", // 53
"recompQueuedFlagRelocationFailure", // 54
"debugCounterRelocationFailure", // 55
"directJNICallRelocationFailure", // 56
"ramMethodConstRelocationFailure", // 57

"maxRelocationError" // 58
"isClassVisibleValidationFailure", // 44
"svmValidationFailure", // 45
"wkcValidationFailure", // 46

"classAddressRelocationFailure", // 47
"inlinedMethodRelocationFailure", // 48
"symbolFromManagerRelocationFailure", // 49
"thunkRelocationFailure", // 50
"trampolineRelocationFailure", // 51
"picTrampolineRelocationFailure", // 52
"cacheFullRelocationFailure", // 53
"blockFrequencyRelocationFailure", // 54
"recompQueuedFlagRelocationFailure", // 55
"debugCounterRelocationFailure", // 56
"directJNICallRelocationFailure", // 57
"ramMethodConstRelocationFailure", // 58

"maxRelocationError" // 59
};

TR_RelocationRuntime::TR_RelocationRuntime(J9JITConfig *jitCfg)
Expand Down
39 changes: 20 additions & 19 deletions runtime/compiler/runtime/RelocationRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,25 +186,26 @@ struct TR_RelocationError
methodFromSingleInterfaceImplValidationFailure = (41 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,
methodFromSingleAbstractImplValidationFailure = (42 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,
j2iThunkFromMethodValidationFailure = (43 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,
svmValidationFailure = (44 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,
wkcValidationFailure = (45 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,

classAddressRelocationFailure = (46 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
inlinedMethodRelocationFailure = (47 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
symbolFromManagerRelocationFailure = (48 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
thunkRelocationFailure = (49 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
trampolineRelocationFailure = (50 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
picTrampolineRelocationFailure = (51 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
cacheFullRelocationFailure = (52 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
blockFrequencyRelocationFailure = (53 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
recompQueuedFlagRelocationFailure = (54 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
debugCounterRelocationFailure = (55 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
directJNICallRelocationFailure = (56 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
ramMethodConstRelocationFailure = (57 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,

staticDefaultValueInstanceRelocationFailure = (58 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,

maxRelocationError = (59 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::NO_RELO_ERROR
isClassVisibleValidationFailure = (44 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,
svmValidationFailure = (45 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,
wkcValidationFailure = (46 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::VALIDATION,

classAddressRelocationFailure = (47 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
inlinedMethodRelocationFailure = (48 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
symbolFromManagerRelocationFailure = (49 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
thunkRelocationFailure = (50 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
trampolineRelocationFailure = (51 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
picTrampolineRelocationFailure = (52 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
cacheFullRelocationFailure = (53 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
blockFrequencyRelocationFailure = (54 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
recompQueuedFlagRelocationFailure = (55 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
debugCounterRelocationFailure = (56 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
directJNICallRelocationFailure = (57 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,
ramMethodConstRelocationFailure = (58 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,

staticDefaultValueInstanceRelocationFailure = (59 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::RELOCATION,

maxRelocationError = (60 << RELO_ERRORCODE_SHIFT) | TR_RelocationErrorCodeType::NO_RELO_ERROR
};

static uint32_t decode(TR_RelocationErrorCode errorCode) { return static_cast<uint32_t>(errorCode >> RELO_ERRORCODE_SHIFT); }
Expand Down
45 changes: 45 additions & 0 deletions runtime/compiler/runtime/SymbolValidationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,21 @@ TR::SymbolValidationManager::addJ2IThunkFromMethodRecord(void *thunk, TR_OpaqueM
appendNewRecord(thunk, record);
}

bool
TR::SymbolValidationManager::addIsClassVisibleRecord(TR_OpaqueClassBlock *sourceClass, TR_OpaqueClassBlock *destClass, bool isVisible)
{
SVM_ASSERT_ALREADY_VALIDATED(this, sourceClass);
SVM_ASSERT_ALREADY_VALIDATED(this, destClass);

// Skip creating a record when destClass is a Java.lang.Object
// because Object is always visible
if (sourceClass == destClass
|| _fej9->isJavaLangObject(destClass))
return true;

return addVanillaRecord(sourceClass, new (_region) IsClassVisibleRecord(sourceClass, destClass, isVisible));
}



bool
Expand Down Expand Up @@ -1569,6 +1584,17 @@ TR::SymbolValidationManager::validateJ2IThunkFromMethodRecord(uint16_t thunkID,
return validateSymbol(thunkID, thunk, TR::SymbolType::typeOpaque);
}

bool
TR::SymbolValidationManager::validateIsClassVisibleRecord(uint16_t sourceClassID, uint16_t destClassID, bool wasVisible)
{
TR_OpaqueClassBlock *sourceClass = getClassFromID(sourceClassID);
TR_OpaqueClassBlock *destClass = getClassFromID(destClassID);

bool isVisible = _fej9->isClassVisible(sourceClass, destClass);

return (isVisible == wasVisible);
}

bool
TR::SymbolValidationManager::assertionsAreFatal()
{
Expand Down Expand Up @@ -2160,3 +2186,22 @@ void TR::J2IThunkFromMethodRecord::printFields()
traceMsg(TR::comp(), "\t_thunk=0x%p\n", _thunk);
traceMsg(TR::comp(), "\t_method=0x%p\n", _method);
}

bool TR::IsClassVisibleRecord::isLessThanWithinKind(
SymbolValidationRecord *other)
{
TR::IsClassVisibleRecord *rhs = downcast(this, other);
return LexicalOrder::by(_sourceClass, rhs->_sourceClass)
.thenBy(_destClass, rhs->_destClass)
.thenBy(_isVisible, rhs->_isVisible).less();
}

void TR::IsClassVisibleRecord::printFields()
{
traceMsg(TR::comp(), "IsClassVisibleRecord\n");
traceMsg(TR::comp(), "\t_sourceClass=0x%p\n", _sourceClass);
printClass(_sourceClass);
traceMsg(TR::comp(), "\t_destClass=0x%p\n", _destClass);
printClass(_destClass);
traceMsg(TR::comp(), "\t_isVisible=%s\n", _isVisible ? "true" : "false");
}
20 changes: 20 additions & 0 deletions runtime/compiler/runtime/SymbolValidationManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,23 @@ struct J2IThunkFromMethodRecord : public SymbolValidationRecord
TR_OpaqueMethodBlock *_method;
};

struct IsClassVisibleRecord : public SymbolValidationRecord
{
IsClassVisibleRecord(TR_OpaqueClassBlock *sourceClass, TR_OpaqueClassBlock *destClass, bool isVisible)
: SymbolValidationRecord(TR_ValidateIsClassVisible),
_sourceClass(sourceClass),
_destClass(destClass),
_isVisible(isVisible)
{}

virtual bool isLessThanWithinKind(SymbolValidationRecord *other);
virtual void printFields();

TR_OpaqueClassBlock *_sourceClass;
TR_OpaqueClassBlock *_destClass;
bool _isVisible;
};

class SymbolValidationManager
{
public:
Expand Down Expand Up @@ -775,6 +792,7 @@ class SymbolValidationManager
bool addStackWalkerMaySkipFramesRecord(TR_OpaqueMethodBlock *method, TR_OpaqueClassBlock *methodClass, bool skipFrames);
bool addClassInfoIsInitializedRecord(TR_OpaqueClassBlock *clazz, bool isInitialized);
void addJ2IThunkFromMethodRecord(void *thunk, TR_OpaqueMethodBlock *method);
bool addIsClassVisibleRecord(TR_OpaqueClassBlock *sourceClass, TR_OpaqueClassBlock *destClass, bool isVisible);



Expand Down Expand Up @@ -826,6 +844,8 @@ class SymbolValidationManager
// that the thunk loading logic can be confined to RelocationRecord.cpp.
bool validateJ2IThunkFromMethodRecord(uint16_t thunkID, void *thunk);

bool validateIsClassVisibleRecord(uint16_t sourceClassID, uint16_t destClassID, bool wasVisible);


TR_OpaqueClassBlock *getBaseComponentClass(TR_OpaqueClassBlock *clazz, int32_t & numDims);

Expand Down

0 comments on commit f5a608a

Please sign in to comment.