You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/04/18 07:23:40 UTC
svn commit: r529873 [3/3] - in /harmony/enhanced/drlvm/trunk:
build/custom/msvc_2003/jitrino/ build/custom/msvc_2005/jitrino/
vm/include/open/ vm/jitrino/src/codegenerator/ia32/ vm/thread/src/
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h Tue Apr 17 22:23:39 2007
@@ -379,13 +379,15 @@
-/*
- * FS14_TLS_USE
- *
- * FS14_TLS_USE declaration turns on windows specific TLS access optimization
- * We use free TIB slot with 14 offset, see following article for details
- * http://www.microsoft.com/msj/archive/S2CE.aspx (currently it's used on
- * Windows 32-bit)
+/**
+ * HYTHREAD_FAST_TLS
+ * Enables platform-specific TLS access optimization, such as:
+ * - On Win32, free TIB slot is used via direct reference FS:[0x14]
+ * (see http://www.microsoft.com/msj/archive/S2CE.aspx);
+ * - On Linuxes, initial-exec TLS model allows to address static TLS directly,
+ * via GS:[0] on IA32 and FS:[0] on x86_64
+ * (see http://people.redhat.com/drepper/tls.pdf)
+ *
*
* APR_TLS_USE
*
@@ -400,25 +402,37 @@
-#if (defined (WIN32) && !defined (_WIN64))
-
+#if (defined (_WIN32) && !defined (_WIN64))
//use optimized asm monitor enter and exit helpers
#define ASM_MONITOR_HELPER
+#endif
-// FS14_TLS_USE define turns on windows specific TLS access optimization
-// We use free TIB slot with 14 offset, see following article for details
-// http://www.microsoft.com/msj/archive/S2CE.aspx
-#define FS14_TLS_USE
-
-#elif defined _WIN64
-#define APR_TLS_USE
+#if defined (_WIN32)
+# define HYTHREAD_FAST_TLS_ATTRIBUTE
+# if defined(_IA32_)
+# define HYTHREAD_FAST_TLS (1)
+ // FIXME suggested to drop FS14_TLS_USE in favor of common HYTHREAD_FAST_TLS
+# define FS14_TLS_USE
+# else
+# define APR_TLS_USE
+# endif
+#elif defined(__linux__)
+ // some kind of nix - the threads internals are known for IA32/Intel64
+ // kernels, will use slow way on other HWs (TODO: add IPF support)
+# if defined(_IA32_) || defined(_EM64T_)
+# define HYTHREAD_FAST_TLS (1)
+# define HYTHREAD_FAST_TLS_ATTRIBUTE __attribute__((tls_model("initial-exec")))
+# endif
+#else
+# undef HYTHREAD_FAST_TLS
#endif
+#if !defined(HYTHREAD_FAST_TLS)
+# define HYTHREAD_FAST_TLS_ATTRIBUTE
+#endif
-
#ifdef APR_TLS_USE
-
#ifdef __cplusplus
extern "C" {
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Tue Apr 17 22:23:39 2007
@@ -206,6 +206,8 @@
UDATA VMCALL hythread_tls_get_offset(hythread_tls_key_t key);
UDATA VMCALL hythread_tls_get_request_offset();
UDATA VMCALL hythread_get_thread_times(hythread_t thread, int64* pkernel, int64* puser);
+UDATA VMCALL hythread_uses_fast_tls(void);
+IDATA VMCALL hythread_get_hythread_offset_in_tls(void);
//@}
/** @name Conditional variable
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp Tue Apr 17 22:23:39 2007
@@ -16,17 +16,17 @@
*/
/**
* @author George A. Timoshenko
- * @version $Revision: 1.1.12.3.4.3 $
*/
#include "Ia32IRManager.h"
#include "VMInterface.h"
+#include "Ia32Tls.h"
+#include <open/hythread_ext.h>
namespace Jitrino
{
namespace Ia32{
-
const uint32 BBPollingMaxVersion = 6;
//========================================================================================
@@ -61,8 +61,8 @@
#endif
loopHeaderOfEdge(irManager.getMemoryManager())
{
+ gcFlagOffsetOffset = VMInterface::flagTLSSuspendRequestOffset();
calculateInitialInterruptability(version == 5 || version == 6);
-
if (version == 2 || version == 3)
calculateInterruptablePathes();
// no more calculations here, just collect the edges!
@@ -136,7 +136,7 @@
// 2 - path analysis based on searching of pairs [isOnThreadInterruptablePath]->[!isOnThreadInterruptablePath]
// 3 - recursive version of "2"
// 4 - "1" + suspension flag addr [TLS base + offset] is calculated before the loop header
- // 5 - like "1" but some backedges are not patched (if all paths through it are interuuptable)
+ // 5 - like "1" but some backedges are not patched (if all paths through it are uninterpretable)
// 6 - "4" + "5"
// 7.. illegal
uint32 version;
@@ -158,16 +158,19 @@
BBPControllersMap bbpCFGControllerForNode;
// to get the toppest loop header of the given without calling getLoopHeader
StlVector<Node*> toppestLoopHeader;
- // start index in otheredges collection for the toppest loop headers
+ // start index in otheredges collection for the topmost loop headers
StlVector<uint32> otherStartNdx;
// just a collection of loop headers of the method (Basic blocks only!)
StlVector<Node*> loopHeaders;
- // edgse which are not a back edge
+ // edges which are not a back edge
StlVector<Edge*> otherEdges;
// edges for inserting BBPolling subCFG
StlVector<Edge*> eligibleEdges;
+ /// Offset of the suspension flag in the VM's structure stored in TLS.
+ uint32 gcFlagOffsetOffset;
+
#ifdef _DEBUG
uint32 interruptablePoints;
uint32 pollingPoints;
@@ -189,7 +192,6 @@
if(!lt->hasLoops()) {
return;
}
-
version = getIntArg("version", 6);
if(version == 0) {
return;
@@ -238,9 +240,6 @@
static ActionFactory<BBPollingTransformer> _bbp("bbp");
-
-const uint32 gcFlagOffsetOffset = VMInterface::flagTLSSuspendRequestOffset();
-
Opnd*
BBPolling::getOrCreateTLSBaseReg(Edge* e)
{
@@ -253,64 +252,50 @@
Opnd* tlsBaseReg = tlsBaseRegForLoopHeader[id];
if ( tlsBaseReg ) { // it is already created for this loop
return tlsBaseReg;
- } else {
+ }
+
+ Type* tlsBaseType = irManager.getTypeManager().getUnmanagedPtrType(irManager.getTypeManager().getIntPtrType());
- Type* tlsBaseType;
-#ifdef _EM64T_
- tlsBaseType = irManager.getTypeManager().getUnmanagedPtrType(irManager.getTypeManager().getIntPtrType());
- tlsBaseReg = irManager.newOpnd(tlsBaseType, Constraint(OpndKind_GPReg));
+#ifdef _EM64T_
+ tlsBaseReg = irManager.newOpnd(tlsBaseType, Constraint(OpndKind_GPReg));
#else
- tlsBaseType = irManager.getTypeManager().getPrimitiveType(Type::Int32);
- tlsBaseReg = irManager.newOpnd(tlsBaseType, Constraint(RegName_EAX)|
- RegName_EBX |
- RegName_ECX |
- RegName_EDX |
- RegName_EBP |
- RegName_ESI |
- RegName_EDI);
+ tlsBaseReg = irManager.newOpnd(tlsBaseType, Constraint(RegName_EAX)|
+ RegName_EBX |
+ RegName_ECX |
+ RegName_EDX |
+ RegName_EBP |
+ RegName_ESI |
+ RegName_EDI);
#endif
- // Basic Block for flag address calculating. (To be inserted before the loopHeaders)
- Node * bbpFlagAddrBlock = irManager.getFlowGraph()->createBlockNode();
-#if defined (PLATFORM_POSIX) || defined (_EM64T_)
- // TLS base can be obtained by calling get_thread_ptr() (from vm_threads.h)
- Opnd * target=irManager.newImmOpnd( irManager.getTypeManager().getUnmanagedPtrType(irManager.getTypeManager().getIntPtrType()),
- Opnd::RuntimeInfo::Kind_HelperAddress,
- (void*)CompilationInterface::Helper_GetTLSBase
- );
- Opnd* tlsBase = irManager.newOpnd(tlsBaseType);
- bbpFlagAddrBlock->appendInst(irManager.newCallInst(target, &CallingConvention_STDCALL, 0, NULL, tlsBase));
-#else // PLATFORM_POSIX
- // TLS base can be obtained from [fs:0x14]
- Opnd* tlsBase = irManager.newMemOpnd(tlsBaseType, MemOpndKind_Any, NULL, 0x14, RegName_FS);
-#endif // PLATFORM_POSIX
-
- if (version == 4 || version == 6) {
- Opnd * offset = irManager.newImmOpnd(tlsBaseType, gcFlagOffsetOffset);
- bbpFlagAddrBlock->appendInst(irManager.newInstEx(Mnemonic_ADD, 1, tlsBaseReg, tlsBase, offset));
- } else {
- bbpFlagAddrBlock->appendInst(irManager.newInst(Mnemonic_MOV, tlsBaseReg, tlsBase));
- }
+ // Basic Block for flag address calculating. (To be inserted before the loopHeaders)
+ Node * bbpFlagAddrBlock = irManager.getFlowGraph()->createBlockNode();
+ Opnd* tlsBase = createTlsBaseLoadSequence(irManager, bbpFlagAddrBlock);
+
+ if (version == 4 || version == 6) {
+ Opnd * offset = irManager.newImmOpnd(tlsBaseType, gcFlagOffsetOffset);
+ bbpFlagAddrBlock->appendInst(irManager.newInstEx(Mnemonic_ADD, 1, tlsBaseReg, tlsBase, offset));
+ } else {
+ bbpFlagAddrBlock->appendInst(irManager.newInst(Mnemonic_MOV, tlsBaseReg, tlsBase));
+ }
- // inserting bbpFlagAddrBlock before the given loopHeader
- uint32 startIndex = otherStartNdx[id];
+ // inserting bbpFlagAddrBlock before the given loopHeader
+ uint32 startIndex = otherStartNdx[id];
- ControlFlowGraph* fg = irManager.getFlowGraph();
- for (uint32 otherIdx = startIndex; ; otherIdx++) {
- if (otherIdx == otherEdges.size())
- break;
- Edge* other = otherEdges[otherIdx];
- if (other->getTargetNode() != loopHeader)
- break;
-
- fg->replaceEdgeTarget(other, bbpFlagAddrBlock);
- }
-
- assert(loopHeader->isBlockNode());
- fg->addEdge(bbpFlagAddrBlock, loopHeader, 1);
-
- tlsBaseRegForLoopHeader[id] = tlsBaseReg;
- return tlsBaseReg;
+ ControlFlowGraph* fg = irManager.getFlowGraph();
+ for (uint32 otherIdx = startIndex; ; otherIdx++) {
+ if (otherIdx == otherEdges.size())
+ break;
+ Edge* other = otherEdges[otherIdx];
+ if (other->getTargetNode() != loopHeader)
+ break;
+ fg->replaceEdgeTarget(other, bbpFlagAddrBlock);
}
+
+ assert(loopHeader->isBlockNode());
+ fg->addEdge(bbpFlagAddrBlock, loopHeader, 1);
+
+ tlsBaseRegForLoopHeader[id] = tlsBaseReg;
+ return tlsBaseReg;
}
Node*
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Encoder.cpp Tue Apr 17 22:23:39 2007
@@ -28,9 +28,10 @@
namespace Jitrino {
namespace Ia32 {
-//fixme64: for adapter needs
-bool is_ptr_type(const Type* typ) {
- switch(typ->tag) {
+#ifdef _EM64T_
+ //FIXME64: for adapter needs
+ static bool is_ptr_type(const Type* typ) {
+ switch(typ->tag) {
case Type::TypedReference:
case Type::SystemObject:
case Type::SystemString:
@@ -45,10 +46,34 @@
case Type::VTablePtrObj:
case Type::ITablePtrObj:
return true;
- default:
- break;
+ default:
+ break;
+ }
+ return false;
+ }
+#endif // _EM64T_
+
+static InstPrefix getInstPrefixFromSReg(RegName reg) {
+ if (reg == RegName_Null) {
+ return InstPrefix_Null;
+ }
+ if (reg == RegName_FS) {
+ return InstPrefix_FS;
+ }
+ if (reg == RegName_GS) {
+ return InstPrefix_GS;
+ }
+ if (reg == RegName_DS) {
+ return InstPrefix_DS;
+ }
+ if (reg == RegName_ES) {
+ return InstPrefix_ES;
+ }
+ if (reg == RegName_CS) {
+ return InstPrefix_CS;
}
- return false;
+ assert(false);
+ return InstPrefix_Null;
}
@@ -188,11 +213,6 @@
Opnd * const * opnds = inst->getOpnds();
const uint32 * roles = inst->getOpndRoles();
- //emit inst prefix
- if (inst->getPrefix()!=InstPrefix_Null) {
- stream = (uint8*)EncoderBase::prefix((char*)stream, inst->getPrefix());
- }
-
for( int idx=0, n=inst->getOpndCount(); idx<n; idx++ ) {
if (!(roles[idx] & Inst::OpndRole_Explicit)) continue;
const Opnd * p = opnds[idx];
@@ -232,7 +252,8 @@
RegName baseReg = pbase == NULL ? RegName_Null : pbase->getRegName();
RegName indexReg = pindex == NULL ? RegName_Null : pindex->getRegName();
#ifdef _EM64T_
- // adapter: all PTR types go as 64 bits
+ // FIXME64 adapter: all PTR types go as 64 bits
+ // this is a porting quick workaround, should be fixed
assert(pindex != NULL || pbase != NULL);
sz = is_ptr_type(p->getType()) ? OpndSize_64 : sz;
#endif
@@ -240,10 +261,14 @@
baseReg,
indexReg,
NULL == pscale ? 0 : (unsigned char)pscale->getImmValue(),
- disp
- );
+ disp);
args.add( o );
-
+ // Emit prefix here - so it relates to the real instruction
+ // emitted alter, rather that to the hidden MOV inserted above
+ InstPrefix instPrefix = getInstPrefixFromSReg(p->getSegReg());
+ if (instPrefix != InstPrefix_Null) {
+ stream = (uint8*)EncoderBase::prefix((char*)stream, instPrefix);
+ }
}
break;
default:
@@ -260,6 +285,10 @@
}
}
+ //emit inst prefix
+ if (inst->getPrefix()!=InstPrefix_Null) {
+ stream = (uint8*)EncoderBase::prefix((char*)stream, inst->getPrefix());
+ }
return (uint8*)EncoderBase::encode((char*)stream, mnemonic, args);
}
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Tue Apr 17 22:23:39 2007
@@ -16,7 +16,6 @@
*/
/**
* @author Intel, Vyacheslav P. Shakin, Nikolay A. Sidelnikov
- * @version $Revision: 1.23.8.2.4.4 $
*/
#include "Log.h"
@@ -26,6 +25,7 @@
#include "EMInterface.h"
#include "VMInterface.h"
#include "Opcode.h"
+#include "Ia32Tls.h"
#include <float.h>
#include <math.h>
@@ -196,9 +196,6 @@
switchNumTargets(0), currPersistentId(),
currPredOpnd(NULL)
{
-#ifdef _DEBUG
- nextInArg = 0;
-#endif
}
//_______________________________________________________________________________________________________________
@@ -1693,20 +1690,6 @@
}
//_______________________________________________________________________________________________________________
-Opnd* InstCodeSelector::buildOffset(uint32 offset, MemoryAttribute::Context context)
-{
- ICS_ASSERT(0);
- return 0;
-}
-
-//_______________________________________________________________________________________________________________
-Opnd* InstCodeSelector::buildOffsetPlusHeapbase(uint32 offset, MemoryAttribute::Context context)
-{
- ICS_ASSERT(0);
- return 0;
-}
-
-//_______________________________________________________________________________________________________________
CG_OpndHandle * InstCodeSelector::ldFieldOffset(FieldDesc *fieldDesc)
{
return irManager.newImmOpnd(typeManager.getIntPtrType(), Opnd::RuntimeInfo::Kind_FieldOffset, fieldDesc);
@@ -1991,17 +1974,6 @@
#endif
}
-
-//_______________________________________________________________________________________________________________
-// Get type of the field reference
-
-Type * InstCodeSelector::getFieldRefType(Type *dstType,
- Type::Tag fieldTypeTag)
-{
- ICS_ASSERT(0);
- return 0;
-}
-
//_______________________________________________________________________________________________________________
// Load static field
@@ -2084,43 +2056,6 @@
{
ICS_ASSERT(0);
}
-
-
-
-//_______________________________________________________________________________________________________________
-// Compress a reference operand
-
-void InstCodeSelector::compressOpnd(Opnd *dst, Opnd *src)
-{
- ICS_ASSERT(0);
-}
-
-//_______________________________________________________________________________________________________________
-// Decompress a reference operand
-
-void InstCodeSelector::decompressOpnd(Opnd *dst, Opnd *src)
-{
- ICS_ASSERT(0);
-}
-
-//_______________________________________________________________________________________________________________
-// If one operand is a raw reference and the other is a compressed reference
-// change them both to either compressed or raw references so that they can be
-// compared for equality/inequality etc..
-
-void InstCodeSelector::makeComparable(Opnd*& srcOpnd1, Opnd*& srcOpnd2)
-{
- ICS_ASSERT(0);
-}
-
-//_______________________________________________________________________________________________________________
-// If pointer points to the enumerated type change type tag to
-// the type tag of the underlying type of the enumerated type.
-
-void InstCodeSelector::simplifyTypeTag(Type::Tag& tag,Type *ptr)
-{
- ICS_ASSERT(0);
-}
//_______________________________________________________________________________________________________________
// Load indirect
@@ -2466,18 +2401,6 @@
}
//_______________________________________________________________________________________________________________
-// Add the base of all VTables and an immediate offset to a CG_OpndHandle
-// This gets an absolute address into a field in the VTable
-
-Opnd* InstCodeSelector::addVtableBaseAndOffset(Opnd * addr,
- CG_OpndHandle * compPtr,
- uint32 offset)
-{
- ICS_ASSERT(0);
- return 0;
-}
-
-//_______________________________________________________________________________________________________________
// Load interface table address
// The tau parameter is irrelevant because VM helper does not expect JIT
// to verify that the object type has given interface
@@ -2741,54 +2664,26 @@
case SaveThisState:
{
assert(numArgs == 1);
-#ifdef PLATFORM_POSIX
- // Not supported
- assert(0);
-#else // PLATFORM_POSIX
- // TLS base can be obtained from [fs:0x14]
- Opnd * tlsBaseReg = irManager.newOpnd(typeManager.getUnmanagedPtrType(typeManager.getInt32Type()));
- appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, tlsBaseReg,
- irManager.newMemOpnd(typeManager.getInt32Type(),
- MemOpndKind_Any,
- NULL,
- 0x14, RegName_FS)));
- appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV,
- irManager.newMemOpnd(typeManager.getUnmanagedPtrType(typeManager.getInt32Type()),
- MemOpndKind_Any,
- tlsBaseReg,
- VMInterface::flagTLSThreadStateOffset()),
- (Opnd*)args[0]));
-#endif // PLATFORM_POSIX
-
+ Type* int32type = typeManager.getInt32Type();
+ Type* unmanPtr = typeManager.getUnmanagedPtrType(int32type);
+ Opnd * tlsBase = createTlsBaseLoadSequence(irManager, currentBasicBlock, unmanPtr);
+ uint32 offsetInTLS = VMInterface::flagTLSThreadStateOffset();
+ Opnd* pStateFlag = irManager.newMemOpnd(int32type, MemOpndKind_Any, tlsBase, offsetInTLS);
+ Inst* ii = irManager.newCopyPseudoInst(Mnemonic_MOV, pStateFlag, (Opnd*)args[0]);
+ appendInsts(ii);
break;
}
case ReadThisState:
{
assert(numArgs == 0);
-#ifdef PLATFORM_POSIX
- // Not supported
- assert(0);
-#else // PLATFORM_POSIX
- // TLS base can be obtained from [fs:0x14]
- Opnd * tlsBaseReg = irManager.newOpnd(typeManager.getUnmanagedPtrType(typeManager.getInt32Type()));
- appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV,
- tlsBaseReg,
- irManager.newMemOpnd(typeManager.getInt32Type(),
- MemOpndKind_Any,
- NULL, 0x14, RegName_FS)));
- appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dstOpnd,
- irManager.newMemOpnd(typeManager.getInt32Type(),
- MemOpndKind_Any,
- tlsBaseReg,
- VMInterface::flagTLSThreadStateOffset())));
- appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV,
- irManager.newMemOpnd(typeManager.getInt32Type(),
- MemOpndKind_Any,
- tlsBaseReg,
- VMInterface::flagTLSThreadStateOffset()),
- irManager.newImmOpnd(typeManager.getInt32Type(),1)));
-#endif
+ Type* int32type = typeManager.getInt32Type();
+ Type* unmanPtr = typeManager.getUnmanagedPtrType(int32type);
+ Opnd * tlsBase = createTlsBaseLoadSequence(irManager, currentBasicBlock, unmanPtr);
+ uint32 offsetInTLS = VMInterface::flagTLSThreadStateOffset();
+ Opnd* pStateFlag = irManager.newMemOpnd(int32type, MemOpndKind_Any, tlsBase, offsetInTLS);
+ Inst* ii = irManager.newCopyPseudoInst(Mnemonic_MOV, dstOpnd, pStateFlag);
+ appendInsts(ii);
break;
}
case LockedCompareAndExchange:
@@ -2880,18 +2775,9 @@
case CompilationInterface::Helper_GetTLSBase:
{
assert(numArgs == 0);
- Opnd * tlsBaseReg = irManager.newOpnd(typeManager.getUnmanagedPtrType(typeManager.getInt8Type()));
-#if defined(PLATFORM_POSIX) || defined (_EM64T_)
- TypeManager& tm =irManager.getTypeManager();
- Opnd * callAddrOpnd =irManager.newImmOpnd(tm.getUnmanagedPtrType(tm.getIntPtrType()),
- Opnd::RuntimeInfo::Kind_HelperAddress, (void*)CompilationInterface::Helper_GetTLSBase);
- appendInsts(irManager.newCallInst(callAddrOpnd, &CallingConvention_STDCALL, 0, NULL, tlsBaseReg));
-#else
- appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, tlsBaseReg,
- irManager.newMemOpnd(typeManager.getInt32Type(), MemOpndKind_Any, NULL, 0x14, RegName_FS)));
-#endif
- dstOpnd = tlsBaseReg;
-
+ Type* tlsBaseType = typeManager.getUnmanagedPtrType(typeManager.getInt8Type());
+ Opnd * tlsBase = createTlsBaseLoadSequence(irManager, currentBasicBlock, tlsBaseType);
+ dstOpnd = tlsBase;
break;
}
case CompilationInterface::Helper_NewObj_UsingVtable:
@@ -2967,12 +2853,6 @@
}
//_______________________________________________________________________________________________________________
-// Static estimate of fast path success probabilities
-
-#define FAST_PATH_MONITOR_ENTER_SUCCESS_PROB 0.99
-#define FAST_PATH_MONITOR_EXIT_SUCCESS_PROB 0.99
-
-//_______________________________________________________________________________________________________________
// Acquire monitor for an object
void InstCodeSelector::tau_monitorEnter(CG_OpndHandle* obj, CG_OpndHandle* tauIsNonNull)
@@ -3036,15 +2916,6 @@
}
//_______________________________________________________________________________________________________________
-// Read synchronization fence flag
-
-uint32 InstCodeSelector::getSyncFenceFlag()
-{
- ICS_ASSERT(0);
- return 0;
-}
-
-//_______________________________________________________________________________________________________________
// Monitor enter fence
void InstCodeSelector::monitorEnterFence(CG_OpndHandle* obj)
@@ -3224,14 +3095,6 @@
// Create a tau point definition indicating that control flow reached the current point
CG_OpndHandle* InstCodeSelector::tauPoint()
-{
- return getTauUnsafe();
-}
-
-//_______________________________________________________________________________________________________________
-// Generate a tau split instruction
-
-CG_OpndHandle * InstCodeSelector::genTauSplit(BranchInst *br)
{
return getTauUnsafe();
}
Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.cpp?view=auto&rev=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.cpp Tue Apr 17 22:23:39 2007
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexander Astapchuk
+ */
+ /**
+ * @file
+ * @brief Concentrates all the codegen's knowledge about the TLS and
+ * related things.
+ */
+
+
+#include "Ia32Tls.h"
+#include <open/hythread_ext.h>
+
+namespace Jitrino {
+namespace Ia32 {
+
+static Opnd* createTlsBaseLoadGeneric(IRManager& ir, Node* ctrlNode, Type* tlsBaseType);
+
+#ifdef _WIN32
+ static Opnd* createTlsBaseLoadWin(IRManager& ir, Node* ctrlNode, Type* tlsBaseType);
+#else
+ static Opnd* createTlsBaseLoadLin(IRManager& ir, Node* ctrlNode, Type* tlsBaseType);
+#endif
+
+Opnd* createTlsBaseLoadSequence(IRManager& irManager, Node* ctrlNode)
+{
+ Type* int8type = irManager.getTypeManager().getInt8Type();
+ Type* tlsBaseType = irManager.getTypeManager().getUnmanagedPtrType(int8type);
+ return createTlsBaseLoadSequence(irManager, ctrlNode, tlsBaseType);
+}
+
+Opnd* createTlsBaseLoadSequence(IRManager& irManager, Node* ctrlNode, Type* tlsBaseType)
+{
+ Opnd* tlsBase;
+#if defined(_WIN32) && defined(_EM64T_)
+ // Currently do it in a looong way - via the helper, but need to change
+ // it to FS:[0x14] - TODO
+ tlsBase = createTlsBaseLoadGeneric(irManager, ctrlNode, tlsBaseType);
+#elif defined(_WIN32)
+ // Fast access through FS:[0x14]
+ tlsBase = createTlsBaseLoadWin(irManager, ctrlNode, tlsBaseType);
+#elif defined(__linux__)
+ // On Linux, try the fast way
+ tlsBase = createTlsBaseLoadLin(irManager, ctrlNode, tlsBaseType);
+#else
+ // Some other unknown platform - slow, but platform-independent way through the helper
+ tlsBase = createTlsBaseLoadGeneric(irManager, ctrlNode, tlsBaseType);
+#endif
+ return tlsBase;
+}
+
+Opnd* createTlsBaseLoadGeneric(IRManager& irManager, Node* ctrlNode, Type* tlsBaseType)
+{
+ // Dunno where the HYTHR keeps its thread structure - request through the helper
+ Opnd* tlsBase = irManager.newOpnd(tlsBaseType);
+ Inst* callInst = irManager.newRuntimeHelperCallInst(CompilationInterface::Helper_GetTLSBase, 0, NULL, tlsBase);
+ ctrlNode->appendInst(callInst);
+ return tlsBase;
+}
+
+#ifdef _WIN32
+
+Opnd* createTlsBaseLoadWin(IRManager& irManager, Node* ctrlNode, Type* tlsBaseType)
+{
+ if (!hythread_uses_fast_tls()) {
+ return createTlsBaseLoadGeneric(irManager, ctrlNode, tlsBaseType);
+ }
+ // HYTHR's structure is stored in TIB's free offset aka [fs:0x14]
+ Opnd* tlsBase = irManager.newMemOpnd(tlsBaseType, MemOpndKind_Any, NULL, 0x14, RegName_FS);
+ return tlsBase;
+}
+
+#else // ifdef _WIN32
+
+Opnd* createTlsBaseLoadLin(IRManager& irManager, Node* ctrlNode, Type* tlsBaseType)
+{
+ if (!hythread_uses_fast_tls()) {
+ return createTlsBaseLoadGeneric(irManager, ctrlNode, tlsBaseType);
+ }
+
+ // HYTHR's structure is stored in global TLS
+ /*
+ MOV tib, fs:[0]
+ MOV pHythr, [tib + threadOffset]
+ MOV hythread_t, *pHythr
+ tlsBase = hythread_t
+ */
+
+ int threadOffset = hythread_get_hythread_offset_in_tls();
+ Opnd* pTib;
+#if defined(_EM64T_)
+ pTib = irManager.newMemOpnd(tlsBaseType, MemOpndKind_Any, NULL, 0, RegName_FS);
+#else
+ pTib = irManager.newMemOpnd(tlsBaseType, MemOpndKind_Any, NULL, 0, RegName_GS);
+#endif
+ Opnd* tib = irManager.newOpnd(tlsBaseType);
+ Inst* ii;
+ ii = irManager.newCopyPseudoInst(Mnemonic_MOV, tib, pTib);
+ ctrlNode->appendInst(ii);
+
+ Opnd* pHyThread = irManager.newMemOpnd(tlsBaseType, MemOpndKind_Any, tib, threadOffset);
+ Opnd* _hythread_t = irManager.newOpnd(tlsBaseType);
+
+ ii= irManager.newCopyPseudoInst(Mnemonic_MOV, _hythread_t, pHyThread);
+ ctrlNode->appendInst(ii);
+ Opnd* tlsBase = _hythread_t;
+ return tlsBase;
+}
+
+#endif // ifdef _WIN32
+
+
+}}; // ~Jitrino::Ia32
+
Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.h?view=auto&rev=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.h Tue Apr 17 22:23:39 2007
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Alexander Astapchuk
+ */
+ /**
+ * @file
+ * @brief Concentrates all the codegen's knowledge about the TLS and
+ * related things.
+ */
+
+
+#ifndef _IA32_TLS_H_
+#define _IA32_TLS_H_
+
+#include "Ia32IRManager.h"
+
+namespace Jitrino {
+namespace Ia32 {
+
+/**
+ * @brief Creates a sequence that loads TLS base.
+ *
+ * Create a sequence of instructions that loads TLS base into an Opnd.
+ * The TLS base is created with the provided type.
+ *
+ * The sequence may be empty, for example, on Windows, where the TLS base
+ * is simple memory reference FS:[0x14].
+ * The sequence may include a call, or may result in just several memory loads.
+ * The instructions are appended at the end of ctrlNode.
+ */
+Opnd* createTlsBaseLoadSequence(IRManager& irManager, Node* ctrlNode, Type* tlsBaseType);
+
+
+/**
+ * Same as 3-args method, but presumes type for the TLS base as int8*.
+ */
+Opnd* createTlsBaseLoadSequence(IRManager& irManager, Node* ctrlNode);
+
+
+}}; // ~Jitrino::Ia32
+
+#endif // ifdef _IA32_TLS_H_
+
Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Tls.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def Tue Apr 17 22:23:39 2007
@@ -3,6 +3,7 @@
EXPORTS
hythread_detach
+hythread_uses_fast_tls
hythread_tls_alloc
hythread_sleep_interruptable
hythread_cancel
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp Tue Apr 17 22:23:39 2007
@@ -37,6 +37,8 @@
hythread_get_priority;
hythread_tls_get;
hythread_tls_get_request_offset;
+hythread_get_hythread_offset_in_tls;
+hythread_uses_fast_tls;
hythread_tls_get_offset;
hythread_global_lock;
hythread_global_unlock;
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c Tue Apr 17 22:23:39 2007
@@ -17,8 +17,7 @@
/**
* @author Nikolay Kuznetsov
- * @version $Revision: 1.1.2.13 $
- */
+ */
/**
* @file thread_native_basic.c
@@ -50,16 +49,15 @@
static hythread_t allocate_thread();
static void reset_thread(hythread_t thread);
static IDATA register_to_group(hythread_t thread, hythread_group_t group);
-//#define APR_TLS_USE 1
#define NAKED __declspec(naked)
-#if !defined (APR_TLS_USE) && !defined (FS14_TLS_USE)
-#ifdef PLATFORM_POSIX
-__thread hythread_t tm_self_tls = NULL;
-#else
-__declspec(thread) hythread_t tm_self_tls = NULL;
-#endif
+#if !defined (APR_TLS_USE)
+ #if !defined(_WIN32)
+ __thread hythread_t tm_self_tls HYTHREAD_FAST_TLS_ATTRIBUTE;
+ #elif !defined(HYTHREAD_FAST_TLS)
+ __declspec(thread) hythread_t tm_self_tls = NULL;
+ #endif
#endif
#define MAX_ID 1000000
@@ -320,7 +318,7 @@
return hylatch_wait_interruptable(t->join_event, millis, nanos);
}
-/**
+/**
* Yield the processor.
*
* @return none
@@ -353,11 +351,11 @@
hythread_t hythread_self_slow() {
hythread_t thread;
apr_status_t UNUSED apr_status;
-
+
// Extract hythread_t from TLS
- apr_status = apr_threadkey_private_get((void **)(&thread), TM_THREAD_KEY);
+ apr_status = apr_threadkey_private_get((void **)(&thread), TM_THREAD_KEY);
assert(apr_status == APR_SUCCESS);
-
+
return thread;
}
@@ -365,7 +363,7 @@
apr_threadkey_private_set(thread, TM_THREAD_KEY);
}
#else
-#ifdef FS14_TLS_USE
+#if defined(_WIN32) && defined(HYTHREAD_FAST_TLS)
/**
* Return the hythread_t for the current thread.
*
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c Tue Apr 17 22:23:39 2007
@@ -33,18 +33,88 @@
static void tls_finalizer_placeholder(void *args) {}
+/**
+ * Returns non-zero if a 'fast TLS access' is in use.
+ *
+ * The 'fast TLS access' varies depending on platform.
+ *
+ * On Windows, the thread manager's structure is stored in the free slot
+ * of the TIB (see http://www.microsoft.com/msj/archive/S2CE.aspx).
+ * On Linux, it's stored in app's TLS where it can be retrieved from.
+ */
+UDATA VMCALL hythread_uses_fast_tls(void) {
+#ifdef HYTHREAD_FAST_TLS
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#if !defined(_WIN32) && defined(HYTHREAD_FAST_TLS)
+ #if defined(_EM64T_)
+ #define HYTHREAD_TLS_GET_VAR_OFFSET(var,offset) \
+ { \
+ void* tmp1 = &var; \
+ void* tmp2; \
+ asm(" movq %%fs:0x00, %0": "=r" (tmp2)); \
+ offset = tmp1 - tmp2; \
+ }
+ //TODO: GCC-specific, need to add ICL
+ //#define HYTHREAD_TLS_GET_VAR_OFFSET(var,offset) \
+ // { void* tmp; __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (tmp)); offset = tmp; }
+ #elif defined(_IA32_)
+ #define HYTHREAD_TLS_GET_VAR_OFFSET(var,offset) \
+ { \
+ void* tmp1 = &var; \
+ void* tmp2; \
+ asm(" movl %%gs:0x00, %0": "=r" (tmp2)); \
+ offset = tmp1 - tmp2; \
+ }
+ //TODO: GCC-specific, need to add ICL
+ //#define HYTHREAD_TLS_GET_VAR_OFFSET(var,offset) \
+ // { __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset)); }
+ #elif defined(_IPF_)
+ #define HYTHREAD_TLS_GET_VAR_OFFSET(var,offset) \
+ { \
+ void* tmp1 = &var; \
+ void* tmp2; \
+ asm("mov %0 = r13;;": "=r" (tmp2)); \
+ offset = tmp1 - tmp2; \
+ }
+ //TODO: GCC-specific, need to add ICL
+ //TODO: NOTE: not even tested, may require fix.
+ //#define HYTHREAD_TLS_GET_VAR_OFFSET(var,offset) \
+ // { __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset)) }
+ #else
+ #error "Don't know how to get the variable offset in TLS on this platfrom. Try to undef HYTHREAD_FAST_TLS or provide the macros here."
+ #endif
+#else
+ #define HYTHREAD_TLS_GET_VAR_OFFSET(var, offset) { offset = -1; }
+#endif
+
+/**
+ * Returns offset of the hythread's control structure in the TLS.
+ *
+ * @note Only meaningful on Linux-es \b and when hythread_uses_fast_tls() returns \c true.
+ */
+IDATA VMCALL hythread_get_hythread_offset_in_tls(void) {
+ int threadOffset;
+ HYTHREAD_TLS_GET_VAR_OFFSET(tm_self_tls, threadOffset);
+
+ return threadOffset;
+}
/**
* Allocate a thread local storage (TLS) key.
- *
- * Create and return a new, unique key for thread local storage.
- *
+ *
+ * Create and return a new, unique key for thread local storage.
+ *
* @note The handle returned will be >=0, so it is safe to test the handle against 0 to see if it's been
* allocated yet.
- *
+ *
* @param[out] handle pointer to a key to be initialized with a key value
* @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated)
- *
+ *
* @see hythread_tls_free, hythread_tls_set
*/
IDATA VMCALL hythread_tls_alloc(hythread_tls_key_t *handle) {
@@ -53,17 +123,17 @@
/**
* Allocate a thread local storage (TLS) key.
- *
- * Create and return a new, unique key for thread local storage.
- *
+ *
+ * Create and return a new, unique key for thread local storage.
+ *
* @note The handle returned will be >=0, so it is safe to test the handle against 0 to see if it's been
* allocated yet.
- *
+ *
* @param[out] handle pointer to a key to be initialized with a key value
* @param[in] finalizer a finalizer function which will be invoked when a thread is
* detached or terminates if the thread's TLS entry for this key is non-NULL
* @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated)
- *
+ *
* @see hythread_tls_free, hythread_tls_set
*/
IDATA VMCALL hythread_tls_alloc_with_finalizer(hythread_tls_key_t *handle, hythread_tls_finalizer_t finalizer) {
@@ -78,11 +148,11 @@
/**
* Set a thread's TLS value.
*
- * @param[in] thread a thread
+ * @param[in] thread a thread
* @param[in] key key to have TLS value set (any value returned by hythread_alloc)
* @param[in] data value to be stored in TLS
* @return 0 on success or negative value on failure
- *
+ *
* @see hythread_tls_alloc, hythread_tls_free, hythread_tls_get
*/
IDATA VMCALL hythread_tls_set(hythread_t thread, hythread_tls_key_t key, void *data) {
@@ -93,9 +163,9 @@
/**
* Release a TLS key.
- *
+ *
* Release a TLS key previously allocated by hythread_tls_alloc.
- *
+ *
* @param[in] key TLS key to be freed
* @return 0 on success or negative value on failure
*
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h?view=diff&rev=529873&r1=529872&r2=529873
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Tue Apr 17 22:23:39 2007
@@ -18,7 +18,6 @@
#define THREAD_PRIVATE_H
#include <assert.h>
-//#include <open/thread_types.h>
#include <stdlib.h>
#include <open/types.h>
#include <open/hythread_ext.h>
@@ -56,19 +55,14 @@
#endif // !defined (_IPF_)
-#if defined(WIN32) && !defined (_EM64T_)
+#if defined(_WIN32) && !defined (_EM64T_)
//use optimized asm monitor enter and exit helpers
#define ASM_MONITOR_HELPER
-// FS14_TLS_USE define turns on windows specific TLS access optimization
-// We use free TIB slot with 14 offset, see following article for details
-// http://www.microsoft.com/msj/archive/S2CE.aspx
-//#define FS14_TLS_USE
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-
#ifdef __linux__