From 4a5057cb2f82c284e9c3f8357ff3370a1cb39627 Mon Sep 17 00:00:00 2001 From: redestad Date: Fri, 16 Jan 2015 12:41:36 +0100 Subject: [PATCH] 8068736: Avoid synchronization on Executable/Field.declaredAnnotations Reviewed-by: jfranck, psandoz --- .../classes/java/lang/reflect/Executable.java | 35 +++++++++++-------- .../classes/java/lang/reflect/Field.java | 33 ++++++++++------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/share/classes/java/lang/reflect/Executable.java b/src/share/classes/java/lang/reflect/Executable.java index 3e82d992e..43101fbb3 100644 --- a/src/share/classes/java/lang/reflect/Executable.java +++ b/src/share/classes/java/lang/reflect/Executable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -588,22 +588,29 @@ public abstract class Executable extends AccessibleObject return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Executable root = getRoot(); - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - getAnnotationBytes(), - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Executable root = getRoot(); + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + getAnnotationBytes(), + sun.misc.SharedSecrets.getJavaLangAccess(). + getConstantPool(getDeclaringClass()), + getDeclaringClass() + ); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } /** diff --git a/src/share/classes/java/lang/reflect/Field.java b/src/share/classes/java/lang/reflect/Field.java index bb23b22dc..cb3cbf5e7 100644 --- a/src/share/classes/java/lang/reflect/Field.java +++ b/src/share/classes/java/lang/reflect/Field.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1139,21 +1139,28 @@ class Field extends AccessibleObject implements Member { return AnnotationParser.toArray(declaredAnnotations()); } - private transient Map, Annotation> declaredAnnotations; + private transient volatile Map, Annotation> declaredAnnotations; - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - Field root = this.root; - if (root != null) { - declaredAnnotations = root.declaredAnnotations(); - } else { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, - sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), - getDeclaringClass()); + private Map, Annotation> declaredAnnotations() { + Map, Annotation> declAnnos; + if ((declAnnos = declaredAnnotations) == null) { + synchronized (this) { + if ((declAnnos = declaredAnnotations) == null) { + Field root = this.root; + if (root != null) { + declAnnos = root.declaredAnnotations(); + } else { + declAnnos = AnnotationParser.parseAnnotations( + annotations, + sun.misc.SharedSecrets.getJavaLangAccess() + .getConstantPool(getDeclaringClass()), + getDeclaringClass()); + } + declaredAnnotations = declAnnos; + } } } - return declaredAnnotations; + return declAnnos; } private native byte[] getTypeAnnotationBytes0(); -- GitLab