123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2011 by Jonas Maebe,
- member of the Free Pascal development team.
- This file implements support routines for threadvarq with FPC/JVM
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- { In Java, threadvars are represented by descendnts of java.lang.ThreadLocal.
- This class has three important methods: set, get and initialValue.
- If you call the "get" method of a JLThreadLocal instance in a thread for the
- first time before calling "set", it will call the initialValue method and
- return its result. After that, it will return whatever initialValue returned,
- or the previous value instated by "set". A JLThreadLocal always keeps track of
- a JLObject.
- We don't want to translate accesses to threadvars into calls to get/set, since
- that would mean that we would
- a) have to generate different code in the compiler for read and write
- accesses
- b) no be able to pass threadvars to var-parameters etc
- Instead, we add a method called getReadWriteReference to all of our
- descendants classes that returns a pointer to the actual value of the
- threadvar for this thread. This results in several cases:
- a) For primitive types, we store an array of one element of that ordinal
- type.
- Their initialValue is simply an array of one element (automatically
- initialized to 0).
- The pointer returned is the "address" of element 0 (pointers to primitive
- types are internally arrays pointing to element 0).
- b) For non-dynamic arrays, we store that array itself (all arrays are
- internally Java arrays, which descend from JLObject).
- When initializing the threadvar on startup, we pass an empty copy of such
- an array to the constructor and store it. Their initialValue is a deep
- copy of this array, created by fpc_dynarray_copy (it accepts a number of
- dimensions, because it also has to work for making a copy of dynamic
- arrays whose elements are regular arrays).
- The pointer returned is simply the address of the array.
- c) For implicit pointer types other than regular arrays, we also store the
- implicit pointer itself and keep an initialized empty instance around
- that is passed to the constructor.
- Their initialValue is a clone of this empty instance (can't use this for
- arrays, since it would make a shallow copy of the array). Because of the
- way the JLCloneable interface works, we have to call the clone method via
- reflection.
- The pointer returned is again simply the implicit pointer itself.
- d) For all other types, we store an array of JLObject of one element,
- similar as with primitive types.
- Their initialValue is either nil, or optionally a value passed to the
- constructor when creating the JLThreadLocal instance (e.g. an empty
- string for unicodestring/ansistring, or the enum instance whose ordinal
- value is 0)
- The pointer returned is the address of element 0 of the array.
- }
- type
- FpcImplicitPtrThreadVar = class(JLThreadLocal)
- protected
- { all implicit pointer types are clonable }
- fInstanceToClone: JLObject;
- { don't look up the clone method every time }
- fCloneMethod: JLRMethod;
- function initialValue: JLObject; override;
- public
- constructor create(initInstanceToClone: JLObject);
- function getReadWriteReference: Pointer;
- end;
- FpcNormalArrayThreadVar = class sealed (FpcImplicitPtrThreadVar)
- protected
- fArrDim: longint;
- fArrTyp: widechar;
- function initialValue: JLObject; override;
- public
- constructor create(initInstanceToClone: JLObject; arrdim: longint; arrtyp: widechar);
- end;
- FpcBooleanThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PBoolean;
- end;
- FpcByteThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PShortint;
- end;
- FpcShortThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PSmallint;
- end;
- FpcIntThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PLongint;
- end;
- FpcLongThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PInt64;
- end;
- FpcCharThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PWideChar;
- end;
- FpcFloatThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PSingle;
- end;
- FpcDoubleThreadVar = class sealed (JLThreadLocal)
- protected
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PDouble;
- end;
- FpcPointerThreadVar = class sealed (JLThreadLocal)
- protected
- fInitVal: JLObject;
- function initialValue: JLObject; override;
- public
- function getReadWriteReference: PPointer;
- constructor create(initVal: JLObject);overload;
- end;
|