Path: blob/master/runtime/bcutil/ROMClassCreationContext.cpp
5985 views
/*******************************************************************************1* Copyright (c) 2001, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122#include "ROMClassCreationContext.hpp"2324extern "C" void25romVerboseRecordPhaseStart(void *verboseContext, UDATA phase)26{27ROMClassCreationContext *context = (ROMClassCreationContext*)verboseContext;28context->recordPhaseStart(ROMClassCreationPhase(phase));29}3031extern "C" void32romVerboseRecordPhaseEnd(void *verboseContext, UDATA phase)33{34ROMClassCreationContext *context = (ROMClassCreationContext*)verboseContext;35context->recordPhaseEnd(ROMClassCreationPhase(phase), OK);36}3738void39ROMClassCreationContext::verbosePrintPhase(ROMClassCreationPhase phase, bool *printedPhases, UDATA indent)40{41static const char *verbosePhaseName[] = { /* Ensure this matches ROMClassCreationPhase */42"ROMClassCreation",43"ROMClassTranslation",44"CompareHashtableROMClass",45"CompareSharedROMClass",46"CreateSharedClass",47"WalkUTF8sAndMarkInterns",48"MarkAndCountUTF8s",49"VisitUTF8Block",50"WriteUTF8s",51"PrepareUTF8sAfterInternsMarked",52"ComputeExtraModifiers",53"ComputeOptionalFlags",54"ROMClassPrepareAndLayDown",55"PrepareROMClass",56"LayDownROMClass",57"ClassFileAnalysis",58"ClassFileHeaderAnalysis",59"ClassFileFieldsAnalysis",60"ClassFileAttributesAnalysis",61"ClassFileAttributesRecordAnalysis",62"ClassFileInterfacesAnalysis",63"ClassFileMethodsAnalysis",64"ClassFileMethodAttributesAnalysis",65"ClassFileAnnotationsAnalysis",66"ClassFileAnnotationElementAnalysis",67"ComputeSendSlotCount",68"ClassFileMethodThrownExceptionsAnalysis",69"ClassFileMethodCodeAttributeAnalysis",70"ClassFileMethodCodeAttributeAttributesAnalysis",71"ClassFileMethodMethodParametersAttributeAnalysis",72"CompressLineNumbers",73"ClassFileMethodCodeAttributeCaughtExceptionsAnalysis",74"ClassFileMethodCodeAttributeCodeAnalysis",75"CheckForLoop",76"ClassFileStackMapSlotsAnalysis",77"MethodIsFinalize",78"MethodIsEmpty",79"MethodIsForwarder",80"MethodIsGetter",81"MethodIsVirtual",82"MethodIsObjectConstructor",83#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)84"MethodIsConstructor",85"MethodIsNonStaticSynchronized",86#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */87"ShouldConvertInvokeVirtualToInvokeSpecial",88"ParseClassFile",89"ParseClassFileConstantPool",90"ParseClassFileFields",91"ParseClassFileMethods",92"ParseClassFileAttributes",93"ParseClassFileCheckClass",94"ParseClassFileVerifyClass",95"ParseClassFileInlineJSRs",96"ConstantPoolMapping",97"SRPOffsetTableCreation"98};99100if (!printedPhases[phase]) {101printedPhases[phase] = true;102if ((0 != _verboseRecords[phase].accumulatedTime) || (0 != _verboseRecords[phase].failureTime) || (OK != _verboseRecords[phase].buildResult)) {103bool printCompactElement = (0 == _verboseRecords[phase].failureTime) && (OK == _verboseRecords[phase].buildResult);104ROMClassCreationPhase nested = ROMClassCreationPhase(phase + 1);105/*106* Look for a nested phase.107* Postcondition: printCompactElement || (phase != _verboseRecords[i].parentPhase where i < nested && i > phase)108*/109while (printCompactElement && (nested < ROMClassCreationPhaseCount)) {110if (phase == _verboseRecords[nested].parentPhase) {111printCompactElement = false;112} else {113++nested;114}115}116117PORT_ACCESS_FROM_PORT(_portLibrary);118if (printCompactElement) {119j9tty_printf(_portLibrary, "% *c<phase name=\"%s\" totalusec=\"%i\" />\n", indent, ' ', verbosePhaseName[phase], _verboseRecords[phase].accumulatedTime);120} else {121j9tty_printf(_portLibrary, "% *c<phase name=\"%s\" totalusec=\"%i\">\n", indent, ' ', verbosePhaseName[phase], _verboseRecords[phase].accumulatedTime);122if (0 != _verboseRecords[phase].failureTime) {123j9tty_printf(_portLibrary, "% *c<failures totalusec=\"%i\" />\n", indent + 2, ' ', _verboseRecords[phase].failureTime);124}125if (OK != _verboseRecords[phase].buildResult) {126j9tty_printf(_portLibrary, "% *c<result value=\"%i\" />\n", indent + 2, ' ', buildResultString(_verboseRecords[phase].buildResult));127}128129/*130* Print nested phases.131* Precondition: phase != _verboseRecords[i].parentPhase where i < nested && i > phase132*/133while (nested < ROMClassCreationPhaseCount) {134if (phase == _verboseRecords[nested].parentPhase) {135verbosePrintPhase(nested, printedPhases, indent + 2);136}137++nested;138}139140j9tty_printf(_portLibrary, "% *c</phase>\n", indent, ' ');141}142}143}144}145146const char *147ROMClassCreationContext::buildResultString(BuildResult result)148{149switch (result) {150case OK: return "OK";151case GenericError: return "GenericError";152case OutOfROM: return "OutOfROM";153case ClassRead: return "ClassRead";154case BytecodeTranslationFailed: return "BytecodeTranslationFailed";155case StackMapFailed: return "StackMapFailed";156case InvalidBytecode: return "InvalidBytecode";157case OutOfMemory: return "OutOfMemory";158case VerifyErrorInlining: return "VerifyErrorInlining";159case NeedWideBranches: return "NeedWideBranches";160case UnknownAnnotation: return "UnknownAnnotation";161case ClassNameMismatch: return "ClassNameMismatch";162case InvalidAnnotation: return "InvalidAnnotation";163case InvalidClassType: return "InvalidClassType";164default: return "Unknown";165}166}167168void169ROMClassCreationContext::reportVerboseStatistics()170{171bool printedPhases[ROMClassCreationPhaseCount] = { false, }; // TODO check correct initialization syntax172173PORT_ACCESS_FROM_PORT(_portLibrary);174j9tty_printf(_portLibrary, "<romclass name=\"%.*s\" result=\"%s\">\n", _classNameLength, _className, buildResultString(_buildResult));175for (ROMClassCreationPhase phase = ROMClassCreation; phase != ROMClassCreationPhaseCount; ++phase) {176verbosePrintPhase(phase, printedPhases, 2);177}178if (0 != _verboseOutOfMemoryCount) {179j9tty_printf(_portLibrary, " <oom count=\"%i\" lastBufferSizeExceeded=\"%i\" />\n", _verboseOutOfMemoryCount, _verboseLastBufferSizeExceeded);180181}182j9tty_printf(_portLibrary, "</romclass>\n");183}184185J9ROMMethod *186ROMClassCreationContext::romMethodFromOffset(IDATA offset)187{188J9ROMMethod *returnMethod = NULL;189if (NULL != _romClass) {190UDATA romclassaddr = ((UDATA)_romClass) + offset;191J9ROMMethod *currentMethod = J9ROMCLASS_ROMMETHODS(_romClass);192193for (UDATA i = 0; i < _romClass->romMethodCount; i++) {194/* There's no easy way to get the exact end of a ROMMethod, so iterate195* thru the methods until we get to the last one.196*197* TODO:198* - If a bad & large address is being looked for the last method199* will be returned.200* - If a bad & small address is being looked for then null will be returned.201* - A function similar to nextROMMethod should maybe written to replace this logic,202* except have it return the end addr of the method.203*/204if (romclassaddr >= (UDATA)currentMethod) {205returnMethod = currentMethod;206currentMethod = nextROMMethod(currentMethod);207continue;208} else {209break;210}211}212}213return returnMethod;214}215216217