I poked around in the code for TypeSystemImpl a bit and concluded:
1) Re: The Array of arbitrary FSs mechanism, which is implemented to
allow adding additional arrays of specific FS types after the type
system has been committed. The call which actually adds a type is
ts.getArrayType(componentType). The framework seems to avoid calling
this, other than when creating a whole type system. But this method is
public, defined in the TypeSystem interfaqce, and so a user could call
it at any time, on any thread:
/**
* Obtain an array type with component type <code>componentType</code>.
*
* @param componentType
* The type of the elements of the resulting array type. This
can be any type, even
* another array type.
* @return The array type with the corresponding component type.
*/
Type getArrayType(Type componentType);
This method will do a lookup in componentToArrayTypeMap, and if it
doesn't find the component type, it will add it, and update this using a
"put". The componentToArrayTypeMap is a non-synchronized
IntRedBlackTree. So this is a potential failure if this happens in a
multi-threaded environment, via a user calling ts.getArrayType(...).
We probably need to make access to this synchronized, or use some
fancier method of locking.
2) It seems very surprising to me that the synchronization around
get(int) would ever have a collision - it's too tiny a piece of code.
The code for get(int) I think just is an array dereference, contained in
a synchronized method. So - I think something else is causing the
slowdown, but I don't know what that could be. It also could be that
the JProbe code is altering the behavior.
3) We should probably eliminate the call in ll_isArrayType that calls
ll_isValidTypeCode - it's not needed.
4) I think we want to design the TypeSystemImpl so that when it is
"locked" - it is thread-safe for running with multiple threads. This
seems to involve adding synchronization to other object accesses.
(Example object: the "locked" boolean). Because of (2) above, I'm
guessing (hoping) this would not have an impact on performance. Before
it is locked, it can probably be assumed that only one thread will ever
be accessing the type system (is this true / "provable" in the current
design? - if not - I suppose we could make the design thread-safe even
before "committting").
5) The instance of CASMetaData and FSClassRegistry are tied to
instances of TypeSystemImpl, and so, also has to be thread safe.
Note that the FSClassRegistry "generators" already have shadow instances
for each CAS in a CAS Pool that might be running
on different threads.
If we did all this, we still probably haven't solved the problem of
slowdown for xmi serialization. Would be great to have a test case for
this. Greg - can you sanitize up something simple that shows the
problem, and then submit a Jira issue and attach the test as a patch?
-Marshall