From eafd3e7ef5f433a3fd14a960addf17c13b70eed5 Mon Sep 17 00:00:00 2001 From: Yiling Han Date: Wed, 26 Jun 2019 17:17:27 -0400 Subject: [PATCH] Add a TypeLayout introspection api 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 --- compiler/compile/OMRCompilation.cpp | 18 ++++ compiler/compile/OMRCompilation.hpp | 18 ++++ compiler/env/OMRClassEnv.hpp | 16 +++ compiler/env/TypeLayout.hpp | 152 ++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 compiler/env/TypeLayout.hpp diff --git a/compiler/compile/OMRCompilation.cpp b/compiler/compile/OMRCompilation.cpp index 36a0573ec5c..5ea9259583f 100644 --- a/compiler/compile/OMRCompilation.cpp +++ b/compiler/compile/OMRCompilation.cpp @@ -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" @@ -292,6 +293,7 @@ OMR::Compilation::Compilation( _gpuKernelLineNumberList(m), _gpuPtxCount(0), _bitVectorPool(self()), + _typeLayoutMap((LayoutComparator()), LayoutAllocator(self()->region())), _tlsManager(*self()) { @@ -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; + } + } diff --git a/compiler/compile/OMRCompilation.hpp b/compiler/compile/OMRCompilation.hpp index ba61b8b6013..b52f9058074 100644 --- a/compiler/compile/OMRCompilation.hpp +++ b/compiler/compile/OMRCompilation.hpp @@ -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 @@ -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 ¤tInfo); @@ -1262,6 +1275,11 @@ class OMR_EXTENSIBLE Compilation BitVectorPool _bitVectorPool; //MUST be declared after _trMemory + typedef TR::typed_allocator, TR::Region &> LayoutAllocator; + typedef std::less LayoutComparator; + typedef std::map TypeLayoutMap; + TypeLayoutMap _typeLayoutMap; + /* * This must be last * NOTE: TLS for Compilation needs to be set before any object that may use it is initialized. diff --git a/compiler/env/OMRClassEnv.hpp b/compiler/env/OMRClassEnv.hpp index 21afff8a19e..8d7ef31caa2 100644 --- a/compiler/env/OMRClassEnv.hpp +++ b/compiler/env/OMRClassEnv.hpp @@ -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; @@ -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; } + }; } diff --git a/compiler/env/TypeLayout.hpp b/compiler/env/TypeLayout.hpp new file mode 100644 index 00000000000..ff71842c6be --- /dev/null +++ b/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 _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