Skip to content

Commit

Permalink
Add a TypeLayout introspection api
Browse files Browse the repository at this point in the history
The TypeLayout API abstracts the process of querying and caching
information related to the layout of objects in memory - this API
will be needed to help implement the newvalue opcode because its
meaning is coupled to the layout of the type being instantiated.

Signed-off-by: Yiling Han <Yiling.Han@ibm.com>
  • Loading branch information
Yiling Han authored and Yiling Han committed Sep 23, 2019
1 parent 09eee48 commit eafd3e7
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 0 deletions.
18 changes: 18 additions & 0 deletions compiler/compile/OMRCompilation.cpp
Expand Up @@ -56,6 +56,7 @@
#include "env/PersistentInfo.hpp"
#include "env/StackMemoryRegion.hpp"
#include "env/TRMemory.hpp"
#include "env/TypeLayout.hpp"
#include "env/defines.h"
#include "env/jittypes.h"
#include "il/Block.hpp"
Expand Down Expand Up @@ -292,6 +293,7 @@ OMR::Compilation::Compilation(
_gpuKernelLineNumberList(m),
_gpuPtxCount(0),
_bitVectorPool(self()),
_typeLayoutMap((LayoutComparator()), LayoutAllocator(self()->region())),
_tlsManager(*self())
{

Expand Down Expand Up @@ -2748,3 +2750,19 @@ bool OMR::Compilation::isRecursiveMethodTarget(TR::Symbol *targetSymbol)

return isRecursive;
}

const TR::TypeLayout* OMR::Compilation::typeLayout(TR_OpaqueClassBlock * clazz)
{
TR::Region& region = self()->region();
auto it = _typeLayoutMap.find(clazz);
if (it != _typeLayoutMap.end())
{
return it->second;
}
else
{
const TR::TypeLayout* layout = TR::Compiler->cls.enumerateFields(region, clazz, self());
_typeLayoutMap.insert(std::make_pair(clazz, layout));
return layout;
}
}
18 changes: 18 additions & 0 deletions compiler/compile/OMRCompilation.hpp
Expand Up @@ -109,6 +109,7 @@ namespace TR { class Symbol; }
namespace TR { class SymbolReference; }
namespace TR { class SymbolReferenceTable; }
namespace TR { class TreeTop; }
namespace TR { class TypeLayout; }
typedef TR::SparseBitVector SharedSparseBitVector;

#if _AIX
Expand Down Expand Up @@ -1051,6 +1052,18 @@ class OMR_EXTENSIBLE Compilation
TR::Region &aliasRegion();
void invalidateAliasRegion();

/** \brief
* Requests the layout of a type. The layout here means how the fields
* are laid out in an object of the given type.
*
* \param clazz
* Class of the type whose layout is requested.
*
* \return
* Returns a TypeLayout object pointer.
*/
const TR::TypeLayout* typeLayout(TR_OpaqueClassBlock * clazz);

private:
void resetVisitCounts(vcount_t, TR::ResolvedMethodSymbol *);
int16_t restoreInlineDepthUntil(int32_t stopIndex, TR_ByteCodeInfo &currentInfo);
Expand Down Expand Up @@ -1262,6 +1275,11 @@ class OMR_EXTENSIBLE Compilation

BitVectorPool _bitVectorPool; //MUST be declared after _trMemory

typedef TR::typed_allocator<std::pair<TR_OpaqueClassBlock* const, const TR::TypeLayout *>, TR::Region &> LayoutAllocator;
typedef std::less<TR_OpaqueClassBlock*> LayoutComparator;
typedef std::map<TR_OpaqueClassBlock *, const TR::TypeLayout *, LayoutComparator, LayoutAllocator> TypeLayoutMap;
TypeLayoutMap _typeLayoutMap;

/*
* This must be last
* NOTE: TLS for Compilation needs to be set before any object that may use it is initialized.
Expand Down
16 changes: 16 additions & 0 deletions compiler/env/OMRClassEnv.hpp
Expand Up @@ -38,6 +38,8 @@ namespace OMR { typedef OMR::ClassEnv ClassEnvConnector; }
struct OMR_VMThread;
namespace TR { class Compilation; }
namespace TR { class SymbolReference; }
namespace TR { class TypeLayout; }
namespace TR { class Region; }
class TR_ResolvedMethod;
class TR_Memory;

Expand Down Expand Up @@ -122,6 +124,20 @@ class OMR_EXTENSIBLE ClassEnv

bool classUnloadAssumptionNeedsRelocation(TR::Compilation *comp);

/** \brief
* Populates a TypeLayout object.
*
* \param region
* The region used to allocate TypeLayout.
*
* \param opaqueClazz
* Class of the type whose layout needs to be populated.
*
* \return
* Returns a NULL pointer.
*/
const TR::TypeLayout* enumerateFields(TR::Region& region, TR_OpaqueClassBlock * clazz, TR::Compilation *comp) { return NULL; }

};

}
Expand Down
152 changes: 152 additions & 0 deletions compiler/env/TypeLayout.hpp
@@ -0,0 +1,152 @@
/*******************************************************************************
* Copyright (c) 2019, 2019 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
* distribution and is available at http://eclipse.org/legal/epl-2.0
* or the Apache License, Version 2.0 which accompanies this distribution
* and is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception [1] and GNU General Public
* License, version 2 with the OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] http://openjdk.java.net/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
*******************************************************************************/

#ifndef TYPE_LAYOUT_INCL
#define TYPE_LAYOUT_INCL

#include "il/DataTypes.hpp"
#include "infra/vector.hpp"

namespace TR {

/** \brief
* TypeLayoutEntry represents a field.
*
* For each field entry its TR::DataType and
* its offset (including the object header size) are recorded.
*/
class TypeLayoutEntry
{
public:
TypeLayoutEntry(TR::DataType datatype, int32_t offset, char * fieldname)
: _datatype(datatype), _offset(offset), _fieldname(fieldname){}
TR::DataType _datatype;
int32_t _offset;
const char * _fieldname;
};

/** \brief
* TypeLayout represents the layout of fields.
*
* It contains TypeLayoutEntry that belongs to
* a single class. It stores a `TR::vector` of TypeLayoutEntry objects.
*/
class TypeLayout
{
public:
size_t count() const { return _entries.size(); }

/** \brief
* Finds the corresponding entry based on index given.
*
* \param ind
* The index of the entry that wants to be returned.
*
* \return
* The TypeLayoutEntry object stored in the vector at given index.
*/
const TypeLayoutEntry& entry(size_t ind) const { return _entries.at(ind); }

/** \brief
* Queries for the index of the field at a given offset.
*
* \param offset
* The offset of the field shadow.
*
* \return
* The index of the entry that wants to be queried for.
*/
int32_t fieldIndex (int32_t offset) const
{
int32_t ind = 0;
while (_entries.at(ind)._offset != offset)
{
ind++;
}
return ind;
}

private:
TR::vector<TR::TypeLayoutEntry, TR::Region&> _entries;
TypeLayout(TR::Region& region) : _entries(region) {}

struct CompareOffset
{
bool operator() (const TypeLayoutEntry& entry1, const TypeLayoutEntry& entry2) const
{
return entry1._offset < entry2._offset;
}
};

/** \brief
* Sorts TypeLayout entries by offset.
*/
void sort()
{
CompareOffset compareOffset;
std::sort(_entries.begin(), _entries.end(), compareOffset);
}

friend class TypeLayoutBuilder;
};

/** \brief
* TypeLayoutBuilder is a builder class for TypeLayout.
*
* It encapsulates building a TypeLayout instance.
*/
class TypeLayoutBuilder
{
public:
TypeLayoutBuilder(TR::Region & region) : tl(new (region) TypeLayout(region)) {}

/** \brief
* Add TypeLayoutEntry to TypeLayout being built.
*
* \param entry
* The entry being added.
*/
void add(TR::TypeLayoutEntry entry)
{
tl->_entries.push_back(entry);
}

/** \brief
* Return built TypeLayout object.
*
* \return
* The built TypeLayout.
*/
TypeLayout* build()
{
tl->sort();
auto* temp = tl;
tl = NULL;
return temp;
}

private:
TypeLayout* tl;
};

} //TR

#endif

0 comments on commit eafd3e7

Please sign in to comment.