From 7de36a6d33baf6e72c8bf42343b58d5e569ebcf7 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Tue, 9 Sep 2014 13:35:43 +0400 Subject: [PATCH] Disk cached classes and programs --- .../cache/ClassPathClassDateProvider.java | 57 ------------------- .../cache/DiskCachedClassHolderSource.java | 3 +- .../org/teavm/cache/DiskProgramCache.java | 6 +- .../java/org/teavm/cache/FileSymbolTable.java | 2 +- .../main/java/org/teavm/cache/ProgramIO.java | 2 +- .../{cache => parsing}/ClassDateProvider.java | 2 +- .../parsing/ClasspathClassHolderSource.java | 11 +++- .../parsing/ClasspathResourceMapper.java | 53 ++++++++++++++++- 8 files changed, 68 insertions(+), 68 deletions(-) delete mode 100644 teavm-core/src/main/java/org/teavm/cache/ClassPathClassDateProvider.java rename teavm-core/src/main/java/org/teavm/{cache => parsing}/ClassDateProvider.java (96%) diff --git a/teavm-core/src/main/java/org/teavm/cache/ClassPathClassDateProvider.java b/teavm-core/src/main/java/org/teavm/cache/ClassPathClassDateProvider.java deleted file mode 100644 index 159597936..000000000 --- a/teavm-core/src/main/java/org/teavm/cache/ClassPathClassDateProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.cache; - -import java.io.File; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Date; - -/** - * - * @author Alexey Andreev - */ -public class ClassPathClassDateProvider implements ClassDateProvider { - private ClassLoader classLoader; - - public ClassPathClassDateProvider(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - @Override - public Date getModificationDate(String className) { - URL url = classLoader.getResource(className.replace('.', '/') + ".class"); - if (url == null) { - return null; - } - if (url.getProtocol().equals("file")) { - try { - File file = new File(url.toURI()); - return file.exists() ? new Date(file.lastModified()) : null; - } catch (URISyntaxException e) { - // If URI is invalid, we just report that class should be reparsed - return null; - } - } else if (url.getProtocol().equals("jar") && url.getPath().startsWith("file:")) { - int exclIndex = url.getPath().indexOf('!'); - String jarFileName = exclIndex >= 0 ? url.getPath().substring(0, exclIndex) : url.getPath(); - File file = new File(jarFileName.substring("file:".length())); - return file.exists() ? new Date(file.lastModified()) : null; - } else { - return null; - } - } -} diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java b/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java index 5d998633b..5a62200aa 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java @@ -18,6 +18,7 @@ package org.teavm.cache; import java.io.*; import java.util.*; import org.teavm.model.*; +import org.teavm.parsing.ClassDateProvider; /** * @@ -53,7 +54,7 @@ public class DiskCachedClassHolderSource implements ClassHolderSource { if (classFile.exists()) { Date classDate = classDateProvider.getModificationDate(name); if (classDate != null && classDate.before(new Date(classFile.lastModified()))) { - try (InputStream input = new FileInputStream(classFile)) { + try (InputStream input = new BufferedInputStream(new FileInputStream(classFile))) { item.cls = readClass(input, name); } catch (IOException e) { // We could not access cache file, so let's parse class file diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskProgramCache.java b/teavm-core/src/main/java/org/teavm/cache/DiskProgramCache.java index 66801d0f4..dc40c9d91 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskProgramCache.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskProgramCache.java @@ -19,6 +19,7 @@ import java.io.*; import java.util.*; import org.teavm.model.*; import org.teavm.model.instructions.*; +import org.teavm.parsing.ClassDateProvider; /** * @@ -46,7 +47,7 @@ public class DiskProgramCache implements ProgramCache { cache.put(method, item); File file = getMethodFile(method); if (file.exists()) { - try (InputStream stream = new FileInputStream(file)) { + try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) { DataInput input = new DataInputStream(stream); int depCount = input.readShort(); boolean dependenciesChanged = false; @@ -66,9 +67,6 @@ public class DiskProgramCache implements ProgramCache { } } } - if (item.program == null) { - System.out.println(method); - } return item.program; } diff --git a/teavm-core/src/main/java/org/teavm/cache/FileSymbolTable.java b/teavm-core/src/main/java/org/teavm/cache/FileSymbolTable.java index 494894f1e..c42052af6 100644 --- a/teavm-core/src/main/java/org/teavm/cache/FileSymbolTable.java +++ b/teavm-core/src/main/java/org/teavm/cache/FileSymbolTable.java @@ -39,7 +39,7 @@ public class FileSymbolTable implements SymbolTable { symbols.clear(); symbolMap.clear(); firstUnstoredIndex = 0; - try (DataInputStream input = new DataInputStream(new FileInputStream(file))) { + try (DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream(file)))) { while (true) { int length = input.read(); if (length == -1) { diff --git a/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java b/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java index 40d9f1542..1d7b9a60c 100644 --- a/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java @@ -130,7 +130,7 @@ public class ProgramIO { TryCatchBlock tryCatch = new TryCatchBlock(); int typeIndex = data.readInt(); if (typeIndex >= 0) { - tryCatch.setExceptionType(symbolTable.at(data.readShort())); + tryCatch.setExceptionType(symbolTable.at(typeIndex)); } short varIndex = data.readShort(); if (varIndex >= 0) { diff --git a/teavm-core/src/main/java/org/teavm/cache/ClassDateProvider.java b/teavm-core/src/main/java/org/teavm/parsing/ClassDateProvider.java similarity index 96% rename from teavm-core/src/main/java/org/teavm/cache/ClassDateProvider.java rename to teavm-core/src/main/java/org/teavm/parsing/ClassDateProvider.java index 4d87d2e3f..5ba3de271 100644 --- a/teavm-core/src/main/java/org/teavm/cache/ClassDateProvider.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ClassDateProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.cache; +package org.teavm.parsing; import java.util.Date; diff --git a/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java b/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java index 39bfb877c..a56c8616d 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java @@ -15,6 +15,7 @@ */ package org.teavm.parsing; +import java.util.Date; import org.teavm.model.ClassHolder; import org.teavm.model.ClassHolderSource; import org.teavm.resource.ClasspathResourceReader; @@ -25,13 +26,14 @@ import org.teavm.resource.ResourceClassHolderMapper; * * @author Alexey Andreev */ -public class ClasspathClassHolderSource implements ClassHolderSource { +public class ClasspathClassHolderSource implements ClassHolderSource, ClassDateProvider { private MapperClassHolderSource innerClassSource; + private ClasspathResourceMapper classPathMapper; public ClasspathClassHolderSource(ClassLoader classLoader) { ClasspathResourceReader reader = new ClasspathResourceReader(classLoader); ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader); - ClasspathResourceMapper classPathMapper = new ClasspathResourceMapper(classLoader, rawMapper); + classPathMapper = new ClasspathResourceMapper(classLoader, rawMapper); innerClassSource = new MapperClassHolderSource(classPathMapper); } @@ -43,4 +45,9 @@ public class ClasspathClassHolderSource implements ClassHolderSource { public ClassHolder get(String name) { return innerClassSource.get(name); } + + @Override + public Date getModificationDate(String className) { + return classPathMapper.getModificationDate(className); + } } diff --git a/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java b/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java index 71cb58048..58f784957 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java @@ -15,8 +15,10 @@ */ package org.teavm.parsing; +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URISyntaxException; import java.net.URL; import java.util.*; import org.teavm.common.CachedMapper; @@ -27,12 +29,13 @@ import org.teavm.model.ClassHolder; * * @author Alexey Andreev */ -public class ClasspathResourceMapper implements Mapper { +public class ClasspathResourceMapper implements Mapper, ClassDateProvider { private static final String PACKAGE_PREFIX = "packagePrefix."; private static final String CLASS_PREFIX = "classPrefix."; private Mapper innerMapper; private List transformations = new ArrayList<>(); private ClassRefsRenamer renamer; + private ClassLoader classLoader; private static class Transformation { String packageName; @@ -59,6 +62,7 @@ public class ClasspathResourceMapper implements Mapper { throw new RuntimeException("Error reading resources", e); } renamer = new ClassRefsRenamer(new CachedMapper<>(classNameMapper)); + this.classLoader = classLoader; } private void loadProperties(Properties properties, Map cache) { @@ -126,4 +130,51 @@ public class ClasspathResourceMapper implements Mapper { return renameClass(preimage); } }; + + @Override + public Date getModificationDate(String className) { + int dotIndex = className.lastIndexOf('.'); + String packageName; + String simpleName; + if (dotIndex > 0) { + packageName = className.substring(0, dotIndex + 1); + simpleName = className.substring(dotIndex + 1); + } else { + packageName = ""; + simpleName = className; + } + for (Transformation transformation : transformations) { + if (packageName.startsWith(transformation.packageName)) { + String fullName = transformation.packagePrefix + packageName + transformation.classPrefix + simpleName; + Date date = getOriginalModificationDate(fullName); + if (date != null) { + return date; + } + } + } + return getOriginalModificationDate(className); + } + + private Date getOriginalModificationDate(String className) { + URL url = classLoader.getResource(className.replace('.', '/') + ".class"); + if (url == null) { + return null; + } + if (url.getProtocol().equals("file")) { + try { + File file = new File(url.toURI()); + return file.exists() ? new Date(file.lastModified()) : null; + } catch (URISyntaxException e) { + // If URI is invalid, we just report that class should be reparsed + return null; + } + } else if (url.getProtocol().equals("jar") && url.getPath().startsWith("file:")) { + int exclIndex = url.getPath().indexOf('!'); + String jarFileName = exclIndex >= 0 ? url.getPath().substring(0, exclIndex) : url.getPath(); + File file = new File(jarFileName.substring("file:".length())); + return file.exists() ? new Date(file.lastModified()) : null; + } else { + return null; + } + } }