-
Notifications
You must be signed in to change notification settings - Fork 903
fix logic for obtaining TypeInfoFactory #1961
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
fix logic for obtaining TypeInfoFactory #1961
Conversation
|
While you're in there, I think you may have a race in static TypeInfoFactory get(Scriptable scope) {
TypeInfoFactory got =
(TypeInfoFactory) ScriptableObject.getTopScopeValue(scope, "TypeInfoFactory");
if (got == null) {
// we expect this to not happen frequently, so computing top scope twice is acceptable
var topScope = ScriptableObject.getTopLevelScope(scope);
if (!(topScope instanceof ScriptableObject)) {
// Note: it's originally a RuntimeException, the super class of
// IllegalArgumentException, so this will not break error catching
throw new IllegalArgumentException(
"top scope have no associated TypeInfoFactory and cannot have TypeInfoFactory associated due to not being a ScriptableObject");
}
got = new ConcurrentFactory();
got.associate(((ScriptableObject) topScope));
}
return got;
}You aren't checking the result of
|
|
@ZZZank I think, we should remove the lazy init and change the code if (got == null) {
// we expect this to not happen frequently, so computing top scope twice is acceptable
var topScope = ScriptableObject.getTopLevelScope(scope);
if (!(topScope instanceof ScriptableObject)) {
// Note: it's originally a RuntimeException, the super class of
// IllegalArgumentException, so this will not break error catching
throw new IllegalArgumentException(
"top scope have no associated TypeInfoFactory and cannot have TypeInfoFactory associated due to not being a ScriptableObject");
}
got = new ConcurrentFactory();
got.associate(((ScriptableObject) topScope));
}to if (got == null) { // or just return null?
throw new IllegalArgumentException(
"top scope have no associated TypeInfoFactory and cannot have TypeInfoFactory associated due to not being a ScriptableObject");
}Unfortunately, I don't remember why we need this lazy-init: the (de)serialization roundtrip should be fixed and I think if you get no TypeInfoFactory, this means there is a programming error. Or am I missing something? |
|
Tests failed again due to the removal of lazy init. Will do some more research tomorrow And a note for myself: global factory for scope independent action |
|
Thanks - there's a lot in this TypeInfoFactory stuff, but I see what it's doing I'm trying to figure out the impact of this -- since the "ConcurrentFactory" is global, and doesn't do any GC via weak references, I'm trying to ensure that an environment that might use a JVM to start and stop lots and lots of tests doesn't end up with a memory leak. I don't think so because it seems like the default behavior is that each context gets its own factory associated with the top level scope, right? |
|
The default behaviour now is:
So either the factory itself or the cached objects in factory can be garbage collected, so no memory leak I believe |
|
That seems OK to me. Looks like a few people have had a chance to look at it, so I'll get to it soon. Thanks! |
|
Oooh -- first time for this -- upon rebasing, we have a failure in the "decycle" test, which we added recently. @rPraml is our expert in this, I believe, as this either suggests that the implementation should change or we should add some exceptions in the configuration of the cycle detector. |
This reverts commit edfe340.
ed06b62 to
e755465
Compare
rPraml
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| scope.associateValue(LIBRARY_SCOPE_KEY, scope); | ||
| new ClassCache().associate(scope); | ||
| new ConcurrentFactory().associate(scope); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with that. We can move that later to LcBridge (or whatever concept we make)
https://github.com/mozilla/rhino/pull/1983/files#diff-24249e911005a5f57fee7790be93c8a477f7584f853110544bd704cc971277e9R169
| ignoring from: "org.mozilla.javascript.ScriptableObject", to: "org.mozilla.javascript.lc.type.TypeInfoFactory" | ||
| ignoring from: "org.mozilla.javascript.FunctionObject", to: "org.mozilla.javascript.lc.type.TypeInfo*" | ||
| ignoring from: "org.mozilla.javascript.Context", to: "org.mozilla.javascript.lc.type.TypeInfo*" | ||
| ignoring from: "org.mozilla.javascript.ScriptRuntime", to: "org.mozilla.javascript.lc.type.TypeInfoFactory" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both? (probably... TypeInfoFactory implements TypeInfo)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we need. My guess is that the .associate(...) method is from TypeInfoFactory, and Decycle consider it as a reference to TypeInfoFactory
|
OK -- this looks good now. Thanks! |
The
TypeInfoFactoryused inFunctionObjectis currently obtained via:where the
thisis FunctionObject itself, which doesn't make any sense because it's trying to obtained a TypeInfoFactory from a not-yet-initialized object.scopeshould be used instead.I also added a test case for it
EDIT: lazy-init for TypeInfoFactory is removed now, using a custom factory now requires: