Clone Tools
  • last updated a few seconds ago
Constraints
Constraints: committers
 
Constraints: files
Constraints: dates
Add initial support component metadata supplier caching

This commit adds the infrastructure for caching of component metadata rules.

For now, the only kind of rule we can cache are the component metadata supplier

rules, which are used during dynamic version selection, but the executor

infrastructure can be reused to cache more kinds of rules.

The implementation relies on the principal that a "rule" can be safely cached if:

- the rule has no side effect, and uses the "class-based pattern"

- the implementation of the rule didn't change

- the inputs of the rule didn't change

For this, we introduce a new persistent cache (hence cross-build) with an in-memory

facing cache, that allows us to avoid the execution of a rule if the result is

already in the cache. The implementation makes use of _snapshotting_ to capture the

state of the inputs of a rule, which consists of the implementation of the rule and

its potential parameters. It's worth noting that at this stage we do not consider

the services the rule can use, it's going to be done in a subsequent commit.

This worked required a clarification of what an rule cares about (the result) in

opposition to what the user is faced with. For example, a component metadata supplier

rule output is a `ComponentMetadata`, but what we offer to the user, to build that

metadata, is a `ComponentMetadataSupplierDetails` instance. Similarly, component

metadata rules would have different kind of output and what the user manipulates.

The cache works with a primary key (for the first implemented cache, the key is the

module version identifier) and will invalidate the results based on the cache policy

(should refresh modules).

The persistent cache uses the snapshot as the key in the store. In theory, should we

consider that we have a nearly perfect hash function, we could instead use the hash

of the snapshot as the key. Measurements would have to be made to check if it's worth

implementing.

  1. … 46 more files in changeset.
Extract common InstantiatingAction type

    • -0
    • +47
    ./InstantiatingAction.java
  1. … 2 more files in changeset.
Extract common InstantiatingAction type

    • -0
    • +47
    ./InstantiatingAction.java
  1. … 2 more files in changeset.
Fix convention mapping class loader leak

The reflection cache keeps a set of property names for each class.

This set was provided by calling keySet() on a map which contains

class values. The keyset would thus keep a strong reference back

to its map and all of its values, leading to a classloader leak.

We now do a defensive copy of they keyset to avoid surprises for

callers of this method.

  1. … 1 more file in changeset.
Fix convention mapping class loader leak

The reflection cache keeps a set of property names for each class.

This set was provided by calling keySet() on a map which contains

class values. The keyset would thus keep a strong reference back

to its map and all of its values, leading to a classloader leak.

We now do a defensive copy of they keyset to avoid surprises for

callers of this method.

  1. … 1 more file in changeset.
Consistent ordering of `public` and `abstract` modifiers

  1. … 10 more files in changeset.
Replace usages of org.gradle.api.Nullable

With javax.annotation.Nullable.

  1. … 460 more files in changeset.
Javadoc.

Fix setter selection in presence of multiple setters (#2386)

  1. … 5 more files in changeset.
Removed some indirection.

  1. … 2 more files in changeset.
Moved ObjectInstantiationException to public API

This avoids leaking an internal exception type through the

ObjectFactory.newInstance API.

    • -29
    • +0
    ./ObjectInstantiationException.java
  1. … 24 more files in changeset.
Fixed handling for setters that return non-void types.

  1. … 2 more files in changeset.
Reused the property detection logic that is used for object decoration and task annotation handling also for determining whether a convention mapping can be applied to a decorated object.

The logic is shared but the actual work isn't shared, so this inspection can happen several times per decorated type (but no more than once per build).

  1. … 3 more files in changeset.
Use the same logic to decide whether a method is a property getter or not when decorating a task and when processing the annotations attached to the task's properties, so that this behaviour is consistent.

  1. … 3 more files in changeset.
Remove guava from worker process path

  1. … 15 more files in changeset.
Replaced all direct usages of `DependencyInjectingInstantiator` with a global `InstantiatorFactory` service.

  1. … 15 more files in changeset.
Use a consistent chain of exceptions on failure to create an instance of the action implementation, for worker actions, artifact transforms, attribute compatibility rules, attribute disambiguation rules and metadata supplier rules.

  1. … 7 more files in changeset.
Replace `TypeToken<T>` by `ModelType<T>` in `TypeOf<T>`

And introduce `TypeOf.Visitor`.

  1. … 6 more files in changeset.
Add coverage for Types.getGenericSimpleName(Type)

And fix basic wildcard type case, e.g. List<?>

  1. … 1 more file in changeset.
Allow extension public types to be specified via “type token”

and by being so, faithfully represent generic types.

  1. … 9 more files in changeset.
Avoid usage of `EqualsBuilder`

Calling `getGenericParameterTypes` is very expensive, and usage of `EqualsBuilder` implies calling the methods

even if they shouldn't be. This reworks the algorithm to avoid use of equals builder, and also changes the

generated hash code to use parameter types instead of generic parameter types.

This shaves a few ms for cold daemon startup (first use case, or `--no-daemon`).

Remove logging as it doesn't bring much value and log4j is not always available

There was an error in `buildSrc` compilation for some performance tests due to missing log4j dependency.

Signed-off-by: Cedric Champeau <cedric@gradle.com>

Avoid the creation of a `Factory<T>` for each call to `get`

Rework the reflection cache

The reflection cache is now safer, because we use a hierarchical cache where

the node entries are weakly referenced `Class` instances. Typically the first

level of the cache would be the receiver, while lower levels would be the

argument types. If those types are collected, the weak hash maps that we use

internally would automatically clean the entries. Eventually, the value associated

with this "path" of `Class` itself references a `Method` or a `Constructor`

with additional, computed, data.

The advantage of this approach is that typically for the instantiator case,

we no longer need to match the argument types (`isMatch`) for each call: instead,

we go through the tree using subsequent argument types, and if a match is found,

we know it's the right one.

  1. … 4 more files in changeset.
Attempt to implement faster `stat` using JDK 7 attributes

  1. … 6 more files in changeset.
Reuse the same infrastructure for cached constructors and cached methods

  1. … 2 more files in changeset.
Fix GC possibly collecting cached entries when using only weak references: values need to be validated

  1. … 1 more file in changeset.
Do not wrap values in `WeakReference`

It's not the cache which should wrap values into weak references, but the value itself that should

do whatever is necessary to avoid the `Class` from being un-collectable.

Small optimization : wrapped types need not be wrapped into weak references since they will never be collected

Fix unit test

  1. … 1 more file in changeset.