Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Excessive locking in TypeCachingBytecodeGenerator#BOOTSTRAP_LOCK #3035

Closed
5 tasks done
aswath80 opened this issue Jun 10, 2023 · 1 comment · Fixed by #3095
Closed
5 tasks done

Excessive locking in TypeCachingBytecodeGenerator#BOOTSTRAP_LOCK #3035

aswath80 opened this issue Jun 10, 2023 · 1 comment · Fixed by #3095
Assignees

Comments

@aswath80
Copy link

aswath80 commented Jun 10, 2023

The TypeCachingBytecodeGenerator#BOOTSTRAP_LOCK is resulting in excessive BLOCKED threads when running several thousand tests concurrently. Byte-buddy TypeCache's findOrInsert without monitor seems to handle concurrency. Is this global lock needed ?

Mockito-Inline 4.10, Byte-Buddy 1.12.19

"ForkJoinPool-1-worker-84" Id=115 RUNNABLE (daemon=TRUE) at java.base@17.0.4/java.lang.StringLatin1.replace(StringLatin1.java:322) at java.base@17.0.4/java.lang.String.replace(String.java:2806) at app//net.bytebuddy.jar.asm.Type.getInternalName(Type.java:510) at app//net.bytebuddy.jar.asm.Type.appendDescriptor(Type.java:644) at app//net.bytebuddy.jar.asm.Type.getMethodDescriptor(Type.java:585) at app//net.bytebuddy.description.method.MethodDescription$ForLoadedMethod.getDescriptor(MethodDescription.java:1288) at app//net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.visitMethod(Advice.java:8400) at app//net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1353) at app//net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:744) at app//net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:424) at app//net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.apply(Advice.java:8394) at app//net.bytebuddy.asm.Advice$AdviceVisitor$WithExitAdvice.onUserEnd(Advice.java:10904) at app//net.bytebuddy.asm.Advice$AdviceVisitor.visitMaxs(Advice.java:10683) at app//net.bytebuddy.jar.asm.ClassReader.readCode(ClassReader.java:2665) at app//net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1514) at app//net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:744) at app//net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:424) at app//net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:4014) at app//net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2224) at app//net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$UsingTypeWriter.make(DynamicType.java:4050) at app//net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3734) at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.transform(InlineBytecodeGenerator.java:401) at java.instrument@17.0.4/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:244) at java.instrument@17.0.4/sun.instrument.TransformerManager.transform(TransformerManager.java:188) at java.instrument@17.0.4/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:541) at java.instrument@17.0.4/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method) at java.instrument@17.0.4/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:169) at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:280) at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:217) - locked <0x730e33e8> (a org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator) at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.lambda$mockClass$0(TypeCachingBytecodeGenerator.java:47) at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$$Lambda$895/0x0000000801aeaf98.call(Unknown Source) at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168) at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399) at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190) - locked <0x62f72614> (a java.lang.Object) at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)

"ForkJoinPool-1-worker-51" Id=82 BLOCKED on java.lang.Object@62f72614 owned by "ForkJoinPool-1-worker-84" Id=115115 (daemon=TRUE) at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:189) at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410) at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:40) at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:396) at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:355) at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334) at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56) at app//org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)

check that

  • The mockito message in the stacktrace have useful information, but it didn't help
  • The problematic code (if that's possible) is copied here;
    Note that some configuration are impossible to mock via Mockito
  • Provide versions (mockito / jdk / os / any other relevant information)
  • Provide a Short, Self Contained, Correct (Compilable), Example of the issue
    (same as any question on stackoverflow.com)
  • Read the contributing guide
AndreasTu added a commit to AndreasTu/mockito that referenced this issue Aug 17, 2023
Changed locking scheme in TypeCachingBytecodeGenerator from a
single global lock to mockType class lock.
But the mockType class lock will still ensure that a MockitoMockKey
will never be created twice.

Fixes mockito#3035
@AndreasTu
Copy link
Contributor

AndreasTu commented Aug 17, 2023

I have opened the PR #3095, which would ease this issue, by changing the locking scheme in TypeCachingBytecodeGenerator from a single global lock to cacheLocks with size 16.
The used TypeCachingLock from cacheLocks depends on the hashcode of MockitoMockKey, which aggregates the types and
settings to mock.

So this will spread the Locks over 16 instances, assuming that the hashcodes of the class to mock are more or less evenly distributed.

AndreasTu added a commit to AndreasTu/mockito that referenced this issue Aug 19, 2023
Changed locking scheme in TypeCachingBytecodeGenerator from a
single global lock to cacheLocks with size 16.
The used TypeCachingLock from cacheLocks depends on
the hashcode of MockitoMockKey, which aggregates the types and
settings to mock.

Fixes mockito#3035
AndreasTu added a commit to AndreasTu/mockito that referenced this issue Aug 19, 2023
Changed locking scheme in TypeCachingBytecodeGenerator from a
single global lock to cacheLocks with size 16.
The used TypeCachingLock from cacheLocks depends on
the hashcode of MockitoMockKey, which aggregates the types and
settings to mock.

Fixes mockito#3035
AndreasTu added a commit to AndreasTu/mockito that referenced this issue Aug 19, 2023
Changed locking scheme in TypeCachingBytecodeGenerator from a
single global lock to cacheLocks with size 16.
The used TypeCachingLock from cacheLocks depends on
the hashcode of MockitoMockKey, which aggregates the types and
settings to mock.

Fixes mockito#3035
TimvdLippe pushed a commit that referenced this issue Aug 22, 2023
Changed locking scheme in TypeCachingBytecodeGenerator from a
single global lock to cacheLocks with size 16.
The used TypeCachingLock from cacheLocks depends on
the hashcode of MockitoMockKey, which aggregates the types and
settings to mock.

Fixes #3035
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants