Skip to content

Commit

Permalink
Merge pull request bytedance#59 from bytedance/yangzhiqian/master
Browse files Browse the repository at this point in the history
merge internal
  • Loading branch information
yangzhiqian authored Sep 11, 2020
2 parents 749d951 + ce2edbd commit 6e3910c
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 70 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Change Log
### Version 0.2.2
- fix bugs:default transform configuration、NPE
- optimize daemon cache with --no-daemon

### Version 0.2.1
> optimize incremental build:Cache graph nodes with daemon
- optimize incremental build:Cache graph nodes with daemon

### Version 0.1.9
- optimize refer checker:More detailed error information
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Add those configuration code to your build.gradle, and apply your plugins on dem

```groovy
buildscript {
ext.plugin_version="0.2.1"
ext.plugin_version="0.2.2"
repositories {
google()
jcenter()
Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ ByteX是一个基于gradle transform api和ASM的字节码插件平台(或许

```groovy
buildscript {
ext.plugin_version="0.2.1"
ext.plugin_version="0.2.2"
repositories {
google()
jcenter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.ss.android.ugc.bytex.transformer.utils.Service;

import org.gradle.api.Project;
import org.gradle.api.internal.project.ProjectInternal;
import org.gradle.launcher.daemon.server.scaninfo.DaemonScanInfo;
import org.objectweb.asm.tree.ClassNode;

import java.io.File;
Expand Down Expand Up @@ -68,8 +70,8 @@ public TransformContext(TransformInvocation invocation, Project project, AppExte
graphCacheFile = new File(byteXBuildDir(), "graphCache.json");
this.shouldSaveCache = shouldSaveCache;
this.locator = new Locator(this);
this.transformOutputs = new TransformOutputs(this, invocation, new File(byteXBuildDir(), "outputs.txt"), isPluginIncremental, shouldSaveCache, useRawCache);
this.transformInputs = new TransformInputs(this, invocation, new File(byteXBuildDir(), "inputs.txt"), isPluginIncremental, shouldSaveCache, useRawCache);
this.transformOutputs = new TransformOutputs(this, invocation, new File(byteXBuildDir(), "outputs.txt"), isPluginIncremental, shouldSaveCache, !isDaemonSingleUse() && useRawCache);
this.transformInputs = new TransformInputs(this, invocation, new File(byteXBuildDir(), "inputs.txt"), isPluginIncremental, shouldSaveCache, !isDaemonSingleUse() && useRawCache);
this.finder = new ClassNodeLoader(this);
}

Expand Down Expand Up @@ -219,6 +221,16 @@ synchronized void markRunningState(State state) {
this.state = state;
}

/**
* daemon是否在构建之后会被杀死,这个对于使用daemon缓存数据有作用
* Whether the daemon will be killed after build finish, this is useful for using the daemon to cache data
*
* @return true 表示构建结束后会被杀死,类似于--no-daemon
*/
public boolean isDaemonSingleUse() {
return ((ProjectInternal) project).getServices().get(DaemonScanInfo.class).isSingleUse();
}

public void release() {
transformInputs.saveCache();
transformInputs.release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public Set<? super QualifiedContent.Scope> getScopes() {
result = Sets.union(result, scopes);
}
}
if (result.isEmpty()) {
return TransformManager.SCOPE_FULL_PROJECT;
}
return result;
}

Expand All @@ -83,6 +86,9 @@ public Set<QualifiedContent.ContentType> getOutputTypes() {
result = Sets.union(result, outputTypes);
}
}
if (result.isEmpty()) {
return TransformManager.CONTENT_CLASS;
}
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.ss.android.ugc.bytex.common.IPlugin
import com.ss.android.ugc.bytex.common.builder.ByteXBuildListener
import com.ss.android.ugc.bytex.common.configuration.BooleanProperty
import com.ss.android.ugc.bytex.common.flow.TransformFlow
import com.ss.android.ugc.bytex.common.flow.main.LifecycleAwareManProcessHandler
import com.ss.android.ugc.bytex.common.flow.main.LifecycleAwareMainProcessHandler
import com.ss.android.ugc.bytex.common.flow.main.MainProcessHandler
import com.ss.android.ugc.bytex.common.flow.main.MainProcessHandlerListener
import com.ss.android.ugc.bytex.transformer.TransformEngine
Expand All @@ -33,7 +33,7 @@ internal object DefaultByteXBuildListener : ByteXBuildListener, MainProcessHandl
DefaultByteXBuildListener.project = project
validRun = false
if (!plugin.transformConfiguration().isIncremental) {
System.err.println("[ByteX Warning]:" + this.javaClass.name + " does not yet support incremental build")
System.err.println("[ByteX Warning]:" + plugin.javaClass.name + " does not yet support incremental build")
}
PluginStatus(project, plugin).apply {
pluginStatuses[plugin] = this
Expand Down Expand Up @@ -65,13 +65,13 @@ internal object DefaultByteXBuildListener : ByteXBuildListener, MainProcessHandl
override fun onByteXPluginTransformStart(transform: Transform, transformInvocation: TransformInvocation) {
validRun = true
currentTransformInfo = TransformInfo(transform, transformInvocation)
currentTransformInfo!!.task = project!!.tasks.filter {
currentTransformInfo!!.task = project?.tasks?.filter {
//此处不使用==是因为有些操作(比如构建优化或者监控等)会代理替换Transform
//此处实际上是对比了taskName,因为名字不会重复
it is TransformTask &&
it.transform.name == transform.name &&
Sets.difference(it.transform.inputTypes, transform.inputTypes).isEmpty()
}.firstOrNull()
}?.firstOrNull()
currentTransformInfo!!.startTime = System.currentTimeMillis()
}

Expand All @@ -98,7 +98,7 @@ internal object DefaultByteXBuildListener : ByteXBuildListener, MainProcessHandl
handlers[handler] = MainProcessHandlerInfo(handler)
if (handler is IPlugin) {
plugins.add(handler)
} else if (handler is LifecycleAwareManProcessHandler && handler.real is IPlugin) {
} else if (handler is LifecycleAwareMainProcessHandler && handler.real is IPlugin) {
plugins.add(handler.real)
}
}
Expand Down Expand Up @@ -364,7 +364,7 @@ internal object DefaultByteXBuildListener : ByteXBuildListener, MainProcessHandl
}

class MainProcessHandlerInfo(handler: MainProcessHandler) {
val name = if (handler is LifecycleAwareManProcessHandler) {
val name = if (handler is LifecycleAwareMainProcessHandler) {
handler.real
} else {
handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import org.objectweb.asm.tree.ClassNode
* Created by yangzhiqian on 2020/8/30<br/>
*/

class LifecycleAwareManProcessHandler(val real: MainProcessHandler) : MainProcessHandler by real {
class LifecycleAwareMainProcessHandler(val real: MainProcessHandler) : MainProcessHandler by real {
init {
MainProcessHandler::class.java.methods.filter {
it.isDefault
}.forEach {
try {
LifecycleAwareManProcessHandler::class.java.getDeclaredMethod(it.name, *it.parameterTypes)
LifecycleAwareMainProcessHandler::class.java.getDeclaredMethod(it.name, *it.parameterTypes)
} catch (e: NoSuchMethodException) {
throw RuntimeException("default methods in java interface must be overridden while using `by operation` in kotlin", e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class MainProcessHandlerContainer : Collection<MainProcessHandler> {

@Synchronized
fun add(element: MainProcessHandler): Boolean {
return handlers.add(LifecycleAwareManProcessHandler(element))
return handlers.add(LifecycleAwareMainProcessHandler(element))
}

@Synchronized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void runTransform() throws IOException, InterruptedException {
Schedulers.COMPUTATION().submitAndAwait(handlers, plugin -> plugin.startRunning(transformEngine));
if (!isOnePassEnough()) {
timer.startRecord("LOADCACHE");
GraphBuilder graphBuilder = new CachedGraphBuilder(getGraphCache(), context.isIncremental(), context.shouldSaveCache());
GraphBuilder graphBuilder = new CachedGraphBuilder(getGraphCache(), context.isIncremental(), context.shouldSaveCache(), !context.isDaemonSingleUse());
if (context.isIncremental() && !graphBuilder.isCacheValid()) {
throw new IllegalStateException("Transform is running as incrementally, but failed to load cache for the transform!");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
package com.ss.android.ugc.bytex.common.graph.cache;

import com.ss.android.ugc.bytex.common.configuration.BooleanProperty
import com.ss.android.ugc.bytex.common.graph.*
import com.ss.android.ugc.bytex.common.graph.Graph
import com.ss.android.ugc.bytex.common.graph.GraphBuilder
import com.ss.android.ugc.bytex.common.graph.Node
import java.io.File
import java.util.*
import java.util.concurrent.ConcurrentHashMap

class CachedGraphBuilder(private val graphCacheFile: File?, shouldLoadCache: Boolean, private val shouldSaveCache: Boolean) : GraphBuilder() {
private var useRamCache = true

constructor(graphCacheFile: File?, shouldLoadCache: Boolean, shouldSaveCache: Boolean, useRamCache: Boolean = true)
: this(graphCacheFile, shouldLoadCache, shouldSaveCache) {
this.useRamCache = useRamCache
}

private val graphCache =
AsynchronousGraphCacheStorage(
DefaultGraphCacheStorage(
if (BooleanProperty.ENABLE_RAM_CACHE.value() && BooleanProperty.ENABLE_RAM_NODES_CACHE.value()) {
if (useRamCache && BooleanProperty.ENABLE_RAM_CACHE.value() && BooleanProperty.ENABLE_RAM_NODES_CACHE.value()) {
RamNodeCacheStorage
} else {
null
},
GsonFileClassCacheStorage(
if (BooleanProperty.ENABLE_RAM_CACHE.value() && BooleanProperty.ENABLE_RAM_CLASSES_CACHE.value()) {
if (useRamCache && BooleanProperty.ENABLE_RAM_CACHE.value() && BooleanProperty.ENABLE_RAM_CLASSES_CACHE.value()) {
RamClassesCacheStorage
} else {
null
Expand Down Expand Up @@ -50,23 +58,6 @@ class CachedGraphBuilder(private val graphCacheFile: File?, shouldLoadCache: Boo
* from cache during incremental build
*/
internal fun addNodes(nodes: Map<String, Node>) {
//during incremental build, the classes which changed will be added again, and the calculation of the inheritance
//relationship will be repeated. Replace it with a de-duplicated list here
//增量时,原先的class changd会导致被add两次,计算继承关系会重复,这里替换成去重的list
for (node in nodes.values) {
if (node is ClassNode) {
if (node.children.isNotEmpty() && node.children !is SkipDuplicatedList) {
node.children = SkipDuplicatedList(node.children)
}
} else if (node is InterfaceNode) {
if (node.children.isNotEmpty() && node.children !is SkipDuplicatedList) {
node.children = SkipDuplicatedList(node.children)
}
if (node.implementedClasses.isNotEmpty() && node.implementedClasses !is SkipDuplicatedList) {
node.implementedClasses = SkipDuplicatedList(node.implementedClasses)
}
}
}
if (nodeMap.isEmpty() && nodes is ConcurrentHashMap) {
//减少复制
nodeMap = nodes
Expand All @@ -87,36 +78,4 @@ class CachedGraphBuilder(private val graphCacheFile: File?, shouldLoadCache: Boo
}
return graph
}


internal class SkipDuplicatedList<T>(c: Collection<T>) : LinkedList<T>(c) {

override fun add(element: T): Boolean {
if (contains(element)) {
return false
}
return super.add(element)
}

override fun add(index: Int, element: T) {
if (contains(element)) {
return
}
super.add(index, element)
}

override fun addFirst(element: T) {
if (contains(element)) {
return
}
super.addFirst(element)
}

override fun addLast(element: T) {
if (contains(element)) {
return
}
super.addLast(element)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.ss.android.ugc.bytex.common.graph.cache

import com.ss.android.ugc.bytex.common.graph.ClassNode
import com.ss.android.ugc.bytex.common.graph.InterfaceNode
import com.ss.android.ugc.bytex.common.graph.Node
import java.io.File
import java.util.*
import java.util.concurrent.ConcurrentHashMap

/**
Expand Down Expand Up @@ -32,8 +35,34 @@ internal object RamNodeCacheStorage : NodeCacheStorage {
if (t == null) {
return false
}
println("Save ByteX Nodes Cache(${d.size}) Success[RAM]:" + t.absolutePath)
//during incremental build, the classes which changed will be added again, and the calculation of the inheritance
//relationship will be repeated. Replace it with a de-duplicated list here
//增量时,原先的class changd会导致被add两次,计算继承关系会重复,这里替换成去重的list
for (node in d.values) {
if (node is ClassNode) {
if (node.children.isNotEmpty() && node.children !is SkipDuplicatedList) {
node.children = SkipDuplicatedList(node.children)
}
} else if (node is InterfaceNode) {
if (node.children.isNotEmpty() && node.children !is SkipDuplicatedList) {
node.children = SkipDuplicatedList(node.children)
}
if (node.implementedClasses.isNotEmpty() && node.implementedClasses !is SkipDuplicatedList) {
node.implementedClasses = SkipDuplicatedList(node.implementedClasses)
}
}
}
caches[t.absolutePath] = d
println("Save ByteX Nodes Cache(${d.size}) Success[RAM]:" + t.absolutePath)
return true
}

internal class SkipDuplicatedList<T>(c: Collection<T>) : LinkedList<T>(c) {
override fun add(element: T): Boolean {
if (contains(element)) {
return false
}
return super.add(element)
}
}
}
2 changes: 1 addition & 1 deletion gradle/ext.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ext {
upload_password_snapshot = PASSWORD_SNAPSHOT
upload_maven_url_snapshot = UPLOAD_MAVEN_URL_SNAPSHOT
upload_group = 'com.bytedance.android.byteX'
upload_version = "0.2.1${(useSnapshotMaven.toBoolean() ? "-${doSh("git config user.name")}-SNAPSHOT" : "")}"
upload_version = "0.2.2${(useSnapshotMaven.toBoolean() ? "-${doSh("git config user.name")}-SNAPSHOT" : "")}"
upload_dir = project.rootProject.file('gradle_plugins').path
gradle_version = '3.5.3'
gson_version = '2.8.2'
Expand Down

0 comments on commit 6e3910c

Please sign in to comment.