Skip to content

Commit

Permalink
Make runtime helper table class do lazy address translation
Browse files Browse the repository at this point in the history
Runtime helper table no longer unwrap function pointers at initialization
time. It now keeps an array of function pointers; and API users can query
function pointers via the new getFunctionPointer() API. On certain
platforms, this allows users to get the function descriptors and extract
useful info such as function environment pointers.

The old getAddress() API is replaced with getFunctionPointerOrConst(),
whose name is more self-explanatory.

Signed-off-by: Nigel Yu <yunigel@ca.ibm.com>
  • Loading branch information
NigelYiboYu committed Jul 26, 2018
1 parent c2806ba commit 9800d09
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 12 deletions.
24 changes: 23 additions & 1 deletion compiler/runtime/Runtime.cpp
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2016 IBM Corp. and others
* Copyright (c) 2000, 2018 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -47,6 +47,28 @@ TR_RuntimeHelperTable::translateAddress(void * a)
return a;
}

void* TR_RuntimeHelperTable::getFunctionEntryPointOrConst(TR_RuntimeHelper h)
{
if (h < TR_numRuntimeHelpers)
{
if (_linkage[h] == TR_Helper)
return translateAddress(_helpers[h]);
else
return _helpers[h];
}
else
return reinterpret_cast<void*>(TR_RuntimeHelperTable::INVALID_FUNCTION_POINTER);
}

void*
TR_RuntimeHelperTable::getFunctionPointer(TR_RuntimeHelper h)
{
if ((h < TR_numRuntimeHelpers) && (_linkage[h] == TR_Helper))
return _helpers[h];
else
return reinterpret_cast<void*>(TR_RuntimeHelperTable::INVALID_FUNCTION_POINTER);
}

void
initializeJitRuntimeHelperTable(char isSMP)
{
Expand Down
66 changes: 55 additions & 11 deletions compiler/runtime/Runtime.hpp
Expand Up @@ -170,40 +170,84 @@ enum TR_RuntimeHelper
class TR_RuntimeHelperTable
{
public:
void* getAddress(TR_RuntimeHelper h)
{
return h < TR_numRuntimeHelpers ? _helpers[h] : (void *) (uintptr_t) 0xDEADB00F;
}

static const intptrj_t INVALID_FUNCTION_POINTER = 0xdeadb00f;

/**
* \brief
*
* Looks up the given helper table and returns the function pointer if it's a function index.
* For constant number entries, return INVALID_FUNCTION_POINTER.
*/
void* getFunctionPointer(TR_RuntimeHelper h);

/**
* \brief
*
* For helper functions, this API returns the raw entry address. If the runtime
* helper's corresponding linkage is not a function, return the helper as data.
*
*/
void* getFunctionEntryPointOrConst(TR_RuntimeHelper h);

/**
* \brief
*
* Returns the linkage type of the given helper index. The linkage types are set during
* the JIT initilization phase.
*/
TR_LinkageConventions getLinkage(TR_RuntimeHelper h)
{
return h < TR_numRuntimeHelpers ? _linkage[h] : TR_None;
}
// Linkage convention is essential when calling a helper
// For example, on X86, there are private linkage, System V ABI, fastcall, cdecl, etc.

/**
* \brief
*
* Sets the address and linkage convention.
*
* Linkage convention is essential when calling a helper
* For example, on X86, there are private linkage, System V ABI, fastcall, cdecl, etc.
*/
void setAddress(TR_RuntimeHelper h, void * a, TR_LinkageConventions lc = TR_Helper)
{
_helpers[h] = translateAddress(a);
_helpers[h] = a;
_linkage[h] = lc;
}

/**
* \brief
*
* Stores the given pointer as a helper constant.
*/
void setConstant(TR_RuntimeHelper h, void * a)
{
_helpers[h] = a;
_linkage[h] = TR_None;
}

private:
// translate address is to allow each platform converting a C function pointer
// to an address callable by assembly, which is essential for P and Z.
/**
* \brief
* Translate address is to allow converting a C function pointer
* to an address callable by assembly.
*/
void* translateAddress(void* a);

void* _helpers[TR_numRuntimeHelpers];
TR_LinkageConventions _linkage[TR_numRuntimeHelpers];
};

extern TR_RuntimeHelperTable runtimeHelpers;



inline void* runtimeHelperValue(TR_RuntimeHelper h) { return runtimeHelpers.getAddress(h); }
/**
* \brief
* Returns the value to which the runtime helper index corresponds to.
* The values stored in the helper table are either entry point addresses or constant values, depending on the
* linkage type.
*/
inline void* runtimeHelperValue(TR_RuntimeHelper h) { return runtimeHelpers.getFunctionEntryPointOrConst(h); }
inline TR_LinkageConventions runtimeHelperLinkage(TR_RuntimeHelper h) { return runtimeHelpers.getLinkage(h); }


Expand Down
6 changes: 6 additions & 0 deletions include_core/omrcomp.h
Expand Up @@ -318,6 +318,10 @@ typedef struct {
void *rawFnAddress;
} J9FunctionDescriptor_T;

// Set the Address Enviroment pointer. Same for all routines from
// same library, so doesn't matter which routine, but currently only
// used when calling jitProfile* in zOS, so use one of them
#define TOC_UNWRAP_ENV(wrappedPointer) (wrappedPointer ? ((J9FunctionDescriptor_T *) (wrappedPointer))->ada : NULL)
#define TOC_UNWRAP_ADDRESS(wrappedPointer) (wrappedPointer ? ((J9FunctionDescriptor_T *)(uintptr_t)(wrappedPointer))->rawFnAddress : NULL)


Expand All @@ -335,6 +339,8 @@ typedef struct {

#endif /* __cplusplus */

#else
#define TOC_UNWRAP_ENV(wrappedPointer) 0xdeafbeef
#endif /* J9ZOS390 */

#ifndef J9CONST64
Expand Down

0 comments on commit 9800d09

Please sign in to comment.