< prev index next >

src/jdk.jfr/share/classes/jdk/jfr/internal/EventClassBuilder.java

Print this page

  1 /*
  2  * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.jfr.internal;
 27 
 28 import static jdk.jfr.internal.util.Bytecode.invokespecial;
 29 
 30 import java.lang.constant.ClassDesc;
 31 import java.lang.constant.ConstantDescs;
 32 import java.lang.reflect.AccessFlag;
 33 import java.util.ArrayList;
 34 import java.util.List;
 35 import java.util.concurrent.atomic.AtomicLong;
 36 
 37 import jdk.internal.classfile.AnnotationValue;
 38 import jdk.internal.classfile.ClassBuilder;
 39 import jdk.internal.classfile.Classfile;
 40 import jdk.internal.classfile.Label;
 41 import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute;

 42 import jdk.jfr.AnnotationElement;
 43 import jdk.jfr.Event;
 44 import jdk.jfr.ValueDescriptor;
 45 import jdk.jfr.internal.util.Bytecode;
 46 import jdk.jfr.internal.util.Bytecode.MethodDesc;
 47 
 48 // Helper class for building dynamic events
 49 public final class EventClassBuilder {
 50     private static final ClassDesc TYPE_EVENT = Bytecode.classDesc(Event.class);
 51     private static final ClassDesc TYPE_IOBE = Bytecode.classDesc(IndexOutOfBoundsException.class);
 52     private static final MethodDesc DEFAULT_CONSTRUCTOR = MethodDesc.of("<init>", "()V");
 53     private static final MethodDesc SET_METHOD = MethodDesc.of("set", "(ILjava/lang/Object;)V");
 54     private static final AtomicLong idCounter = new AtomicLong();
 55 
 56     private final String fullClassName;
 57     private final ClassDesc type;
 58     private final List<ValueDescriptor> fields;
 59     private final List<AnnotationElement> annotationElements;
 60 
 61     public EventClassBuilder(List<AnnotationElement> annotationElements, List<ValueDescriptor> fields) {

 93                 Bytecode.unbox(codeBuilder, cd);
 94                 codeBuilder.putfield(type, v.getName(), cd);
 95                 codeBuilder.return_();
 96                 codeBuilder.labelBinding(notEqual);
 97                 index++;
 98             }
 99             Bytecode.throwException(codeBuilder, TYPE_IOBE, "Index must between 0 and " + fields.size());
100         }));
101     }
102 
103     private void buildConstructor(ClassBuilder builder) {
104         builder.withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, methodBuilder -> methodBuilder.withCode(codeBuilder -> {
105             codeBuilder.aload(0);
106             invokespecial(codeBuilder, TYPE_EVENT, DEFAULT_CONSTRUCTOR);
107             codeBuilder.return_();
108         }));
109     }
110 
111     private void buildClassInfo(ClassBuilder builder) {
112         builder.withSuperclass(Bytecode.classDesc(Event.class));
113         builder.withFlags(AccessFlag.FINAL, AccessFlag.PUBLIC, AccessFlag.SUPER);
114         List<jdk.internal.classfile.Annotation> annotations = new ArrayList<>();
115         for (jdk.jfr.AnnotationElement a : annotationElements) {
116             List<jdk.internal.classfile.AnnotationElement> list = new ArrayList<>();
117             for (ValueDescriptor v : a.getValueDescriptors()) {
118                 // ValueDescriptor can only hold primitive
119                 // No need to care about classes/enums
120                 var value = a.getValue(v.getName());
121                 var av = AnnotationValue.of(value);
122                 var ae = jdk.internal.classfile.AnnotationElement.of(v.getName(), av);
123                 list.add(ae);
124             }
125             ClassDesc cd = ClassDesc.of(a.getTypeName());
126             annotations.add(jdk.internal.classfile.Annotation.of(cd, list));
127         }
128         builder.with(RuntimeVisibleAnnotationsAttribute.of(annotations));
129     }
130 
131     private void buildFields(ClassBuilder builder) {
132         for (ValueDescriptor v : fields) {
133             builder.withField(v.getName(), Bytecode.classDesc(v), Classfile.ACC_PRIVATE);

  1 /*
  2  * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.jfr.internal;
 27 
 28 import static jdk.jfr.internal.util.Bytecode.invokespecial;
 29 
 30 import java.lang.constant.ClassDesc;
 31 import java.lang.constant.ConstantDescs;
 32 import java.lang.reflect.AccessFlag;
 33 import java.util.ArrayList;
 34 import java.util.List;
 35 import java.util.concurrent.atomic.AtomicLong;
 36 
 37 import jdk.internal.classfile.AnnotationValue;
 38 import jdk.internal.classfile.ClassBuilder;
 39 import jdk.internal.classfile.Classfile;
 40 import jdk.internal.classfile.Label;
 41 import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
 42 import jdk.internal.misc.PreviewFeatures;
 43 import jdk.jfr.AnnotationElement;
 44 import jdk.jfr.Event;
 45 import jdk.jfr.ValueDescriptor;
 46 import jdk.jfr.internal.util.Bytecode;
 47 import jdk.jfr.internal.util.Bytecode.MethodDesc;
 48 
 49 // Helper class for building dynamic events
 50 public final class EventClassBuilder {
 51     private static final ClassDesc TYPE_EVENT = Bytecode.classDesc(Event.class);
 52     private static final ClassDesc TYPE_IOBE = Bytecode.classDesc(IndexOutOfBoundsException.class);
 53     private static final MethodDesc DEFAULT_CONSTRUCTOR = MethodDesc.of("<init>", "()V");
 54     private static final MethodDesc SET_METHOD = MethodDesc.of("set", "(ILjava/lang/Object;)V");
 55     private static final AtomicLong idCounter = new AtomicLong();
 56 
 57     private final String fullClassName;
 58     private final ClassDesc type;
 59     private final List<ValueDescriptor> fields;
 60     private final List<AnnotationElement> annotationElements;
 61 
 62     public EventClassBuilder(List<AnnotationElement> annotationElements, List<ValueDescriptor> fields) {

 94                 Bytecode.unbox(codeBuilder, cd);
 95                 codeBuilder.putfield(type, v.getName(), cd);
 96                 codeBuilder.return_();
 97                 codeBuilder.labelBinding(notEqual);
 98                 index++;
 99             }
100             Bytecode.throwException(codeBuilder, TYPE_IOBE, "Index must between 0 and " + fields.size());
101         }));
102     }
103 
104     private void buildConstructor(ClassBuilder builder) {
105         builder.withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, methodBuilder -> methodBuilder.withCode(codeBuilder -> {
106             codeBuilder.aload(0);
107             invokespecial(codeBuilder, TYPE_EVENT, DEFAULT_CONSTRUCTOR);
108             codeBuilder.return_();
109         }));
110     }
111 
112     private void buildClassInfo(ClassBuilder builder) {
113         builder.withSuperclass(Bytecode.classDesc(Event.class));
114         builder.withFlags(AccessFlag.FINAL, AccessFlag.PUBLIC, (PreviewFeatures.isEnabled() ? AccessFlag.IDENTITY : AccessFlag.SUPER));
115         List<jdk.internal.classfile.Annotation> annotations = new ArrayList<>();
116         for (jdk.jfr.AnnotationElement a : annotationElements) {
117             List<jdk.internal.classfile.AnnotationElement> list = new ArrayList<>();
118             for (ValueDescriptor v : a.getValueDescriptors()) {
119                 // ValueDescriptor can only hold primitive
120                 // No need to care about classes/enums
121                 var value = a.getValue(v.getName());
122                 var av = AnnotationValue.of(value);
123                 var ae = jdk.internal.classfile.AnnotationElement.of(v.getName(), av);
124                 list.add(ae);
125             }
126             ClassDesc cd = ClassDesc.of(a.getTypeName());
127             annotations.add(jdk.internal.classfile.Annotation.of(cd, list));
128         }
129         builder.with(RuntimeVisibleAnnotationsAttribute.of(annotations));
130     }
131 
132     private void buildFields(ClassBuilder builder) {
133         for (ValueDescriptor v : fields) {
134             builder.withField(v.getName(), Bytecode.classDesc(v), Classfile.ACC_PRIVATE);
< prev index next >