Skip to content

Commit

Permalink
Merge pull request #10644 from dsouzai/reloFailure
Browse files Browse the repository at this point in the history
Reduce AOT load failures with SVM enabled
  • Loading branch information
mpirvu committed Sep 18, 2020
2 parents 0887828 + 7c2f23a commit c363c49
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
76 changes: 55 additions & 21 deletions runtime/compiler/runtime/SymbolValidationManager.cpp
Expand Up @@ -38,7 +38,25 @@
#define snprintf _snprintf
#endif

static const char * const jlthrowableName = "java/lang/Throwable";
TR::SymbolValidationManager::SystemClassNotWorthRemembering
TR::SymbolValidationManager::_systemClassesNotWorthRemembering[] = {

/* Generally, classes that inherit from java/lang/Throwable are used to indicate exception
* conditions; as such, they are not going be important for the performance of normal mainline
* code. Therefore, it is better for the AOT compiler to not be aware of these classes (and
* thereby lose the ability to optimize for them) rather than risk a load failure due to a code
* path that was unlikely to execute.
*/
{ "java/lang/Throwable", NULL, true },

/* Newer java code is moving towards using StringBuilder. Therefore, ignoring this class
* reduces load failures, while having minimal impact on steady state throughput.
*/
{ "java/lang/StringBuffer", NULL, false },

/* Terminating entry */
{ NULL, NULL, false }
};

TR::SymbolValidationManager::SymbolValidationManager(TR::Region &region, TR_ResolvedMethod *compilee)
: _symbolID(FIRST_ID),
Expand All @@ -64,8 +82,7 @@ TR::SymbolValidationManager::SymbolValidationManager(TR::Region &region, TR_Reso
_idToSymbolTable(_region),
_seenSymbolsSet((SeenSymbolsComparator()), _region),
_wellKnownClasses(_region),
_loadersOkForWellKnownClasses(_region),
_jlthrowable(_fej9->getSystemClassFromClassName(jlthrowableName, (int32_t)strlen(jlthrowableName)))
_loadersOkForWellKnownClasses(_region)
{
assertionsAreFatal(); // Acknowledge the env var whether or not assertions fail

Expand Down Expand Up @@ -108,31 +125,43 @@ TR::SymbolValidationManager::defineGuaranteedID(void *symbol, TR::SymbolType typ
bool
TR::SymbolValidationManager::isClassWorthRemembering(TR_OpaqueClassBlock *clazz)
{
if (!_jlthrowable)
_jlthrowable = _fej9->getSystemClassFromClassName(jlthrowableName, (int32_t)strlen(jlthrowableName));
bool worthRemembering = true;

/* This heuristic checks whether the class being considered is, or inherits from, java/lang/Throwable.
* If it is, the class is deemed not worth remembering. The reason for this is to reduce the chances
* of an AOT load failure. Generally, classes that inherit from java/lang/Throwable are used to indicate
* exception conditions; as such, they are not going be important for the performance of normal mainline
* code. Therefore, it is better for the compiler to not be aware of these classes (and thereby lose the
* ability to optimize for them) rather than risk a load failure due to a code path that was unlikely to
* execute.
*/
if (_jlthrowable && _fej9->isSameOrSuperClass((J9Class *)_jlthrowable, (J9Class *)clazz))
for (int i = 0; worthRemembering && _systemClassesNotWorthRemembering[i]._className; i++)
{
if (_comp->getOption(TR_TraceRelocatableDataCG))
traceMsg(_comp, "isClassWorthRemembering: clazz %p is or inherits from jlthrowable\n", clazz);
return false;
SystemClassNotWorthRemembering *systemClassNotWorthRemembering = &_systemClassesNotWorthRemembering[i];
if (!systemClassNotWorthRemembering->_clazz)
{
systemClassNotWorthRemembering->_clazz = _fej9->getSystemClassFromClassName(
systemClassNotWorthRemembering->_className,
(int32_t)strlen(systemClassNotWorthRemembering->_className));
}

if (systemClassNotWorthRemembering->_checkIsSuperClass)
{
if (systemClassNotWorthRemembering->_clazz &&
_fej9->isSameOrSuperClass((J9Class *)systemClassNotWorthRemembering->_clazz, (J9Class *)clazz))
{
if (_comp->getOption(TR_TraceRelocatableDataCG))
traceMsg(_comp, "isClassWorthRemembering: clazz %p is or inherits from %s (%p)\n",
clazz, systemClassNotWorthRemembering->_className, systemClassNotWorthRemembering->_clazz);

worthRemembering = false;
}
}
else
{
worthRemembering = (clazz != systemClassNotWorthRemembering->_clazz);
}
}

return true;
return worthRemembering;
}

void
TR::SymbolValidationManager::populateWellKnownClasses()
{
#define WELL_KNOWN_CLASS_COUNT 10
#define WELL_KNOWN_CLASS_COUNT 9
#define REQUIRED_WELL_KNOWN_CLASS_COUNT 1

// Classes must have names only allowed to be defined by the bootstrap loader
Expand All @@ -146,7 +175,6 @@ TR::SymbolValidationManager::populateWellKnownClasses()
"java/lang/Runnable",
"java/lang/String",
"java/lang/StringBuilder",
"java/lang/StringBuffer",
"java/lang/System",
"java/lang/ref/Reference",
"com/ibm/jit/JITHelpers",
Expand Down Expand Up @@ -601,8 +629,11 @@ TR::SymbolValidationManager::addMultipleArrayRecords(TR_OpaqueClassBlock *compon
bool
TR::SymbolValidationManager::addMethodRecord(TR::MethodValidationRecord *record)
{
if (shouldNotDefineSymbol(record->_method))
if (shouldNotDefineSymbol(record->_method)
|| !isClassWorthRemembering(_fej9->getClassOfMethod(record->_method)))
{
return abandonRecord(record);
}

if (recordExists(record))
{
Expand Down Expand Up @@ -944,6 +975,9 @@ TR::SymbolValidationManager::addStackWalkerMaySkipFramesRecord(TR_OpaqueMethodBl
bool
TR::SymbolValidationManager::addClassInfoIsInitializedRecord(TR_OpaqueClassBlock *clazz, bool isInitialized)
{
if (!isClassWorthRemembering(clazz))
return false;

SVM_ASSERT_ALREADY_VALIDATED(this, clazz);
return addVanillaRecord(clazz, new (_region) ClassInfoIsInitialized(clazz, isInitialized));
}
Expand Down
9 changes: 8 additions & 1 deletion runtime/compiler/runtime/SymbolValidationManager.hpp
Expand Up @@ -635,6 +635,13 @@ class SymbolValidationManager

SymbolValidationManager(TR::Region &region, TR_ResolvedMethod *compilee);

struct SystemClassNotWorthRemembering
{
const char * const _className;
TR_OpaqueClassBlock *_clazz;
const bool _checkIsSuperClass;
};

void populateWellKnownClasses();
bool validateWellKnownClasses(const uintptr_t *wellKnownClassChainOffsets);
bool isWellKnownClass(TR_OpaqueClassBlock *clazz);
Expand Down Expand Up @@ -904,7 +911,7 @@ class SymbolValidationManager
typedef std::set<ClassFromAnyCPIndex, LessClassFromAnyCPIndex, ClassFromAnyCPIndexAlloc> ClassFromAnyCPIndexSet;
ClassFromAnyCPIndexSet _classesFromAnyCPIndex;

TR_OpaqueClassBlock *_jlthrowable;
static SystemClassNotWorthRemembering _systemClassesNotWorthRemembering[];
};

}
Expand Down

0 comments on commit c363c49

Please sign in to comment.