From d36ad53e0dc2579995e736967c7ebca6636c9263 Mon Sep 17 00:00:00 2001 From: Omer Sheikh Date: Fri, 8 Dec 2017 16:21:56 -0500 Subject: [PATCH] Add frontend method getVFTEntry The optimizer should ideally not fetch class fields directly. Factor it out into a ClassEnv method instead. Signed-off-by: Noah Weninger --- compiler/env/OMRClassEnv.cpp | 8 +++++++- compiler/env/OMRClassEnv.hpp | 11 ++++++++++- compiler/optimizer/VPHandlers.cpp | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/env/OMRClassEnv.cpp b/compiler/env/OMRClassEnv.cpp index c17d940d1b1..0c6ced55bf9 100644 --- a/compiler/env/OMRClassEnv.cpp +++ b/compiler/env/OMRClassEnv.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 @@ -42,3 +42,9 @@ OMR::ClassEnv::getArrayElementWidthInBytes(TR::Compilation *comp, TR_OpaqueClass notImplemented("getArrayElementWidthInBytes"); return 0; } + +intptrj_t +OMR::ClassEnv::getVFTEntry(TR::Compilation *comp, TR_OpaqueClassBlock* clazz, int32_t offset) + { + return *(intptrj_t*) (((uint8_t *)clazz) + offset); + } diff --git a/compiler/env/OMRClassEnv.hpp b/compiler/env/OMRClassEnv.hpp index 0384ee274e1..bcaed363a97 100644 --- a/compiler/env/OMRClassEnv.hpp +++ b/compiler/env/OMRClassEnv.hpp @@ -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 @@ -111,6 +111,15 @@ class OMR_EXTENSIBLE ClassEnv char *classSignature_DEPRECATED(TR::Compilation *comp, TR_OpaqueClassBlock * clazz, int32_t & length, TR_Memory *) { return NULL; } char *classSignature(TR::Compilation *comp, TR_OpaqueClassBlock * clazz, TR_Memory *) { return NULL; } + /** + * Get the virtual function table entry at a specific offset from the class + * + * @param clazz The RAM class pointer to read from + * @param offset An offset into the virtual function table (VFT) of clazz + * @return The entry point of the method at the given offset + */ + intptrj_t getVFTEntry(TR::Compilation *comp, TR_OpaqueClassBlock* clazz, int32_t offset); + }; } diff --git a/compiler/optimizer/VPHandlers.cpp b/compiler/optimizer/VPHandlers.cpp index 7e80b15a726..d17df895219 100644 --- a/compiler/optimizer/VPHandlers.cpp +++ b/compiler/optimizer/VPHandlers.cpp @@ -9678,9 +9678,9 @@ static TR::Node *constrainIfcmpeqne(OMR::ValuePropagation *vp, TR::Node *node, b TR::VPConstraint *classConstraint = vp->getConstraint(classNode, isGlobal); if (ignoreVirtualGuard && classConstraint && classConstraint->isFixedClass()) { - uint8_t *clazz = (uint8_t*)classConstraint->getClass(); + TR_OpaqueClassBlock *clazz = classConstraint->getClass(); int32_t vftOffset = vtableEntryNode->getSymbolReference()->getOffset(); - intptrj_t vftEntry = *(intptrj_t*)(clazz + vftOffset); + intptrj_t vftEntry = TR::Compiler->cls.getVFTEntry(vp->comp(), clazz, vftOffset); bool childrenAreEqual = (vftEntry == methodPtrNode->getAddress()); bool testForEquality = (node->getOpCodeValue() == TR::ifacmpeq); traceMsg(vp->comp(), "TR_MethodTest: node=%p, vtableEntryNode=%p, clazz=%p, vftOffset=%d, vftEntry=%p, childrenAreEqual=%d, testForEquality=%d\n",