Release generated bytecode after each processed part

Part here means separate '.kt' file or multi-file facade
Now this memory optimization doesn't work with jar's,
because there is no simple way to write them incrementally.
This commit is contained in:
Denis Zharkov
2016-02-18 15:06:05 +03:00
parent b87cc5712c
commit bc5110550a
7 changed files with 75 additions and 11 deletions
@@ -36,8 +36,12 @@ public class ClassBuilderOnDemand extends DelegatingClassBuilder {
@Override
public void done() {
if (classBuilder.isComputed()) {
if (isComputed()) {
classBuilder.invoke().done();
}
}
public boolean isComputed() {
return classBuilder.isComputed();
}
}
@@ -92,6 +92,10 @@ public class ClassFileFactory implements OutputFileCollection {
}
}
public void releaseGeneratedOutput() {
generators.clear();
}
private void writeModuleMappings() {
final JvmPackageTable.PackageTable.Builder builder = JvmPackageTable.PackageTable.newBuilder();
String outputFilePath = getMappingFileName(state.getModuleName());
@@ -144,6 +148,11 @@ public class ClassFileFactory implements OutputFileCollection {
@Override
public List<OutputFile> asList() {
done();
return getCurrentOutput();
}
@NotNull
public List<OutputFile> getCurrentOutput() {
return ContainerUtil.map(generators.keySet(), new Function<String, OutputFile>() {
@Override
public OutputFile fun(String relativeClassFilePath) {
@@ -127,6 +127,7 @@ class MultifileClassCodegen(
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
try {
generatePart(file, generateCallableMemberTasks, partFqNames)
state.afterIndependentPart()
}
catch (e: ProcessCanceledException) {
throw e
@@ -292,6 +293,9 @@ class MultifileClassCodegen(
private fun done() {
classBuilder.done()
if (classBuilder.isComputed) {
state.afterIndependentPart()
}
}
companion object {
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
import org.jetbrains.kotlin.load.kotlin.PackageParts;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.psi.*;
@@ -60,6 +59,7 @@ public class PackageCodegen {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
try {
generateFile(file);
state.afterIndependentPart();
}
catch (ProcessCanceledException e) {
throw e;
@@ -67,7 +67,8 @@ class GenerationState @JvmOverloads constructor(
val outDirectory: File? = null,
val incrementalCompilationComponents: IncrementalCompilationComponents? = null,
val generateOpenMultifileClasses: Boolean = false,
val progress: Progress = Progress.DEAF
val progress: Progress = Progress.DEAF,
private val onIndependentPartCompilationEnd: GenerationStateEventCallback = GenerationStateEventCallback.DO_NOTHING
) {
abstract class GenerateClassFilter {
abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
@@ -170,6 +171,10 @@ class GenerationState @JvmOverloads constructor(
CodegenBinding.initTrace(this)
}
fun afterIndependentPart() {
onIndependentPartCompilationEnd(this)
}
private fun markUsed() {
if (used) throw IllegalStateException("${GenerationState::class.java} cannot be used more than once")
@@ -197,3 +202,14 @@ private class LazyJvmDiagnostics(compute: () -> Diagnostics): Diagnostics {
override fun iterator() = delegate.iterator()
}
interface GenerationStateEventCallback : (GenerationState) -> Unit {
companion object {
val DO_NOTHING = GenerationStateEventCallback { }
}
}
fun GenerationStateEventCallback(block: (GenerationState) -> Unit): GenerationStateEventCallback =
object : GenerationStateEventCallback {
override fun invoke(s: GenerationState) = block(s)
}