< 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 java.lang.classfile.AnnotationValue;
 38 import java.lang.classfile.ClassBuilder;
 39 import java.lang.classfile.ClassFile;
 40 import java.lang.classfile.Label;
 41 import java.lang.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<java.lang.classfile.Annotation> annotations = new ArrayList<>();
115         for (jdk.jfr.AnnotationElement a : annotationElements) {
116             List<java.lang.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 = java.lang.classfile.AnnotationElement.of(v.getName(), av);
123                 list.add(ae);
124             }
125             ClassDesc cd = ClassDesc.of(a.getTypeName());
126             annotations.add(java.lang.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 java.lang.classfile.AnnotationValue;
 38 import java.lang.classfile.ClassBuilder;
 39 import java.lang.classfile.ClassFile;
 40 import java.lang.classfile.Label;
 41 import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
 42 
 43 import jdk.internal.misc.PreviewFeatures;
 44 
 45 import jdk.jfr.AnnotationElement;
 46 import jdk.jfr.Event;
 47 import jdk.jfr.ValueDescriptor;
 48 import jdk.jfr.internal.util.Bytecode;
 49 import jdk.jfr.internal.util.Bytecode.MethodDesc;
 50 
 51 // Helper class for building dynamic events
 52 public final class EventClassBuilder {
 53     private static final ClassDesc TYPE_EVENT = Bytecode.classDesc(Event.class);
 54     private static final ClassDesc TYPE_IOBE = Bytecode.classDesc(IndexOutOfBoundsException.class);
 55     private static final MethodDesc DEFAULT_CONSTRUCTOR = MethodDesc.of("<init>", "()V");
 56     private static final MethodDesc SET_METHOD = MethodDesc.of("set", "(ILjava/lang/Object;)V");
 57     private static final AtomicLong idCounter = new AtomicLong();
 58 
 59     private final String fullClassName;
 60     private final ClassDesc type;
 61     private final List<ValueDescriptor> fields;
 62     private final List<AnnotationElement> annotationElements;
 63 
 64     public EventClassBuilder(List<AnnotationElement> annotationElements, List<ValueDescriptor> fields) {

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