mirror of https://github.com/sbt/sbt.git
Type cache in API extraction for smaller cache size and faster I/O
manually implement Modifiers, use byte-size bit field
This commit is contained in:
parent
1795ddadb3
commit
403fa42fa2
|
|
@ -44,14 +44,29 @@ final class API(val global: Global, val callback: xsbti.AnalysisCallback) extend
|
|||
val packages = traverser.packages.toArray[String].map(p => new xsbti.api.Package(p))
|
||||
val source = new xsbti.api.Source(packages, traverser.definitions.toArray[xsbti.api.Definition])
|
||||
forceStructures()
|
||||
clearCaches()
|
||||
callback.api(sourceFile, source)
|
||||
}
|
||||
}
|
||||
|
||||
// this cache reduces duplicate work both here and when persisting
|
||||
// caches on other structures had minimal effect on time and cache size
|
||||
// (tried: Definition, Modifier, Path, Id, String)
|
||||
private[this] val typeCache = new HashMap[Type, xsbti.api.Type]
|
||||
// these caches are necessary for correctness
|
||||
private[this] val structureCache = new HashMap[Symbol, xsbti.api.Structure]
|
||||
private[this] val classLikeCache = new HashMap[Symbol, xsbti.api.ClassLike]
|
||||
private[this] val pending = new HashSet[xsbti.api.Lazy[_]]
|
||||
|
||||
// to mitigate "temporary leaks" like that caused by NoPhase in 2.8.0,
|
||||
// this ensures this class is not retaining objects
|
||||
private def clearCaches()
|
||||
{
|
||||
typeCache.clear()
|
||||
structureCache.clear()
|
||||
classLikeCache.clear()
|
||||
}
|
||||
|
||||
// call back to the xsbti.SafeLazy class in main sbt code to construct a SafeLazy instance
|
||||
// we pass a thunk, whose class is loaded by the interface class loader (this class's loader)
|
||||
// SafeLazy ensures that once the value is forced, the thunk is nulled out and so
|
||||
|
|
@ -256,6 +271,7 @@ final class API(val global: Global, val callback: xsbti.AnalysisCallback) extend
|
|||
new xsbti.api.Modifiers(s.hasFlag(ABSTRACT) || s.hasFlag(DEFERRED), s.hasFlag(OVERRIDE),
|
||||
s.isFinal, s.hasFlag(SEALED), isImplicit(s), s.hasFlag(LAZY))
|
||||
}
|
||||
|
||||
private def isImplicit(s: Symbol) = s.hasFlag(Flags.IMPLICIT)
|
||||
private def getAccess(c: Symbol): xsbti.api.Access =
|
||||
{
|
||||
|
|
@ -270,7 +286,8 @@ final class API(val global: Global, val callback: xsbti.AnalysisCallback) extend
|
|||
else new xsbti.api.Private(qualifier)
|
||||
}
|
||||
}
|
||||
private def processType(t: Type): xsbti.api.Type =
|
||||
private def processType(t: Type): xsbti.api.Type = typeCache.getOrElseUpdate(t, makeType(t))
|
||||
private def makeType(t: Type): xsbti.api.Type =
|
||||
{
|
||||
def dealias(t: Type) = t match { case TypeRef(_, sym, _) if sym.isAliasType => t.normalize; case _ => t }
|
||||
|
||||
|
|
@ -394,5 +411,5 @@ final class API(val global: Global, val callback: xsbti.AnalysisCallback) extend
|
|||
if(annots.isEmpty) processType(at.underlying) else annotated(annots, at.underlying)
|
||||
}
|
||||
private def fullName(s: Symbol): String = nameString(s)
|
||||
private def simpleName(s: Symbol): String = s.simpleName.toString.trim
|
||||
private def simpleName(s: Symbol): String = s.simpleName.toString.trim
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,6 @@ Qualifier
|
|||
IdQualifier
|
||||
value: String
|
||||
|
||||
Modifiers
|
||||
isAbstract: Boolean
|
||||
isOverride: Boolean
|
||||
isFinal: Boolean
|
||||
isSealed: Boolean
|
||||
isImplicit: Boolean
|
||||
isLazy: Boolean
|
||||
|
||||
ParameterList
|
||||
parameters: MethodParameter*
|
||||
isImplicit: Boolean
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package xsbti.api;
|
||||
|
||||
public final class Modifiers implements java.io.Serializable
|
||||
{
|
||||
private static final int AbstractBit = 0;
|
||||
private static final int OverrideBit = 1;
|
||||
private static final int FinalBit = 2;
|
||||
private static final int SealedBit = 3;
|
||||
private static final int ImplicitBit = 4;
|
||||
private static final int LazyBit = 5;
|
||||
|
||||
private static final int flag(boolean set, int bit)
|
||||
{
|
||||
return set ? (1 << bit) : 0;
|
||||
}
|
||||
|
||||
public Modifiers(boolean isAbstract, boolean isOverride, boolean isFinal, boolean isSealed, boolean isImplicit, boolean isLazy)
|
||||
{
|
||||
this.flags = (byte)(
|
||||
flag(isAbstract, AbstractBit) |
|
||||
flag(isOverride, OverrideBit) |
|
||||
flag(isFinal, FinalBit) |
|
||||
flag(isSealed, SealedBit) |
|
||||
flag(isImplicit, ImplicitBit) |
|
||||
flag(isLazy, LazyBit)
|
||||
);
|
||||
}
|
||||
|
||||
private final byte flags;
|
||||
|
||||
private final boolean flag(int bit)
|
||||
{
|
||||
return (flags & (1 << bit)) != 0;
|
||||
}
|
||||
|
||||
public final byte raw()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
|
||||
public final boolean isAbstract()
|
||||
{
|
||||
return flag(AbstractBit);
|
||||
}
|
||||
public final boolean isOverride()
|
||||
{
|
||||
return flag(OverrideBit);
|
||||
}
|
||||
public final boolean isFinal()
|
||||
{
|
||||
return flag(FinalBit);
|
||||
}
|
||||
public final boolean isSealed()
|
||||
{
|
||||
return flag(SealedBit);
|
||||
}
|
||||
public final boolean isImplicit()
|
||||
{
|
||||
return flag(ImplicitBit);
|
||||
}
|
||||
public final boolean isLazy()
|
||||
{
|
||||
return flag(LazyBit);
|
||||
}
|
||||
public String toString()
|
||||
{
|
||||
return "Modifiers(" + "isAbstract: " + isAbstract() + ", " + "isOverride: " + isOverride() + ", " + "isFinal: " + isFinal() + ", " + "isSealed: " + isSealed() + ", " + "isImplicit: " + isImplicit() + ", " + "isLazy: " + isLazy()+ ")";
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue