/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * LECCProgram.java * Created: Nov 24, 2003 5:55:26 PM * By: RCypher */ package org.openquark.cal.internal.machine.lecc; import java.util.HashSet; import java.util.List; import java.util.Set; import org.openquark.cal.compiler.ModuleName; import org.openquark.cal.machine.Module; import org.openquark.cal.machine.Program; import org.openquark.cal.machine.ProgramResourceRepository; import org.openquark.cal.module.Cal.Core.CAL_Prelude; import org.openquark.cal.runtime.ExecutionContext; /** * The lecc machine specific version of the Program class. * * @author rcypher */ final class LECCProgram extends Program { private final ProgramResourceRepository resourceRepository; /** * Constructor for a LECCProgram. * @param resourceRepository the finder for resources generated by this program. */ LECCProgram(ProgramResourceRepository resourceRepository) { this.resourceRepository = resourceRepository; } /** * {@inheritDoc} */ @Override synchronized public void resetCachedResults(ExecutionContext context) { resetCachedResults (CAL_Prelude.MODULE_NAME, context); } /** * {@inheritDoc} */ @Override synchronized public void resetCachedResults (ModuleName moduleName, ExecutionContext context) { resetCachedResultsHelper (moduleName, context, new HashSet<ModuleName>()); // run the cleanup hooks when the CAFs are released. context.cleanup(); } synchronized private void resetCachedResultsHelper(ModuleName moduleName, ExecutionContext context, Set<ModuleName> resetModules) { if (resetModules.contains (moduleName)) { return; } LECCModule m = (LECCModule)getModule(moduleName); if (m == null) { return; } m.resetCachedResults(context); resetModules.add (moduleName); for (final Module m2 : getModules()) { if (m2.dependsOn(moduleName)) { resetCachedResultsHelper(m2.getName(), context, resetModules); } } } /** * {@inheritDoc} */ @Override synchronized public void resetMachineState(ExecutionContext context) { resetMachineState(CAL_Prelude.MODULE_NAME, context); } /** * {@inheritDoc} */ @Override synchronized public void resetMachineState (ModuleName moduleName, ExecutionContext context) { resetMachineStateHelper(moduleName, context, new HashSet<ModuleName>()); // run the cleanup hooks when the CAFs are released. context.cleanup(); } /** * Helper method for resetting the machine state for a given module. * @param moduleName the module whose associated machine state is to be reset. * @param context the context with which the machine state is associated. * @param resetModules the modules that have already had their machine state reset. */ synchronized private void resetMachineStateHelper(ModuleName moduleName, ExecutionContext context, Set/*ModuleName*/<ModuleName> resetModules) { if (resetModules.contains (moduleName)) { return; } LECCModule m = (LECCModule)getModule(moduleName); if (m == null) { return; } m.resetMachineState(context); resetModules.add (moduleName); for (final Module m2 : getModules()) { if (m2.dependsOn(moduleName)) { resetMachineStateHelper(m2.getName(), context, resetModules); } } } /** * @return the machine statistics associated with this program. */ synchronized public LECCMachineStatistics getMachineStatistics() { int totalNRegularClassesLoaded = 0; int totalNAdjunctClassesLoaded = 0; int totalNRegularBytesLoaded = 0; int totalNAdjunctBytesLoaded = 0; long totalGenerateRegularClassDataTimeMS = 0; long totalGenerateAdjunctClassDataTimeMS = 0; long totalLookupRegularClassDataTimeMS = 0; long totalLookupAdjunctClassDataTimeMS = 0; long totalRegularFindClassTimeMS = 0; long totalAdjunctFindClassTimeMS = 0; for (final Module moduleBase : getModules()) { LECCModule module = (LECCModule)moduleBase; totalNRegularClassesLoaded += module.getNClassesLoaded(false); totalNAdjunctClassesLoaded += module.getNClassesLoaded(true); totalNRegularBytesLoaded += module.getNClassBytesLoaded(false); totalNAdjunctBytesLoaded += module.getNClassBytesLoaded(true); totalGenerateRegularClassDataTimeMS += module.getGenerateClassDataTimeMS(false); totalGenerateAdjunctClassDataTimeMS += module.getGenerateClassDataTimeMS(true); totalLookupRegularClassDataTimeMS += module.getLookupClassDataTimeMS(false); totalLookupAdjunctClassDataTimeMS += module.getLookupClassDataTimeMS(true); totalRegularFindClassTimeMS += module.getFindClassTimeMS(false); totalAdjunctFindClassTimeMS += module.getFindClassTimeMS(true); } return new LECCMachineStatistics( totalNRegularClassesLoaded, totalNAdjunctClassesLoaded, totalNRegularBytesLoaded, totalNAdjunctBytesLoaded, CALClassLoader.PERFORM_TIMING, totalGenerateRegularClassDataTimeMS, totalGenerateAdjunctClassDataTimeMS, totalLookupRegularClassDataTimeMS, totalLookupAdjunctClassDataTimeMS, totalRegularFindClassTimeMS, totalAdjunctFindClassTimeMS); } /** * @param moduleName * @return the machine statistics associated with the given module. */ synchronized public LECCMachineStatistics getMachineStatisticsForModule(ModuleName moduleName) { LECCModule module = (LECCModule)getModule(moduleName); if (module == null) { return new LECCMachineStatistics(0, 0, 0, 0, false, 0, 0, 0, 0, 0, 0); } int totalNRegularClassesLoaded = module.getNClassesLoaded(false); int totalNAdjunctClassesLoaded = module.getNClassesLoaded(true); int totalNRegularBytesLoaded = module.getNClassBytesLoaded(false); int totalNAdjunctBytesLoaded = module.getNClassBytesLoaded(true); long totalGenerateRegularClassDataTimeMS = module.getGenerateClassDataTimeMS(false); long totalGenerateAdjunctClassDataTimeMS = module.getGenerateClassDataTimeMS(true); long totalLookupRegularClassDataTimeMS = module.getLookupClassDataTimeMS(false); long totalLookupAdjunctClassDataTimeMS = module.getLookupClassDataTimeMS(true); long totalRegularFindClassTimeMS = module.getFindClassTimeMS(false); long totalAdjunctFindClassTimeMS = module.getFindClassTimeMS(true); return new LECCMachineStatistics( totalNRegularClassesLoaded, totalNAdjunctClassesLoaded, totalNRegularBytesLoaded, totalNAdjunctBytesLoaded, CALClassLoader.PERFORM_TIMING, totalGenerateRegularClassDataTimeMS, totalGenerateAdjunctClassDataTimeMS, totalLookupRegularClassDataTimeMS, totalLookupAdjunctClassDataTimeMS, totalRegularFindClassTimeMS, totalAdjunctFindClassTimeMS); } /** * Add a module to this program. * Normally called by a Loader. * Derived Program classes create a type-specific module object and then call addModule (Module) * Creation date: (3/17/00 4:11:18 PM) * @param moduleName * @param foreignClassLoader the classloader to use to resolve foreign classes for the module. * @return the newly created Module */ @Override synchronized public Module addModule(ModuleName moduleName, ClassLoader foreignClassLoader) { Module module = new LECCModule(moduleName, foreignClassLoader, resourceRepository); addModule (module); return module; } /** * Add the given module to this program. * @param module */ @Override synchronized public void addModule (Module module) { super.addModule (module); // Deserialization code does not set the repository. LECCModule leccModule = (LECCModule)module; if (!leccModule.hasRepository()) { leccModule.setRepository(resourceRepository); } } @Override public String toString () { StringBuilder sb = new StringBuilder(); sb.append ("Program: "); List<Module> modules = getModules(); for (int i = 0, n = modules.size(); i < n; ++i) { sb.append((modules.get(i)).getName()); if (i < n-1) { sb.append(", "); } } return sb.toString(); } }