diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-01-25 09:06:38 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-01-25 09:06:38 +0000 |
commit | 4aa88bf92a0181b687a637bd0788eaabc3404db8 (patch) | |
tree | 586e0e7876c2d34a63ce91ea6981e5d42a83f51d | |
parent | a89483ede46d23cddb8fdf7c5a3517223c97f748 (diff) | |
parent | 04f25e91a87fb5314e2e7ad979641dd453e43dda (diff) | |
download | jacoco-4aa88bf92a0181b687a637bd0788eaabc3404db8.tar.gz |
Snap for 4565898 from 04f25e91a87fb5314e2e7ad979641dd453e43dda to pi-release
Change-Id: I2c2977b8782334f7c83759044260161bbb0ebb54
4 files changed, 101 insertions, 12 deletions
diff --git a/README.android b/README.android index cad30c6c..83866748 100644 --- a/README.android +++ b/README.android @@ -14,3 +14,10 @@ is the list of the changes: 1) Remove the creation of JmxRegistration in org.jacoco.agent.rt.internal.Agent. 2) Change default OutputMode to none in org.jacoco.core.runtime.AgentOptions +3) Change the runtime to reduce dependencies on core libraries. + Previously, Offline's static initializer would eagerly create an + Agent, a process which has lots of dependencies. With this change, + Offline only eagerly creates an ExecutionDataStore, which is much + more lightweight. The Agent is only created when it's actually + needed. This makes it possible to instrument a lot of more core + libraries without creating a circular dependency at runtime. diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java index 667a7d0f..f6c1e767 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Agent.java @@ -45,8 +45,26 @@ public class Agent implements IAgent { * @return global instance */ public static synchronized Agent getInstance(final AgentOptions options) { + // BEGIN android-change + return getInstance(options, new RuntimeData()); + // END android-change + } + + // BEGIN android-change + /** + * Returns a global instance which is already started, reusing an existing set of runtime + * data. If the method is called the first time the instance is created with the given + * options. + * + * @param options + * options to configure the instance + * @param data + * the runtime data to reuse + * @return global instance + */ + public static synchronized Agent getInstance(final AgentOptions options, RuntimeData data) { if (singleton == null) { - final Agent agent = new Agent(options, IExceptionLogger.SYSTEM_ERR); + final Agent agent = new Agent(options, IExceptionLogger.SYSTEM_ERR, data); agent.startup(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override @@ -58,18 +76,24 @@ public class Agent implements IAgent { } return singleton; } + // END android-change + // BEGIN android-change /** - * Returns a global instance which is already started. If a agent has not - * been initialized before this method will fail. + * Returns a global instance which is already started. If an agent has not + * been initialized then one will be created via {@link Offline#createAgent()}. * * @return global instance * @throws IllegalStateException * if no Agent has been started yet */ + // END android-change public static synchronized Agent getInstance() throws IllegalStateException { if (singleton == null) { - throw new IllegalStateException("JaCoCo agent not started."); + // BEGIN android-change + // throw new IllegalStateException("JaCoCo agent not started."); + singleton = Offline.createAgent(); + // END android-change } return singleton; } @@ -93,10 +117,28 @@ public class Agent implements IAgent { * logger used by this agent */ Agent(final AgentOptions options, final IExceptionLogger logger) { + // BEGIN android-change + this(options, logger, new RuntimeData()); + // END android-change + } + + // BEGIN android-change + /** + * Creates a new agent with the given agent options, reusing the given runtime data. + * + * @param options + * agent options + * @param logger + * logger used by this agent + * @param data + * the runtime data to reuse + */ + private Agent(final AgentOptions options, final IExceptionLogger logger, RuntimeData data) { this.options = options; this.logger = logger; - this.data = new RuntimeData(); + this.data = data; } + // END android-change /** * Returns the runtime data object created by this agent diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java index 8b8b40c0..21a78bbd 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/Offline.java @@ -13,6 +13,7 @@ package org.jacoco.agent.rt.internal; import java.util.Properties; +import org.jacoco.core.data.ExecutionDataStore; import org.jacoco.core.runtime.AgentOptions; import org.jacoco.core.runtime.RuntimeData; @@ -22,13 +23,19 @@ import org.jacoco.core.runtime.RuntimeData; */ public final class Offline { - private static final RuntimeData DATA; + // BEGIN android-change + // private static final RuntimeData DATA; + private static final ExecutionDataStore DATA; + // END android-change private static final String CONFIG_RESOURCE = "/jacoco-agent.properties"; static { - final Properties config = ConfigLoader.load(CONFIG_RESOURCE, - System.getProperties()); - DATA = Agent.getInstance(new AgentOptions(config)).getData(); + // BEGIN android-change + // final Properties config = ConfigLoader.load(CONFIG_RESOURCE, + // System.getProperties()); + // DATA = Agent.getInstance(new AgentOptions(config)).getData(); + DATA = new ExecutionDataStore(); + // END android-change } private Offline() { @@ -48,8 +55,27 @@ public final class Offline { */ public static boolean[] getProbes(final long classid, final String classname, final int probecount) { - return DATA.getExecutionData(Long.valueOf(classid), classname, - probecount).getProbes(); + // BEGIN android-change + // return DATA.getExecutionData(Long.valueOf(classid), classname, + // probecount).getProbes(); + synchronized (DATA) { + return DATA.get(classid, classname, probecount).getProbes(); + } + // END android-change } + // BEGIN android-change + /** + * Creates a default agent, using config loaded from the classpath resource and the system + * properties, and a runtime data instance populated with the execution data accumulated by + * the probes. + * + * @return the new agent + */ + static Agent createAgent() { + final Properties config = ConfigLoader.load(CONFIG_RESOURCE, + System.getProperties()); + return Agent.getInstance(new AgentOptions(config), new RuntimeData(DATA)); + } + // END android-change } diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java b/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java index ff249e73..74a51dcb 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java @@ -37,10 +37,24 @@ public class RuntimeData { * Creates a new runtime. */ public RuntimeData() { - store = new ExecutionDataStore(); + // BEGIN android-change + this(new ExecutionDataStore()); + // END android-change + } + + // BEGIN android-change + /** + * Creates a new runtime, reusing an existing {@link ExecutionDataStore}. + * + * @param store + * the store to reuse + */ + public RuntimeData(ExecutionDataStore store) { + this.store = store; sessionId = "<none>"; startTimeStamp = System.currentTimeMillis(); } + // END android-change /** * Sets a session identifier for this runtime. The identifier is used when |