fpc/rtl/java/jtvarh.inc
Jonas Maebe a2a0436347 + support for threadvars in the JVM based on JLThreadLocal; see
rtl/java/jtvarh.inc for the details

git-svn-id: branches/jvmbackend@18820 -
2011-08-23 17:45:01 +00:00

167 lines
5.6 KiB
PHP

{
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;