platform: class cache logging centralized; obsolete timing dropped

This commit is contained in:
Roman Shevchenko
2013-08-23 13:49:58 +04:00
parent 1dc531f6e2
commit 2a785d25fa
5 changed files with 68 additions and 115 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.plugins.cl;
import com.intellij.diagnostic.PluginException;
@@ -120,73 +119,44 @@ public class PluginClassLoader extends UrlClassLoader {
return aClass != null && aClass.getClassLoader() == this;
}
@Override
public URL findResource(final String name) {
final long started = myDebugTime ? System.nanoTime():0;
final URL resource = findResourceImpl(name);
if (resource != null) return resource;
try {
final URL resource = findResourceImpl(name);
if (resource != null) {
return resource;
}
for (ClassLoader parent : myParents) {
final URL parentResource = fetchResource(parent, name);
if (parentResource != null) return parentResource;
}
for (ClassLoader parent : myParents) {
final URL parentResource = fetchResource(parent, name);
if (parentResource != null) {
return parentResource;
}
}
return null;
}
finally {
long doneFor = myDebugTime ? (System.nanoTime() - started):0;
if (doneFor > NS_THRESHOLD) {
System.out.println((doneFor / 1000000) + " ms for " + (myPluginId != null?myPluginId.getIdString():null)+ ", resource:"+name);
}
}
return null;
}
@Nullable
@Override
public InputStream getResourceAsStream(final String name) {
final long started = myDebugTime ? System.nanoTime():0;
final InputStream stream = super.getResourceAsStream(name);
if (stream != null) return stream;
try {
final InputStream stream = super.getResourceAsStream(name);
if (stream != null) return stream;
for (ClassLoader parent : myParents) {
final InputStream inputStream = parent.getResourceAsStream(name);
if (inputStream != null) return inputStream;
}
return null;
}
finally {
long doneFor = myDebugTime ? System.nanoTime() - started:0;
if (doneFor > NS_THRESHOLD) {
System.out.println((doneFor/1000000) + " ms for " + (myPluginId != null?myPluginId.getIdString():null)+ ", resource as stream:"+name);
}
for (ClassLoader parent : myParents) {
final InputStream inputStream = parent.getResourceAsStream(name);
if (inputStream != null) return inputStream;
}
return null;
}
@Override
public Enumeration<URL> findResources(final String name) throws IOException {
final long started = myDebugTime ? System.nanoTime() : 0;
try {
final Enumeration[] resources = new Enumeration[myParents.length + 1];
resources[0] = super.findResources(name);
for (int idx = 0; idx < myParents.length; idx++) {
resources[idx + 1] = fetchResources(myParents[idx], name);
}
return new CompoundEnumeration<URL>(resources);
}
finally {
long doneFor = myDebugTime ? System.nanoTime() - started:0;
if (doneFor > NS_THRESHOLD) {
System.out.println((doneFor / 1000000) + " ms for " + (myPluginId != null?myPluginId.getIdString():null)+ ", find resources:"+name);
}
final Enumeration[] resources = new Enumeration[myParents.length + 1];
resources[0] = super.findResources(name);
for (int idx = 0; idx < myParents.length; idx++) {
resources[idx + 1] = fetchResources(myParents[idx], name);
}
return new CompoundEnumeration<URL>(resources);
}
@Override
protected String findLibrary(String libName) {
if (myLibDirectory == null) {
return null;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @author max
*/
package com.intellij.util.lang;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringHash;
import com.intellij.util.ArrayUtil;
import com.intellij.util.BloomFilterBase;
@@ -35,8 +32,13 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author max
*/
public class ClasspathCache {
private static final boolean doDebug = false;
static final Logger LOG = Logger.getInstance(ClasspathCache.class);
static final boolean doDebug = LOG.isDebugEnabled();
private final DebugInfo myDebugInfo;
private final TIntObjectHashMap<Object> myResourcePackagesCache = new TIntObjectHashMap<Object>();
@@ -114,9 +116,9 @@ public class ClasspathCache {
Set<Loader> loaders = myResources2LoadersTempMap.get(name);
if (loaders == null) myResources2LoadersTempMap.put(name, loaders = new THashSet<Loader>());
boolean added = loaders.add(loader);
if (UrlClassLoader.doDebug && added) ++registeredBeforeClose;
if (doDebug && added) ++registeredBeforeClose;
} else {
if (UrlClassLoader.doDebug) {
if (doDebug) {
if (!myNameFilter.maybeContains(name, loader)) ++registeredAfterClose;
}
@@ -147,8 +149,8 @@ public class ClasspathCache {
}
}
if (requests % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("Avoided disk hits: "+hits + " from " + requests + (doDebug ? ", false hits:" + falseHits + ", bitmap diffs:"+diffs3:""));
if (requests % 1000 == 0 && doDebug) {
LOG.debug("Avoided disk hits: " + hits + " from " + requests + ", false hits:" + falseHits + ", bitmap diffs:" + diffs3);
}
}
else {
@@ -176,8 +178,8 @@ public class ClasspathCache {
}
}
if (requests2 % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("Avoided disk hits2: "+hits2 + " from " + requests2 + (doDebug ? "," + diffs + ", false hits:" + falseHits2 + ", bitmap diffs:"+diffs2:""));
if (requests2 % 1000 == 0 && doDebug) {
LOG.debug("Avoided disk hits2: " + hits2 + " from " + requests2 + "," + diffs + ", false hits:" + falseHits2 + ", bitmap diffs:" + diffs2);
}
}
@@ -215,14 +217,14 @@ public class ClasspathCache {
void nameSymbolsLoaded() {
if (!myTempMapMode) {
if (UrlClassLoader.doDebug && registeredAfterClose > 0) {
UrlClassLoader.debug("Registered number of classes after close "+registeredAfterClose + " "+toString());
if (doDebug && registeredAfterClose > 0) {
LOG.debug("Registered number of classes after close " + registeredAfterClose + " " + toString());
}
return;
}
if (UrlClassLoader.doDebug) {
UrlClassLoader.debug("Registered number of classes before classes "+registeredBeforeClose + " "+toString());
if (doDebug) {
LOG.debug("Registered number of classes before classes " + registeredBeforeClose + " " + toString());
}
myTempMapMode = false;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.lang;
import com.intellij.openapi.util.io.FileUtil;
@@ -88,14 +87,14 @@ class FileLoader extends Loader {
if (!check || file.exists()) { // check means we load or process resource so we check its existence via old way
if (check) {
++misses;
if (misses % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("[Sample of] missed resource " + name + " from " + myRootDir);
if (misses % 1000 == 0 && ClasspathCache.doDebug) {
ClasspathCache.LOG.debug("[Sample of] missed resource " + name + " from " + myRootDir);
}
}
++hits;
if (hits % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("Exists file loader: misses:" + misses + ", hits:" + hits);
if (hits % 1000 == 0 && ClasspathCache.doDebug) {
ClasspathCache.LOG.debug("Exists file loader: misses:" + misses + ", hits:" + hits);
}
return new MyResource(name, url, file, !check);
@@ -103,8 +102,8 @@ class FileLoader extends Loader {
}
catch (Exception exception) {
++misses;
if (misses % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("Missed " + name + " from " + myRootDir);
if (misses % 1000 == 0 && ClasspathCache.doDebug) {
ClasspathCache.LOG.debug("Missed " + name + " from " + myRootDir);
}
if (!check && file != null && file.exists()) {
try { // we can not open the file if it is directory, Resource still can be created
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.lang;
import com.intellij.openapi.diagnostic.Logger;
@@ -162,14 +161,14 @@ class JarLoader extends Loader {
ZipEntry entry = file.getEntry(name);
if (entry != null) {
++hits;
if (hits % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("Exists jar loader: misses:" + misses + ", hits:" + hits);
if (hits % 1000 == 0 && ClasspathCache.doDebug) {
ClasspathCache.LOG.debug("Exists jar loader: misses:" + misses + ", hits:" + hits);
}
return new MyResource(entry, new URL(getBaseURL(), name));
}
if (misses % 1000 == 0 && UrlClassLoader.doDebug) {
UrlClassLoader.debug("Missed " + name + " from jar:" + myURL);
if (misses % 1000 == 0 && ClasspathCache.doDebug) {
ClasspathCache.LOG.debug("Missed " + name + " from jar:" + myURL);
}
++misses;
}
@@ -184,7 +183,7 @@ class JarLoader extends Loader {
}
final long doneFor = myDebugTime ? System.nanoTime() - started :0;
if (doneFor > NS_THRESHOLD) {
System.out.println(doneFor/1000000 + " ms for jar loader get resource:"+name);
ClasspathCache.LOG.debug(doneFor/1000000 + " ms for jar loader get resource:"+name);
}
}
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.lang;
import com.intellij.openapi.diagnostic.Logger;
@@ -35,11 +34,10 @@ import java.util.Enumeration;
import java.util.List;
public class UrlClassLoader extends ClassLoader {
@NonNls static final String CLASS_EXTENSION = ".class";
private final ClassPath myClassPath;
private final List<URL> myURLs;
@NonNls static final String CLASS_EXTENSION = ".class";
protected static final boolean myDebugTime = false;
protected static final long NS_THRESHOLD = 10000000;
public UrlClassLoader(@NotNull ClassLoader parent) {
this(Arrays.asList(((URLClassLoader)parent).getURLs()), parent.getParent(), true, true);
@@ -57,7 +55,12 @@ public class UrlClassLoader extends ClassLoader {
this(urls, parent, canLockJars, canUseCache, false, true);
}
public UrlClassLoader(List<URL> urls, @Nullable ClassLoader parent, boolean canLockJars, boolean canUseCache, boolean acceptUnescapedUrls, final boolean preloadJarContents) {
public UrlClassLoader(List<URL> urls,
@Nullable ClassLoader parent,
boolean canLockJars,
boolean canUseCache,
boolean acceptUnescapedUrls,
boolean preloadJarContents) {
super(parent);
List<URL> list = ContainerUtil.map(urls, new Function<URL, URL>() {
@@ -70,7 +73,6 @@ public class UrlClassLoader extends ClassLoader {
myURLs = list;
}
@NotNull
public static URL internProtocol(@NotNull URL url) {
try {
final String protocol = url.getProtocol();
@@ -80,7 +82,7 @@ public class UrlClassLoader extends ClassLoader {
return url;
}
catch (MalformedURLException e) {
LOG.error(e);
Logger.getInstance(UrlClassLoader.class).error(e);
return null;
}
}
@@ -133,12 +135,12 @@ public class UrlClassLoader extends ClassLoader {
private Class defineClass(String name, Resource res) throws IOException {
int i = name.lastIndexOf('.');
if (i != -1) {
String pkgname = name.substring(0, i);
String pkgName = name.substring(0, i);
// Check if package already loaded.
Package pkg = getPackage(pkgname);
Package pkg = getPackage(pkgName);
if (pkg == null) {
try {
definePackage(pkgname, null, null, null, null, null, null, null);
definePackage(pkgName, null, null, null, null, null, null, null);
}
catch (IllegalArgumentException e) {
// do nothing, package already defined by some other thread
@@ -157,28 +159,17 @@ public class UrlClassLoader extends ClassLoader {
@Override
@Nullable // Accessed from PluginClassLoader via reflection // TODO do we need it?
public URL findResource(final String name) {
final long started = myDebugTime ? System.nanoTime():0;
try {
return findResourceImpl(name);
} finally {
long doneFor = myDebugTime ? (System.nanoTime() - started):0;
if (doneFor > NS_THRESHOLD) {
System.out.println((doneFor / 1000000) + " ms for UrlClassLoader.getResource, resource:"+name);
}
}
return findResourceImpl(name);
}
protected URL findResourceImpl(final String name) {
Resource res = _getResource(name);
if (res == null) return null;
return res.getURL();
return res != null ? res.getURL() : null;
}
@Nullable
private Resource _getResource(final String name) {
String n = name;
if (n.startsWith("/")) n = n.substring(1);
return myClassPath.getResource(n, true);
}
@@ -201,12 +192,4 @@ public class UrlClassLoader extends ClassLoader {
protected Enumeration<URL> findResources(String name) throws IOException {
return myClassPath.getResources(name, true);
}
static final boolean doDebug = System.getProperty("idea.classloading.debug") != null;
private static final Logger LOG = Logger.getInstance("idea.UrlClassLoader");
static void debug(String s) {
System.out.println(s); // TODO: remove
LOG.debug(s);
}
}