Bug 516617 - [JDK9]ClassPathManager$JImageEnry::find is too slow
Summary: [JDK9]ClassPathManager$JImageEnry::find is too slow
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-13 15:31 EDT by Cleber Muramoto CLA
Modified: 2017-08-06 08:24 EDT (History)
1 user (show)

See Also:


Attachments
Caching lookups for jfs-rt resources (19.72 KB, text/x-java)
2017-05-13 15:31 EDT, Cleber Muramoto CLA
no flags Details
More Polished Version. (21.82 KB, text/x-java)
2017-05-15 11:13 EDT, Cleber Muramoto CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Cleber Muramoto CLA 2017-05-13 15:31:04 EDT
Created attachment 268326 [details]
Caching lookups for jfs-rt resources

When compiling a maven root project (~90 modules) with JDK8 and aspectj-maven-plugin, it takes less than 3 minutes.

However, when using aspectj 1.9.0.BETA-5 the same operation takes over 22 minutes.

The culprit is org.aspectj.weaver.bcel.ClassPathManager.JImageEnry::find.

I changed the code in order to speed up this lookup by creating an 'index' file in user.home. 

The index takes less than 3 seconds to build and less than 1 sec to load. 

In order to not use a lot of memory, the index keeps only the mappings name->position on heap and the actual class file contents in a MemoryMapped Byte buffer (about 160MB). The impl can easily be adapted to use a RandomAccessFile instead.

By employing this index, compilation time with JDK 9 dropped to ~2min:30s.
Comment 1 Cleber Muramoto CLA 2017-05-15 11:13:00 EDT
Created attachment 268342 [details]
More Polished Version.

Attaching a more polished version that is 100% based on a file index, which takes < 2ms to load.

Lookup strategy can be selected by passing the

-Dorg.aspectj.weaver.bcel.ClassPathManager.JIMAGE_CACHE_STRATEGY=<?>

during build. Possible values for <?> are:

0-Don't use cache
1-Use cache and memory map the file (Default)
2-Use cache and FileChannel

Performance for both 1 and 2 is quite similar on Linux.

The implementation relies on the new JDK 9's java.util.Arrays.compare(byte[], int, int, byte[], int, int), which is vectorized/intrinsified, but can easily be backported.

The index file will be created as a hidden file on user home, named

.aj.cache.<java.vm.specification.vendor>.<java.runtime.version>

e.g.,

.aj.cache.Oracle_Corporation.9_ea_165
Comment 2 Mario Ivankovits CLA 2017-08-06 08:24:31 EDT
I've created a version which just creates an in-memory-toc of all pathes of the module content. Bytes of classes are still read on demand.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=520597

This already brought up performance back for me.