1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  *
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * The contents of this file are subject to the terms of either the Universal Permissive License
   7  * v 1.0 as shown at http://oss.oracle.com/licenses/upl
   8  *
   9  * or the following license:
  10  *
  11  * Redistribution and use in source and binary forms, with or without modification, are permitted
  12  * provided that the following conditions are met:
  13  *
  14  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions
  15  * and the following disclaimer.
  16  *
  17  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
  18  * conditions and the following disclaimer in the documentation and/or other materials provided with
  19  * the distribution.
  20  *
  21  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
  22  * endorse or promote products derived from this software without specific prior written permission.
  23  *
  24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  26  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
  31  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32  */
  33 package org.openjdk.jmc.flightrecorder.jdk;
  34 
  35 import static org.openjdk.jmc.common.item.Attribute.attr;
  36 import static org.openjdk.jmc.common.unit.UnitLookup.ADDRESS;
  37 import static org.openjdk.jmc.common.unit.UnitLookup.CLASS;
  38 import static org.openjdk.jmc.common.unit.UnitLookup.CLASS_LOADER;
  39 import static org.openjdk.jmc.common.unit.UnitLookup.FLAG;
  40 import static org.openjdk.jmc.common.unit.UnitLookup.LABELED_IDENTIFIER;
  41 import static org.openjdk.jmc.common.unit.UnitLookup.MEMORY;
  42 import static org.openjdk.jmc.common.unit.UnitLookup.METHOD;
  43 import static org.openjdk.jmc.common.unit.UnitLookup.NUMBER;
  44 import static org.openjdk.jmc.common.unit.UnitLookup.OLD_OBJECT;
  45 import static org.openjdk.jmc.common.unit.UnitLookup.PERCENTAGE;
  46 import static org.openjdk.jmc.common.unit.UnitLookup.PLAIN_TEXT;
  47 import static org.openjdk.jmc.common.unit.UnitLookup.THREAD;
  48 import static org.openjdk.jmc.common.unit.UnitLookup.TIMESPAN;
  49 import static org.openjdk.jmc.common.unit.UnitLookup.TIMESTAMP;
  50 import static org.openjdk.jmc.common.unit.UnitLookup.UNKNOWN;
  51 
  52 import java.util.ArrayList;
  53 import java.util.List;
  54 
  55 import org.openjdk.jmc.common.IDisplayable;
  56 import org.openjdk.jmc.common.IMCClassLoader;
  57 import org.openjdk.jmc.common.IMCFrame;
  58 import org.openjdk.jmc.common.IMCMethod;
  59 import org.openjdk.jmc.common.IMCModule;
  60 import org.openjdk.jmc.common.IMCOldObject;
  61 import org.openjdk.jmc.common.IMCOldObjectGcRoot;
  62 import org.openjdk.jmc.common.IMCPackage;
  63 import org.openjdk.jmc.common.IMCStackTrace;
  64 import org.openjdk.jmc.common.IMCThread;
  65 import org.openjdk.jmc.common.IMCThreadGroup;
  66 import org.openjdk.jmc.common.IMCType;
  67 import org.openjdk.jmc.common.item.Attribute;
  68 import org.openjdk.jmc.common.item.IAttribute;
  69 import org.openjdk.jmc.common.item.IMemberAccessor;
  70 import org.openjdk.jmc.common.item.IType;
  71 import org.openjdk.jmc.common.unit.ContentType;
  72 import org.openjdk.jmc.common.unit.IQuantity;
  73 import org.openjdk.jmc.common.unit.UnitLookup;
  74 import org.openjdk.jmc.common.util.FormatToolkit;
  75 import org.openjdk.jmc.common.util.LabeledIdentifier;
  76 import org.openjdk.jmc.common.util.MCClassLoader;
  77 import org.openjdk.jmc.common.util.MemberAccessorToolkit;
  78 import org.openjdk.jmc.flightrecorder.JfrAttributes;
  79 import org.openjdk.jmc.flightrecorder.jdk.messages.internal.Messages;
  80 
  81 /**
  82  * Various attributes based on JDK flight recorder data.
  83  */
  84 public final class JdkAttributes {
  85 
  86         public static final IAttribute<String> EVENT_THREAD_NAME = Attribute
  87                         .canonicalize(new Attribute<String>("(thread).name", Messages.getString(Messages.ATTR_EVENT_THREAD_NAME), //$NON-NLS-1$
  88                                         Messages.getString(Messages.ATTR_EVENT_THREAD_NAME_DESC), PLAIN_TEXT) {
  89                                 @Override
  90                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
  91                                         final IMemberAccessor<IMCThread, U> accessor = JfrAttributes.EVENT_THREAD.getAccessor(type);
  92                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
  93                                                 @Override
  94                                                 public String getMember(U i) {
  95                                                         IMCThread thread = accessor.getMember(i);
  96                                                         return thread == null ? null : thread.getThreadName();
  97                                                 }
  98                                         };
  99                                 }
 100                         });
 101         public static final IAttribute<String> EVENT_THREAD_GROUP_NAME = Attribute.canonicalize(
 102                         new Attribute<String>("(thread).groupName", Messages.getString(Messages.ATTR_EVENT_THREAD_GROUP), //$NON-NLS-1$
 103                                         Messages.getString(Messages.ATTR_EVENT_THREAD_GROUP_DESC), PLAIN_TEXT) {
 104                                 @Override
 105                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 106                                         final IMemberAccessor<IMCThread, U> accessor = JfrAttributes.EVENT_THREAD.getAccessor(type);
 107                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 108                                                 @Override
 109                                                 public String getMember(U i) {
 110                                                         IMCThread thread = accessor.getMember(i);
 111                                                         if (thread != null) {
 112                                                                 IMCThreadGroup group = thread.getThreadGroup();
 113                                                                 if (group != null) {
 114                                                                         return group.getName();
 115                                                                 }
 116                                                         }
 117                                                         return null;
 118                                                 }
 119                                         };
 120                                 }
 121                         });
 122         public static final IAttribute<IQuantity> EVENT_THREAD_ID = Attribute.canonicalize(
 123                         new Attribute<IQuantity>("(thread).javaThreadId", Messages.getString(Messages.ATTR_EVENT_THREAD_ID), //$NON-NLS-1$
 124                                         Messages.getString(Messages.ATTR_EVENT_THREAD_ID_DESC), NUMBER) {
 125                                 @Override
 126                                 public <U> IMemberAccessor<IQuantity, U> customAccessor(IType<U> type) {
 127                                         final IMemberAccessor<IMCThread, U> accessor = JfrAttributes.EVENT_THREAD.getAccessor(type);
 128                                         return accessor == null ? null : new IMemberAccessor<IQuantity, U>() {
 129                                                 @Override
 130                                                 public IQuantity getMember(U i) {
 131                                                         IMCThread thread = accessor.getMember(i);
 132                                                         return (thread == null || thread.getThreadId() == null) ? null
 133                                                                         : UnitLookup.NUMBER_UNITY.quantity(thread.getThreadId());
 134                                                 }
 135                                         };
 136                                 }
 137                         });
 138 
 139         public static final IAttribute<String> STACK_TRACE_STRING = Attribute.canonicalize(
 140                         new Attribute<String>("(stackTrace).string", Messages.getString(Messages.ATTR_STACK_TRACE_STRING), //$NON-NLS-1$
 141                                         Messages.getString(Messages.ATTR_STACK_TRACE_STRING_DESC), UnitLookup.PLAIN_TEXT) {
 142                                 @Override
 143                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 144                                         final IMemberAccessor<IMCStackTrace, U> accessor = JfrAttributes.EVENT_STACKTRACE.getAccessor(type);
 145                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 146                                                 @Override
 147                                                 public String getMember(U i) {
 148                                                         IMCStackTrace trace = accessor.getMember(i);
 149                                                         // Using default formatting
 150                                                         return trace == null ? null : FormatToolkit.getHumanReadable(trace, "", "", null); //$NON-NLS-1$ //$NON-NLS-2$
 151                                                 }
 152                                         };
 153                                 }
 154                         });
 155 
 156         public static final IAttribute<IMCFrame> STACK_TRACE_TOP_FRAME = Attribute.canonicalize(
 157                         new Attribute<IMCFrame>("(stackTrace).topframe", Messages.getString(Messages.ATTR_STACK_TRACE_FRAME), //$NON-NLS-1$
 158                                         Messages.getString(Messages.ATTR_STACK_TRACE_FRAME_DESC), UnitLookup.STACKTRACE_FRAME) {
 159                                 @Override
 160                                 public <U> IMemberAccessor<IMCFrame, U> customAccessor(IType<U> type) {
 161                                         final IMemberAccessor<IMCStackTrace, U> accessor = JfrAttributes.EVENT_STACKTRACE.getAccessor(type);
 162                                         return accessor == null ? null : new IMemberAccessor<IMCFrame, U>() {
 163                                                 @Override
 164                                                 public IMCFrame getMember(U i) {
 165                                                         IMCStackTrace trace = accessor.getMember(i);
 166                                                         // FIXME: Fix train wreck to avoid NPEs and IndexOutOfBoundsException
 167                                                         return trace == null || trace.getFrames().isEmpty() ? null : trace.getFrames().get(0);
 168                                                 }
 169                                         };
 170                                 }
 171                         });
 172 
 173         public static final IAttribute<String> STACK_TRACE_TOP_PACKAGE = Attribute.canonicalize(
 174                         new Attribute<String>("(stackTrace).topPackage", Messages.getString(Messages.ATTR_STACK_TRACE_PACKAGE), //$NON-NLS-1$
 175                                         Messages.getString(Messages.ATTR_STACK_TRACE_PACKAGE_DESC), PLAIN_TEXT) {
 176                                 @Override
 177                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 178                                         final IMemberAccessor<IMCType, U> accessor = STACK_TRACE_TOP_CLASS.getAccessor(type);
 179                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 180                                                 @Override
 181                                                 public String getMember(U i) {
 182                                                         IMCType type = accessor.getMember(i);
 183                                                         return type == null ? null : FormatToolkit.getPackage(type.getPackage());
 184                                                 }
 185                                         };
 186                                 }
 187                         });
 188 
 189         public static final IAttribute<IMCType> STACK_TRACE_TOP_CLASS = Attribute.canonicalize(
 190                         new Attribute<IMCType>("(stackTrace).topClass", Messages.getString(Messages.ATTR_STACK_TRACE_CLASS), //$NON-NLS-1$
 191                                         Messages.getString(Messages.ATTR_STACK_TRACE_CLASS_DESC), CLASS) {
 192                                 @Override
 193                                 public <U> IMemberAccessor<IMCType, U> customAccessor(IType<U> type) {
 194                                         final IMemberAccessor<IMCMethod, U> accessor = STACK_TRACE_TOP_METHOD.getAccessor(type);
 195                                         return accessor == null ? null : new IMemberAccessor<IMCType, U>() {
 196                                                 @Override
 197                                                 public IMCType getMember(U i) {
 198                                                         IMCMethod method = accessor.getMember(i);
 199                                                         return method == null ? null : method.getType();
 200                                                 }
 201                                         };
 202                                 }
 203                         });
 204         public static final IAttribute<String> STACK_TRACE_TOP_CLASS_STRING = Attribute.canonicalize(
 205                         new Attribute<String>("(stackTrace).topClass.string", Messages.getString(Messages.ATTR_STACK_TRACE_CLASS), //$NON-NLS-1$
 206                                         Messages.getString(Messages.ATTR_STACK_TRACE_CLASS_DESC), PLAIN_TEXT) {
 207                                 @Override
 208                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 209                                         final IMemberAccessor<IMCType, U> accessor = STACK_TRACE_TOP_CLASS.getAccessor(type);
 210                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 211                                                 @Override
 212                                                 public String getMember(U i) {
 213                                                         IMCType type = accessor.getMember(i);
 214                                                         return type == null ? null : type.getFullName();
 215                                                 }
 216                                         };
 217                                 }
 218                         });
 219         public static final IAttribute<IMCMethod> STACK_TRACE_TOP_METHOD = Attribute.canonicalize(
 220                         new Attribute<IMCMethod>("(stackTrace).topMethod", Messages.getString(Messages.ATTR_STACK_TRACE_METHOD), //$NON-NLS-1$
 221                                         Messages.getString(Messages.ATTR_STACK_TRACE_METHOD_DESC), UnitLookup.METHOD) {
 222                                 @Override
 223                                 public <U> IMemberAccessor<IMCMethod, U> customAccessor(IType<U> type) {
 224                                         final IMemberAccessor<IMCFrame, U> accessor = STACK_TRACE_TOP_FRAME.getAccessor(type);
 225                                         return accessor == null ? null : new IMemberAccessor<IMCMethod, U>() {
 226                                                 @Override
 227                                                 public IMCMethod getMember(U i) {
 228                                                         IMCFrame frame = accessor.getMember(i);
 229                                                         return frame == null ? null : frame.getMethod();
 230                                                 }
 231                                         };
 232                                 }
 233                         });
 234         public static final IAttribute<String> STACK_TRACE_TOP_METHOD_STRING = Attribute.canonicalize(
 235                         new Attribute<String>("(stackTrace).topMethodString", Messages.getString(Messages.ATTR_STACK_TRACE_METHOD), //$NON-NLS-1$
 236                                         Messages.getString(Messages.ATTR_STACK_TRACE_METHOD_DESC), UnitLookup.PLAIN_TEXT) {
 237                                 @Override
 238                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 239                                         final IMemberAccessor<IMCMethod, U> accessor = STACK_TRACE_TOP_METHOD.getAccessor(type);
 240                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 241                                                 @Override
 242                                                 public String getMember(U i) {
 243                                                         IMCMethod method = accessor.getMember(i);
 244                                                         return method == null ? null : FormatToolkit.getHumanReadable(method);
 245                                                 }
 246                                         };
 247                                 }
 248                         });
 249 
 250         public static final IAttribute<IMCFrame> STACK_TRACE_BOTTOM_FRAME = Attribute
 251                         .canonicalize(new Attribute<IMCFrame>("(stackTrace).bottomFrame", //$NON-NLS-1$
 252                                         Messages.getString(Messages.ATTR_STACK_TRACE_BOTTOM_FRAME),
 253                                         Messages.getString(Messages.ATTR_STACK_TRACE_BOTTOM_FRAME_DESC), UnitLookup.STACKTRACE_FRAME) {
 254                                 @Override
 255                                 public <U> IMemberAccessor<IMCFrame, U> customAccessor(IType<U> type) {
 256                                         final IMemberAccessor<IMCStackTrace, U> accessor = JfrAttributes.EVENT_STACKTRACE.getAccessor(type);
 257                                         return accessor == null ? null : new IMemberAccessor<IMCFrame, U>() {
 258                                                 @Override
 259                                                 public IMCFrame getMember(U i) {
 260                                                         IMCStackTrace trace = accessor.getMember(i);
 261                                                         if (trace != null) {
 262                                                                 List<? extends IMCFrame> frames = trace.getFrames();
 263                                                                 return frames == null || frames.size() == 0 ? null : frames.get(frames.size() - 1);
 264                                                         }
 265                                                         return null;
 266                                                 }
 267                                         };
 268                                 }
 269                         });
 270 
 271         public static final IAttribute<IMCMethod> STACK_TRACE_BOTTOM_METHOD = Attribute
 272                         .canonicalize(new Attribute<IMCMethod>("(stackTrace).bottomMethod", //$NON-NLS-1$
 273                                         Messages.getString(Messages.ATTR_STACK_TRACE_BOTTOM_METHOD),
 274                                         Messages.getString(Messages.ATTR_STACK_TRACE_BOTTOM_METHOD_DESC), UnitLookup.METHOD) {
 275                                 @Override
 276                                 public <U> IMemberAccessor<IMCMethod, U> customAccessor(IType<U> type) {
 277                                         final IMemberAccessor<IMCFrame, U> accessor = STACK_TRACE_BOTTOM_FRAME.getAccessor(type);
 278                                         return accessor == null ? null : new IMemberAccessor<IMCMethod, U>() {
 279                                                 @Override
 280                                                 public IMCMethod getMember(U i) {
 281                                                         IMCFrame frame = accessor.getMember(i);
 282                                                         return frame == null ? null : frame.getMethod();
 283                                                 }
 284                                         };
 285                                 }
 286                         });
 287         public static final IAttribute<String> STACK_TRACE_BOTTOM_METHOD_STRING = Attribute
 288                         .canonicalize(new Attribute<String>("(stackTrace).bottomMethodString", //$NON-NLS-1$
 289                                         Messages.getString(Messages.ATTR_STACK_TRACE_BOTTOM_METHOD),
 290                                         Messages.getString(Messages.ATTR_STACK_TRACE_BOTTOM_METHOD_DESC), UnitLookup.PLAIN_TEXT) {
 291                                 @Override
 292                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 293                                         final IMemberAccessor<IMCMethod, U> accessor = STACK_TRACE_BOTTOM_METHOD.getAccessor(type);
 294                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 295                                                 @Override
 296                                                 public String getMember(U i) {
 297                                                         IMCMethod method = accessor.getMember(i);
 298                                                         return method == null ? null : FormatToolkit.getHumanReadable(method);
 299                                                 }
 300                                         };
 301                                 }
 302                         });
 303 
 304         public static final IAttribute<Boolean> STACK_TRACE_TRUNCATED = Attribute.canonicalize(
 305                         new Attribute<Boolean>("(stackTrace).truncationState", Messages.getString(Messages.ATTR_STACK_TRACE_DEPTH), //$NON-NLS-1$
 306                                         Messages.getString(Messages.ATTR_STACK_TRACE_DEPTH_DESC), FLAG) {
 307                                 @Override
 308                                 public <U> IMemberAccessor<Boolean, U> customAccessor(IType<U> type) {
 309                                         final IMemberAccessor<IMCStackTrace, U> accessor = JfrAttributes.EVENT_STACKTRACE.getAccessor(type);
 310                                         return accessor == null ? null : new IMemberAccessor<Boolean, U>() {
 311                                                 @Override
 312                                                 public Boolean getMember(U i) {
 313                                                         IMCStackTrace trace = accessor.getMember(i);
 314                                                         // FIXME: Fix train wreck to avoid NPEs and IndexOutOfBoundsException
 315                                                         return trace == null ? null : trace.getTruncationState().isTruncated();
 316                                                 }
 317                                         };
 318                                 }
 319                         });
 320 
 321         public static final IAttribute<String> PID = attr("pid", Messages.getString(Messages.ATTR_PID), PLAIN_TEXT); //$NON-NLS-1$
 322         public static final IAttribute<String> COMMAND_LINE = attr("commandLine", //$NON-NLS-1$
 323                         Messages.getString(Messages.ATTR_COMMAND_LINE), PLAIN_TEXT);
 324 
 325         public static final IAttribute<IQuantity> JVM_SYSTEM = attr("jvmSystem", //$NON-NLS-1$
 326                         Messages.getString(Messages.ATTR_JVM_SYSTEM), Messages.getString(Messages.ATTR_JVM_SYSTEM_DESC),
 327                         PERCENTAGE);
 328         public static final IAttribute<IQuantity> JVM_USER = attr("jvmUser", Messages.getString(Messages.ATTR_JVM_USER), //$NON-NLS-1$
 329                         Messages.getString(Messages.ATTR_JVM_USER_DESC), PERCENTAGE);
 330         public static final IAttribute<IQuantity> JVM_TOTAL = Attribute.canonicalize(new Attribute<IQuantity>("jvmTotal", //$NON-NLS-1$
 331                         Messages.getString(Messages.ATTR_JVM_TOTAL), Messages.getString(Messages.ATTR_JVM_TOTAL_DESC), PERCENTAGE) {
 332                 @Override
 333                 public <U> IMemberAccessor<IQuantity, U> customAccessor(IType<U> type) {
 334                         // Avoid possible future circularity by asking the type directly.
 335                         final IMemberAccessor<IQuantity, U> jvmUserAccessor = type.getAccessor(JVM_USER.getKey());
 336                         final IMemberAccessor<IQuantity, U> jvmSystemAccessor = type.getAccessor(JVM_SYSTEM.getKey());
 337                         if ((jvmUserAccessor == null) || (jvmSystemAccessor == null)) {
 338                                 return null;
 339                         }
 340                         return new IMemberAccessor<IQuantity, U>() {
 341                                 @Override
 342                                 public IQuantity getMember(U i) {
 343                                         IQuantity jvmUser = jvmUserAccessor.getMember(i);
 344                                         IQuantity jvmSystem = jvmSystemAccessor.getMember(i);
 345                                         return jvmUser != null && jvmSystem != null ? jvmUser.add(jvmSystem) : null;
 346                                 }
 347                         };
 348                 }
 349         });
 350         public static final IAttribute<IQuantity> MACHINE_TOTAL = attr("machineTotal", //$NON-NLS-1$
 351                         Messages.getString(Messages.ATTR_MACHINE_TOTAL), Messages.getString(Messages.ATTR_MACHINE_TOTAL_DESC),
 352                         PERCENTAGE);
 353         public static final IAttribute<IQuantity> OTHER_CPU = Attribute.canonicalize(new Attribute<IQuantity>("otherCpu", //$NON-NLS-1$
 354                         Messages.getString(Messages.ATTR_OTHER_CPU), Messages.getString(Messages.ATTR_OTHER_CPU_DESC), PERCENTAGE) {
 355                 @Override
 356                 public <U> IMemberAccessor<IQuantity, U> customAccessor(IType<U> type) {
 357                         final IMemberAccessor<IQuantity, U> jvmTotalAccessor = JVM_TOTAL.getAccessor(type);
 358                         // Avoid possible future circularity by asking the type directly.
 359                         final IMemberAccessor<IQuantity, U> machineTotalAccessor = type.getAccessor(MACHINE_TOTAL.getKey());
 360                         if ((jvmTotalAccessor == null) || (machineTotalAccessor == null)) {
 361                                 return null;
 362                         }
 363                         return new IMemberAccessor<IQuantity, U>() {
 364                                 @Override
 365                                 public IQuantity getMember(U i) {
 366                                         IQuantity jvmTotal = jvmTotalAccessor.getMember(i);
 367                                         IQuantity machineTotal = machineTotalAccessor.getMember(i);
 368                                         return jvmTotal != null && machineTotal != null ? machineTotal.subtract(jvmTotal) : null;
 369                                 }
 370                         };
 371                 }
 372         });
 373 
 374         public static final IAttribute<IQuantity> RECORDING_ID = attr("id", Messages.getString(Messages.ATTR_RECORDING_ID), //$NON-NLS-1$
 375                         NUMBER);
 376         public static final IAttribute<String> RECORDING_NAME = attr("name", //$NON-NLS-1$
 377                         Messages.getString(Messages.ATTR_RECORDING_NAME), PLAIN_TEXT);
 378         public static final IAttribute<IQuantity> RECORDING_START = attr("recordingStart", //$NON-NLS-1$
 379                         Messages.getString(Messages.ATTR_RECORDING_START), TIMESTAMP);
 380         public static final IAttribute<IQuantity> RECORDING_DURATION = attr("recordingDuration", //$NON-NLS-1$
 381                         Messages.getString(Messages.ATTR_RECORDING_DURATION), TIMESPAN);
 382         public static final IAttribute<IQuantity> RECORDING_MAX_SIZE = attr("maxSize", //$NON-NLS-1$
 383                         Messages.getString(Messages.ATTR_RECORDING_MAX_SIZE), MEMORY);
 384         public static final IAttribute<IQuantity> RECORDING_MAX_AGE = attr("maxAge", //$NON-NLS-1$
 385                         Messages.getString(Messages.ATTR_RECORDING_MAX_AGE), TIMESPAN);
 386         public static final IAttribute<String> RECORDING_DESTINATION = attr("destination", //$NON-NLS-1$
 387                         Messages.getString(Messages.ATTR_RECORDING_DESTINATION), PLAIN_TEXT);
 388 
 389         public static final IAttribute<LabeledIdentifier> REC_SETTING_FOR = attr("settingFor", //$NON-NLS-1$
 390                         Messages.getString(Messages.ATTR_REC_SETTING_FOR), LABELED_IDENTIFIER);
 391         public static final IAttribute<String> REC_SETTING_NAME = attr("name", //$NON-NLS-1$
 392                         Messages.getString(Messages.ATTR_REC_SETTING_NAME), PLAIN_TEXT);
 393         public static final IAttribute<String> REC_SETTING_VALUE = attr("value", //$NON-NLS-1$
 394                         Messages.getString(Messages.ATTR_REC_SETTING_VALUE), PLAIN_TEXT);
 395         public static final IAttribute<String> REC_SETTING_FOR_NAME = Attribute.canonicalize(new Attribute<String>(
 396                         "settingFor.string", Messages.getString(Messages.ATTR_REC_SETTING_FOR), null, PLAIN_TEXT) { //$NON-NLS-1$
 397                 @Override
 398                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 399                         final IMemberAccessor<LabeledIdentifier, U> accessor = REC_SETTING_FOR.getAccessor(type);
 400                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 401                                 @Override
 402                                 public String getMember(U i) {
 403                                         LabeledIdentifier identifier = accessor.getMember(i);
 404                                         return identifier == null ? null : identifier.getName();
 405                                 }
 406                         };
 407                 }
 408         });
 409         public static final IAttribute<String> REC_SETTING_FOR_ID = Attribute.canonicalize(new Attribute<String>(
 410                         "settingFor.id", Messages.getString(Messages.ATTR_REC_SETTING_FOR), null, PLAIN_TEXT) { //$NON-NLS-1$
 411                 @Override
 412                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 413                         final IMemberAccessor<LabeledIdentifier, U> accessor = REC_SETTING_FOR.getAccessor(type);
 414                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 415                                 @Override
 416                                 public String getMember(U i) {
 417                                         LabeledIdentifier identifier = accessor.getMember(i);
 418                                         return identifier == null ? null : identifier.getInterfaceId();
 419                                 }
 420                         };
 421                 }
 422         });
 423 
 424         public static final IAttribute<IMCPackage> EXPORTED_PACKAGE = attr("exportedPackage", //$NON-NLS-1$
 425                         Messages.getString(Messages.ATTR_EXPORTED_PACKAGE), UnitLookup.PACKAGE);
 426 
 427         public static final IAttribute<IMCModule> EXPORTING_MODULE = Attribute.canonicalize(new Attribute<IMCModule>(
 428                         "exportingModule", Messages.getString(Messages.ATTR_EXPORTING_MODULE), null, UnitLookup.MODULE) { //$NON-NLS-1$
 429                 @Override
 430                 public <U> IMemberAccessor<IMCModule, U> customAccessor(IType<U> type) {
 431                         final IMemberAccessor<IMCPackage, U> accessor = EXPORTED_PACKAGE.getAccessor(type);
 432                         return accessor == null ? null : new IMemberAccessor<IMCModule, U>() {
 433                                 @Override
 434                                 public IMCModule getMember(U i) {
 435                                         IMCPackage thePackage = accessor.getMember(i);
 436                                         return thePackage == null ? null : thePackage.getModule();
 437                                 }
 438                         };
 439                 }
 440         });
 441 
 442         public static final IAttribute<IQuantity> JVM_START_TIME = attr("jvmStartTime", //$NON-NLS-1$
 443                         Messages.getString(Messages.ATTR_JVM_START_TIME), TIMESTAMP);
 444         public static final IAttribute<String> JVM_NAME = attr("jvmName", Messages.getString(Messages.ATTR_JVM_NAME), //$NON-NLS-1$
 445                         PLAIN_TEXT);
 446         public static final IAttribute<IQuantity> JVM_PID = attr("pid", Messages.getString(Messages.ATTR_JVM_PID), //$NON-NLS-1$
 447                         NUMBER);
 448         public static final IAttribute<String> JVM_VERSION = attr("jvmVersion", //$NON-NLS-1$
 449                         Messages.getString(Messages.ATTR_JVM_VERSION), PLAIN_TEXT);
 450         public static final IAttribute<String> JVM_ARGUMENTS = attr("jvmArguments", //$NON-NLS-1$
 451                         Messages.getString(Messages.ATTR_JVM_ARGUMENTS), PLAIN_TEXT);
 452         public static final IAttribute<String> JAVA_ARGUMENTS = attr("javaArguments", //$NON-NLS-1$
 453                         Messages.getString(Messages.ATTR_JAVA_ARGUMENTS), PLAIN_TEXT);
 454 
 455         public static final IAttribute<String> IO_PATH = attr("path", Messages.getString(Messages.ATTR_IO_PATH), //$NON-NLS-1$
 456                         Messages.getString(Messages.ATTR_IO_PATH_DESC), PLAIN_TEXT);
 457         public static final IAttribute<IQuantity> IO_FILE_BYTES_READ = attr("bytesRead", //$NON-NLS-1$
 458                         Messages.getString(Messages.ATTR_IO_FILE_BYTES_READ),
 459                         Messages.getString(Messages.ATTR_IO_FILE_BYTES_READ_DESC), MEMORY);
 460         public static final IAttribute<Boolean> IO_FILE_READ_EOF = attr("endOfFile", //$NON-NLS-1$
 461                         Messages.getString(Messages.ATTR_IO_FILE_READ_EOF), Messages.getString(Messages.ATTR_IO_FILE_READ_EOF_DESC),
 462                         FLAG);
 463         public static final IAttribute<IQuantity> IO_FILE_BYTES_WRITTEN = attr("bytesWritten", //$NON-NLS-1$
 464                         Messages.getString(Messages.ATTR_IO_FILE_BYTES_WRITTEN),
 465                         Messages.getString(Messages.ATTR_IO_FILE_BYTES_WRITTEN_DESC), MEMORY);
 466         public static final IAttribute<IQuantity> IO_SOCKET_BYTES_READ = attr("bytesRead", //$NON-NLS-1$
 467                         Messages.getString(Messages.ATTR_IO_SOCKET_BYTES_READ),
 468                         Messages.getString(Messages.ATTR_IO_SOCKET_BYTES_READ_DESC), MEMORY);
 469         public static final IAttribute<Boolean> IO_SOCKET_READ_EOS = attr("endOfStream", //$NON-NLS-1$
 470                         Messages.getString(Messages.ATTR_IO_SOCKET_READ_EOS),
 471                         Messages.getString(Messages.ATTR_IO_SOCKET_READ_EOS_DESC), FLAG);
 472         public static final IAttribute<IQuantity> IO_SOCKET_BYTES_WRITTEN = attr("bytesWritten", //$NON-NLS-1$
 473                         Messages.getString(Messages.ATTR_IO_SOCKET_BYTES_WRITTEN),
 474                         Messages.getString(Messages.ATTR_IO_SOCKET_BYTES_WRITTEN_DESC), MEMORY);
 475         
 476         public static final IAttribute<IQuantity> IO_SIZE = Attribute.canonicalize(new Attribute<IQuantity>("size",  //#NON-NLS-1$
 477                         "Size", null, MEMORY) {
 478                 @Override
 479                 public <U> IMemberAccessor<IQuantity, U> customAccessor(IType<U> type){
 480                         List<IMemberAccessor<IQuantity, U>> accessorList = new ArrayList<>();
 481                         
 482                         accessorList.add(type.getAccessor(JdkAttributes.IO_SOCKET_BYTES_READ.getKey()));
 483                         accessorList.add(type.getAccessor(JdkAttributes.IO_SOCKET_BYTES_WRITTEN.getKey()));
 484                         accessorList.add(type.getAccessor(JdkAttributes.IO_FILE_BYTES_READ.getKey()));
 485                         accessorList.add(type.getAccessor(JdkAttributes.IO_FILE_BYTES_WRITTEN.getKey()));
 486 
 487                         for (IMemberAccessor<IQuantity, U> accessor : accessorList) {
 488                                 if(accessor != null) {
 489                                         return accessor;
 490                                 }
 491                         }
 492                         return MemberAccessorToolkit.constant(UnitLookup.BYTE.quantity(0));
 493                 }
 494         });
 495         public static final IAttribute<String> IO_ADDRESS = attr("address", Messages.getString(Messages.ATTR_IO_ADDRESS), //$NON-NLS-1$
 496                         PLAIN_TEXT);
 497         public static final IAttribute<String> IO_HOST = attr("host", Messages.getString(Messages.ATTR_IO_HOST), //$NON-NLS-1$
 498                         Messages.getString(Messages.ATTR_IO_HOST_DESC), PLAIN_TEXT);
 499         public static final IAttribute<IQuantity> IO_PORT = attr("port", Messages.getString(Messages.ATTR_IO_PORT), NUMBER); //$NON-NLS-1$
 500         public static final IAttribute<Object> IO_PORT_ON_ADDRESS = Attribute.canonicalize(new Attribute<Object>(
 501                         "portOnAddress", Messages.getString(Messages.ATTR_IO_PORT_ON_ADDRESS), null, UNKNOWN) { //$NON-NLS-1$
 502                 @Override
 503                 public <U> IMemberAccessor<Object, U> customAccessor(IType<U> type) {
 504                         class PortOnAddress implements IDisplayable {
 505 
 506                                 final String address;
 507                                 final IQuantity port;
 508 
 509                                 PortOnAddress(String address, IQuantity port) {
 510                                         this.address = address;
 511                                         this.port = port;
 512                                 }
 513 
 514                                 @Override
 515                                 public String displayUsing(String formatHint) {
 516                                         return address + " : " + port.displayUsing(formatHint); //$NON-NLS-1$
 517                                 }
 518 
 519                                 @Override
 520                                 public int hashCode() {
 521                                         return 31 * address.hashCode() + port.hashCode();
 522                                 };
 523 
 524                                 @Override
 525                                 public boolean equals(Object o) {
 526                                         return o instanceof PortOnAddress && ((PortOnAddress) o).address.equals(address)
 527                                                         && ((PortOnAddress) o).port.equals(port);
 528                                 };
 529 
 530                         }
 531                         // Avoid possible future circularity by asking the type directly.
 532                         final IMemberAccessor<String, U> addressAccessor = type.getAccessor(IO_ADDRESS.getKey());
 533                         final IMemberAccessor<IQuantity, U> portAccessor = type.getAccessor(IO_PORT.getKey());
 534                         if ((addressAccessor == null) || (portAccessor == null)) {
 535                                 return null;
 536                         }
 537                         return new IMemberAccessor<Object, U>() {
 538                                 @Override
 539                                 public IDisplayable getMember(U i) {
 540                                         String address = addressAccessor.getMember(i);
 541                                         IQuantity port = portAccessor.getMember(i);
 542                                         if (address != null && port != null) {
 543                                                 return new PortOnAddress(address, port);
 544                                         }
 545                                         return null;
 546                                 }
 547                         };
 548                 }
 549         });
 550 
 551         public static final IAttribute<IQuantity> IO_TIMEOUT = attr("timeout", Messages.getString(Messages.ATTR_IO_TIMEOUT), //$NON-NLS-1$
 552                         TIMESPAN);
 553 
 554         public static final IAttribute<IQuantity> TLAB_SIZE = attr("tlabSize", Messages.getString(Messages.ATTR_TLAB_SIZE), //$NON-NLS-1$
 555                         MEMORY);
 556         public static final IAttribute<IQuantity> ALLOCATION_SIZE = attr("allocationSize", //$NON-NLS-1$
 557                         Messages.getString(Messages.ATTR_ALLOCATION_SIZE), MEMORY);
 558         public static final IAttribute<IMCType> ALLOCATION_CLASS = attr("objectClass", //$NON-NLS-1$
 559                         Messages.getString(Messages.ATTR_ALLOCATION_CLASS), Messages.getString(Messages.ATTR_ALLOCATION_CLASS_DESC),
 560                         CLASS);
 561         public static final IAttribute<IMCType> OBJECT_CLASS = attr("objectClass", //$NON-NLS-1$
 562                         Messages.getString(Messages.ATTR_OBJECT_CLASS), CLASS);
 563         public static final IAttribute<String> OBJECT_CLASS_FULLNAME = Attribute.canonicalize(new Attribute<String>(
 564                         "objectClass.humanreadable", Messages.getString(Messages.ATTR_OBJECT_CLASS), null, PLAIN_TEXT) { //$NON-NLS-1$
 565                 @Override
 566                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 567                         final IMemberAccessor<IMCType, U> accessor = OBJECT_CLASS.getAccessor(type);
 568                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 569                                 @Override
 570                                 public String getMember(U i) {
 571                                         IMCType type = accessor.getMember(i);
 572                                         return type == null ? null : type.getFullName();
 573                                 }
 574                         };
 575                 }
 576         });
 577         public static final IAttribute<IQuantity> COUNT = attr("count", Messages.getString(Messages.ATTR_COUNT), NUMBER); //$NON-NLS-1$
 578 
 579         public static final IAttribute<IQuantity> HW_THREADS = attr("hwThreads", //$NON-NLS-1$
 580                         Messages.getString(Messages.ATTR_HW_THREADS), Messages.getString(Messages.ATTR_HW_THREADS_DESC), NUMBER);
 581 
 582         public static final IAttribute<IQuantity> PARALLEL_GC_THREADS = attr("parallelGCThreads", //$NON-NLS-1$
 583                         Messages.getString(Messages.ATTR_PARALLEL_GC_THREADS),
 584                         Messages.getString(Messages.ATTR_PARALLEL_GC_THREADS_DESC), NUMBER);
 585         public static final IAttribute<IQuantity> CONCURRENT_GC_THREADS = attr("concurrentGCThreads", //$NON-NLS-1$
 586                         Messages.getString(Messages.ATTR_CONCURRENT_GC_THREADS),
 587                         Messages.getString(Messages.ATTR_CONCURRENT_GC_THREADS_DESC), NUMBER);
 588         public static final IAttribute<String> YOUNG_COLLECTOR = attr("youngCollector", //$NON-NLS-1$
 589                         Messages.getString(Messages.ATTR_YOUNG_COLLECTOR), Messages.getString(Messages.ATTR_YOUNG_COLLECTOR_DESC),
 590                         PLAIN_TEXT);
 591         public static final IAttribute<String> OLD_COLLECTOR = attr("oldCollector", //$NON-NLS-1$
 592                         Messages.getString(Messages.ATTR_OLD_COLLECTOR), Messages.getString(Messages.ATTR_OLD_COLLECTOR_DESC),
 593                         PLAIN_TEXT);
 594         public static final IAttribute<Boolean> EXPLICIT_GC_CONCURRENT = attr("isExplicitGCConcurrent", //$NON-NLS-1$
 595                         Messages.getString(Messages.ATTR_EXPLICIT_GC_CONCURRENT),
 596                         Messages.getString(Messages.ATTR_EXPLICIT_GC_CONCURRENT_DESC), FLAG);
 597         public static final IAttribute<Boolean> EXPLICIT_GC_DISABLED = attr("isExplicitGCDisabled", //$NON-NLS-1$
 598                         Messages.getString(Messages.ATTR_EXPLICIT_GC_DISABLED),
 599                         Messages.getString(Messages.ATTR_EXPLICIT_GC_DISABLED_DESC), FLAG);
 600         public static final IAttribute<Boolean> USE_DYNAMIC_GC_THREADS = attr("usesDynamicGCThreads", //$NON-NLS-1$
 601                         Messages.getString(Messages.ATTR_USE_DYNAMIC_GC_THREADS),
 602                         Messages.getString(Messages.ATTR_USE_DYNAMIC_GC_THREADS_DESC), FLAG);
 603         public static final IAttribute<IQuantity> GC_TIME_RATIO = attr("gcTimeRatio", //$NON-NLS-1$
 604                         Messages.getString(Messages.ATTR_GC_TIME_RATIO), Messages.getString(Messages.ATTR_GC_TIME_RATIO_DESC),
 605                         NUMBER);
 606 
 607         public static final IAttribute<IQuantity> HEAP_MAX_SIZE = attr("maxSize", //$NON-NLS-1$
 608                         Messages.getString(Messages.ATTR_HEAP_MAX_SIZE), MEMORY);
 609         public static final IAttribute<IQuantity> HEAP_MIN_SIZE = attr("minSize", //$NON-NLS-1$
 610                         Messages.getString(Messages.ATTR_HEAP_MIN_SIZE), MEMORY);
 611         public static final IAttribute<IQuantity> HEAP_INITIAL_SIZE = attr("initialSize", //$NON-NLS-1$
 612                         Messages.getString(Messages.ATTR_HEAP_INITIAL_SIZE), MEMORY);
 613         public static final IAttribute<IQuantity> HEAP_OBJECT_ALIGNMENT = attr("objectAlignment", //$NON-NLS-1$
 614                         Messages.getString(Messages.ATTR_HEAP_OBJECT_ALIGNMENT),
 615                         Messages.getString(Messages.ATTR_HEAP_OBJECT_ALIGNMENT_DESC), MEMORY);
 616         public static final IAttribute<IQuantity> HEAP_ADDRESS_SIZE = attr("heapAddressBits", //$NON-NLS-1$
 617                         Messages.getString(Messages.ATTR_HEAP_ADDRESS_SIZE),
 618                         Messages.getString(Messages.ATTR_HEAP_ADDRESS_SIZE_DESC), NUMBER);
 619         public static final IAttribute<Boolean> HEAP_USE_COMPRESSED_OOPS = attr("usesCompressedOops", //$NON-NLS-1$
 620                         Messages.getString(Messages.ATTR_HEAP_USE_COMPRESSED_OOPS),
 621                         Messages.getString(Messages.ATTR_HEAP_USE_COMPRESSED_OOPS_DESC), FLAG);
 622         public static final IAttribute<String> HEAP_COMPRESSED_OOPS_MODE = attr("compressedOopsMode", //$NON-NLS-1$
 623                         Messages.getString(Messages.ATTR_HEAP_COMPRESSED_OOPS_MODE),
 624                         Messages.getString(Messages.ATTR_HEAP_COMPRESSED_OOPS_MODE_DESC), PLAIN_TEXT);
 625 
 626         public static final IAttribute<IQuantity> YOUNG_GENERATION_MIN_SIZE = attr("minSize", //$NON-NLS-1$
 627                         Messages.getString(Messages.ATTR_YOUNG_GENERATION_MIN_SIZE), MEMORY);
 628         public static final IAttribute<IQuantity> YOUNG_GENERATION_MAX_SIZE = attr("maxSize", //$NON-NLS-1$
 629                         Messages.getString(Messages.ATTR_YOUNG_GENERATION_MAX_SIZE), MEMORY);
 630 
 631         public static final IAttribute<IQuantity> NEW_RATIO = attr("newRatio", Messages.getString(Messages.ATTR_NEW_RATIO), //$NON-NLS-1$
 632                         Messages.getString(Messages.ATTR_NEW_RATIO_DESC), NUMBER);
 633         public static final IAttribute<IQuantity> TENURING_THRESHOLD_INITIAL = attr("initialTenuringThreshold", //$NON-NLS-1$
 634                         Messages.getString(Messages.ATTR_TENURING_THRESHOLD_INITIAL),
 635                         Messages.getString(Messages.ATTR_TENURING_THRESHOLD_INITIAL_DESC), NUMBER);
 636         public static final IAttribute<IQuantity> TENURING_THRESHOLD_MAXIMUM = attr("maxTenuringThreshold", //$NON-NLS-1$
 637                         Messages.getString(Messages.ATTR_TENURING_THRESHOLD_MAXIMUM),
 638                         Messages.getString(Messages.ATTR_TENURING_THRESHOLD_MAXIMUM_DESC), NUMBER);
 639 
 640         public static final IAttribute<Boolean> USES_TLABS = attr("usesTLABs", Messages.getString(Messages.ATTR_USES_TLABS), //$NON-NLS-1$
 641                         Messages.getString(Messages.ATTR_USES_TLABS_DESC), FLAG);
 642         public static final IAttribute<IQuantity> TLAB_MIN_SIZE = attr("minTLABSize", //$NON-NLS-1$
 643                         Messages.getString(Messages.ATTR_TLAB_MIN_SIZE), MEMORY);
 644         public static final IAttribute<IQuantity> TLAB_REFILL_WASTE_LIMIT = attr("tlabRefillWasteLimit", //$NON-NLS-1$
 645                         Messages.getString(Messages.ATTR_TLAB_REFILL_WASTE_LIMIT), MEMORY);
 646 
 647         public static final IAttribute<IQuantity> HEAP_TOTAL = attr("totalSize", //$NON-NLS-1$
 648                         Messages.getString(Messages.ATTR_HEAP_TOTAL), MEMORY);
 649         public static final IAttribute<IQuantity> HEAP_USED = attr("heapUsed", Messages.getString(Messages.ATTR_HEAP_USED), //$NON-NLS-1$
 650                         Messages.getString(Messages.ATTR_HEAP_USED_DESC), MEMORY);
 651         public static final IAttribute<String> GC_WHEN = attr("when", Messages.getString(Messages.ATTR_GC_WHEN), //$NON-NLS-1$
 652                         PLAIN_TEXT);
 653         public static final IAttribute<IQuantity> GC_ID = attr("gcId", Messages.getString(Messages.ATTR_GC_ID), //$NON-NLS-1$
 654                         Messages.getString(Messages.ATTR_GC_ID_DESC), NUMBER);
 655         public static final IAttribute<IQuantity> REFERENCE_COUNT = attr("count", //$NON-NLS-1$
 656                         Messages.getString(Messages.ATTR_REFERENCE_COUNT), NUMBER);
 657         public static final IAttribute<String> GC_PHASE_NAME = attr("name", Messages.getString(Messages.ATTR_GC_PHASE_NAME), //$NON-NLS-1$
 658                         PLAIN_TEXT);
 659 
 660         public static final IAttribute<IQuantity> GC_HEAPSPACE_COMMITTED = attr("heapSpace:committedSize", //$NON-NLS-1$
 661                         Messages.getString(Messages.ATTR_GC_HEAPSPACE_COMMITTED),
 662                         Messages.getString(Messages.ATTR_GC_HEAPSPACE_COMMITTED_DESC), MEMORY);
 663         public static final IAttribute<IQuantity> GC_HEAPSPACE_RESERVED = attr("heapSpace:reservedSize", //$NON-NLS-1$
 664                         Messages.getString(Messages.ATTR_GC_HEAPSPACE_RESERVED),
 665                         Messages.getString(Messages.ATTR_GC_HEAPSPACE_RESERVED_DESC), MEMORY);
 666 
 667         public static final IAttribute<IQuantity> GC_METASPACE_CAPACITY = attr("metaspace:capacity", //$NON-NLS-1$
 668                         Messages.getString(Messages.ATTR_GC_METASPACE_CAPACITY),
 669                         Messages.getString(Messages.ATTR_GC_METASPACE_CAPACITY_DESC), MEMORY);
 670         public static final IAttribute<IQuantity> GC_METASPACE_COMMITTED = attr("metaspace:committed", //$NON-NLS-1$
 671                         Messages.getString(Messages.ATTR_GC_METASPACE_COMMITTED),
 672                         Messages.getString(Messages.ATTR_GC_METASPACE_COMMITTED_DESC), MEMORY);
 673         public static final IAttribute<IQuantity> GC_METASPACE_RESERVED = attr("metaspace:reserved", //$NON-NLS-1$
 674                         Messages.getString(Messages.ATTR_GC_METASPACE_RESERVED),
 675                         Messages.getString(Messages.ATTR_GC_METASPACE_RESERVED_DESC), MEMORY);
 676         public static final IAttribute<IQuantity> GC_METASPACE_USED = attr("metaspace:used", //$NON-NLS-1$
 677                         Messages.getString(Messages.ATTR_GC_METASPACE_USED),
 678                         Messages.getString(Messages.ATTR_GC_METASPACE_USED_DESC), MEMORY);
 679         public static final IAttribute<IQuantity> GC_DATASPACE_COMMITTED = attr("dataSpace:committed", //$NON-NLS-1$
 680                         Messages.getString(Messages.ATTR_GC_METASPACE_DATA_COMMITTED),
 681                         Messages.getString(Messages.ATTR_GC_METASPACE_DATA_COMMITTED_DESC), MEMORY);
 682         public static final IAttribute<IQuantity> GC_DATASPACE_RESERVED = attr("dataSpace:reserved", //$NON-NLS-1$
 683                         Messages.getString(Messages.ATTR_GC_METASPACE_DATA_RESERVED),
 684                         Messages.getString(Messages.ATTR_GC_METASPACE_DATA_RESERVED_DESC), MEMORY);
 685         public static final IAttribute<IQuantity> GC_DATASPACE_USED = attr("dataSpace:used", //$NON-NLS-1$
 686                         Messages.getString(Messages.ATTR_GC_METASPACE_DATA_USED),
 687                         Messages.getString(Messages.ATTR_GC_METASPACE_DATA_USED_DESC), MEMORY);
 688         public static final IAttribute<IQuantity> GC_CLASSSPACE_COMMITTED = attr("classSpace:committed", //$NON-NLS-1$
 689                         Messages.getString(Messages.ATTR_GC_METASPACE_CLASS_COMMITTED),
 690                         Messages.getString(Messages.ATTR_GC_METASPACE_CLASS_COMMITTED_DESC), MEMORY);
 691         public static final IAttribute<IQuantity> GC_CLASSSPACE_RESERVED = attr("classSpace:reserved", //$NON-NLS-1$
 692                         Messages.getString(Messages.ATTR_GC_METASPACE_CLASS_RESERVED),
 693                         Messages.getString(Messages.ATTR_GC_METASPACE_CLASS_RESERVED_DESC), MEMORY);
 694         public static final IAttribute<IQuantity> GC_CLASSSPACE_USED = attr("classSpace:used", //$NON-NLS-1$
 695                         Messages.getString(Messages.ATTR_GC_METASPACE_CLASS_USED),
 696                         Messages.getString(Messages.ATTR_GC_METASPACE_CLASS_USED_DESC), MEMORY);
 697 
 698         public static final IAttribute<IQuantity> GC_THRESHOLD = attr("gcThreshold", //$NON-NLS-1$
 699                         Messages.getString(Messages.ATTR_GC_THRESHOLD), Messages.getString(Messages.ATTR_GC_THRESHOLD_DESC),
 700                         MEMORY);
 701 
 702         public static final IAttribute<IQuantity> OS_MEMORY_TOTAL = attr("totalSize", //$NON-NLS-1$
 703                         Messages.getString(Messages.ATTR_OS_MEMORY_TOTAL), Messages.getString(Messages.ATTR_OS_MEMORY_TOTAL_DESC),
 704                         MEMORY);
 705         public static final IAttribute<IQuantity> OS_MEMORY_USED = attr("usedSize", //$NON-NLS-1$
 706                         Messages.getString(Messages.ATTR_OS_MEMORY_USED), Messages.getString(Messages.ATTR_OS_MEMORY_USED_DESC),
 707                         MEMORY);
 708 
 709         public static final IAttribute<String> FLAG_NAME = attr("name", Messages.getString(Messages.ATTR_FLAG_NAME), //$NON-NLS-1$
 710                         PLAIN_TEXT);
 711         public static final IAttribute<String> FLAG_ORIGIN = attr("origin", Messages.getString(Messages.ATTR_FLAG_ORIGIN), //$NON-NLS-1$
 712                         PLAIN_TEXT);
 713         public static final IAttribute<IQuantity> FLAG_VALUE_NUMBER = attr("value", //$NON-NLS-1$
 714                         Messages.getString(Messages.ATTR_FLAG_VALUE_NUMBER), NUMBER);
 715         public static final IAttribute<Boolean> FLAG_VALUE_BOOLEAN = attr("value", //$NON-NLS-1$
 716                         Messages.getString(Messages.ATTR_FLAG_VALUE_BOOLEAN), FLAG);
 717         public static final IAttribute<String> FLAG_VALUE_TEXT = attr("value", //$NON-NLS-1$
 718                         Messages.getString(Messages.ATTR_FLAG_VALUE_TEXT), PLAIN_TEXT);
 719 
 720         public static final IAttribute<String> THREAD_DUMP_RESULT = attr("result", //$NON-NLS-1$
 721                         Messages.getString(Messages.ATTR_THREAD_DUMP_RESULT), PLAIN_TEXT);
 722         public static final IAttribute<String> DUMP_REASON = attr("reason", Messages.getString(Messages.ATTR_DUMP_REASON), //$NON-NLS-1$
 723                         Messages.getString(Messages.ATTR_DUMP_REASON_DESC), PLAIN_TEXT);
 724         public static final IAttribute<String> DUMP_REASON_RECORDING_ID = attr("recordingId", //$NON-NLS-1$
 725                         Messages.getString(Messages.ATTR_DUMP_REASON_RECORDING_ID),
 726                         Messages.getString(Messages.ATTR_DUMP_REASON_RECORDING_ID_DESC), PLAIN_TEXT);
 727         
 728         public static final IAttribute<String> SHUTDOWN_REASON = attr("reason", //$NON-NLS-1$
 729                         Messages.getString(Messages.ATTR_SHUTDOWN_REASON),
 730                         Messages.getString(Messages.ATTR_SHUTDOWN_REASON_DESC), PLAIN_TEXT);
 731 
 732         public static final IAttribute<IQuantity> CLASSLOADER_LOADED_COUNT = attr("loadedClassCount", //$NON-NLS-1$
 733                         Messages.getString(Messages.ATTR_CLASSLOADER_LOADED_COUNT),
 734                         Messages.getString(Messages.ATTR_CLASSLOADER_LOADED_COUNT_DESC), NUMBER);
 735         public static final IAttribute<IQuantity> CLASSLOADER_UNLOADED_COUNT = attr("unloadedClassCount", //$NON-NLS-1$
 736                         Messages.getString(Messages.ATTR_CLASSLOADER_UNLOADED_COUNT),
 737                         Messages.getString(Messages.ATTR_CLASSLOADER_UNLOADED_COUNT_DESC), NUMBER);
 738 
 739         private static final IAttribute<IMCType> CLASS_DEFINING_CLASSLOADER_V0 = attr("definingClassLoader", //$NON-NLS-1$
 740                         Messages.getString(Messages.ATTR_CLASS_DEFINING_CLASSLOADER), CLASS);
 741         private static final IAttribute<IMCType> CLASS_INITIATING_CLASSLOADER_V0 = attr("initiatingClassLoader", //$NON-NLS-1$
 742                         Messages.getString(Messages.ATTR_CLASS_INITIATING_CLASSLOADER), CLASS);
 743         private static final IAttribute<IMCType> PARENT_CLASSLOADER_V0 = attr("parentClassLoader", //$NON-NLS-1$
 744                         Messages.getString(Messages.ATTR_PARENT_CLASSLOADER), CLASS);
 745         private static final IAttribute<IMCType> CLASSLOADER_V0 = attr("classLoader", //$NON-NLS-1$
 746                         Messages.getString(Messages.ATTR_CLASSLOADER), CLASS);
 747 
 748         public static final IAttribute<IMCClassLoader> CLASS_DEFINING_CLASSLOADER = Attribute
 749                         .canonicalize(new Attribute<IMCClassLoader>("definingClassLoader", //$NON-NLS-1$
 750                                         Messages.getString(Messages.ATTR_CLASS_DEFINING_CLASSLOADER), null, CLASS_LOADER) {
 751                                 @Override
 752                                 public <U> IMemberAccessor<IMCClassLoader, U> customAccessor(IType<U> type) {
 753                                         // V1 is handled by the standard accessor
 754                                         final IMemberAccessor<IMCType, U> accessorV0 = CLASS_DEFINING_CLASSLOADER_V0.getAccessor(type);
 755                                         if (accessorV0 != null) {
 756                                                 return new IMemberAccessor<IMCClassLoader, U>() {
 757                                                         @Override
 758                                                         public IMCClassLoader getMember(U i) {
 759                                                                 IMCType type = accessorV0.getMember(i);
 760                                                                 return new MCClassLoader(type, null);
 761                                                         }
 762                                                 };
 763                                         }
 764                                         return null;
 765                                 }
 766                         });
 767         public static final IAttribute<IMCClassLoader> CLASS_INITIATING_CLASSLOADER = Attribute
 768                         .canonicalize(new Attribute<IMCClassLoader>("initiatingClassLoader", //$NON-NLS-1$
 769                                         Messages.getString(Messages.ATTR_CLASS_INITIATING_CLASSLOADER), null, CLASS_LOADER) {
 770                                 @Override
 771                                 public <U> IMemberAccessor<IMCClassLoader, U> customAccessor(IType<U> type) {
 772                                         // V1 is handled by the standard accessor
 773                                         final IMemberAccessor<IMCType, U> accessorV0 = CLASS_INITIATING_CLASSLOADER_V0.getAccessor(type);
 774                                         if (accessorV0 != null) {
 775                                                 return new IMemberAccessor<IMCClassLoader, U>() {
 776                                                         @Override
 777                                                         public IMCClassLoader getMember(U i) {
 778                                                                 IMCType type = accessorV0.getMember(i);
 779                                                                 return new MCClassLoader(type, null);
 780                                                         }
 781                                                 };
 782                                         }
 783                                         return null;
 784                                 }
 785                         });
 786         public static final IAttribute<IMCClassLoader> PARENT_CLASSLOADER = Attribute
 787                         .canonicalize(new Attribute<IMCClassLoader>("parentClassLoader", //$NON-NLS-1$
 788                                         Messages.getString(Messages.ATTR_PARENT_CLASSLOADER), null, CLASS_LOADER) {
 789                                 @Override
 790                                 public <U> IMemberAccessor<IMCClassLoader, U> customAccessor(IType<U> type) {
 791                                         // V1 is handled by the standard accessor
 792                                         final IMemberAccessor<IMCType, U> accessorV0 = PARENT_CLASSLOADER_V0.getAccessor(type);
 793                                         if (accessorV0 != null) {
 794                                                 return new IMemberAccessor<IMCClassLoader, U>() {
 795                                                         @Override
 796                                                         public IMCClassLoader getMember(U i) {
 797                                                                 IMCType type = accessorV0.getMember(i);
 798                                                                 return new MCClassLoader(type, null);
 799                                                         }
 800                                                 };
 801                                         }
 802                                         return null;
 803                                 }
 804                         });
 805         public static final IAttribute<IMCClassLoader> CLASSLOADER = Attribute
 806                         .canonicalize(new Attribute<IMCClassLoader>("classLoader", //$NON-NLS-1$
 807                                         Messages.getString(Messages.ATTR_CLASSLOADER), null, CLASS_LOADER) {
 808                                 @Override
 809                                 public <U> IMemberAccessor<IMCClassLoader, U> customAccessor(IType<U> type) {
 810                                         // V1 is handled by the standard accessor
 811                                         final IMemberAccessor<IMCType, U> accessorV0 = CLASSLOADER_V0.getAccessor(type);
 812                                         if (accessorV0 != null) {
 813                                                 return new IMemberAccessor<IMCClassLoader, U>() {
 814                                                         @Override
 815                                                         public IMCClassLoader getMember(U i) {
 816                                                                 IMCType type = accessorV0.getMember(i);
 817                                                                 return new MCClassLoader(type, null);
 818                                                         }
 819                                                 };
 820                                         }
 821                                         return null;
 822                                 }
 823                         });
 824         public static final IAttribute<String> CLASS_DEFINING_CLASSLOADER_STRING = Attribute
 825                         .canonicalize(new Attribute<String>("defininingClassLoader.string", //$NON-NLS-1$
 826                                         Messages.getString(Messages.ATTR_CLASS_DEFINING_CLASSLOADER), null, PLAIN_TEXT) {
 827                                 @Override
 828                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 829                                         final IMemberAccessor<IMCClassLoader, U> accessor = CLASS_DEFINING_CLASSLOADER.getAccessor(type);
 830                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 831                                                 @Override
 832                                                 public String getMember(U i) {
 833                                                         IMCClassLoader cl = accessor.getMember(i);
 834                                                         return cl == null ? null : FormatToolkit.getHumanReadable(cl);
 835                                                 }
 836                                         };
 837                                 }
 838                         });
 839         public static final IAttribute<String> CLASS_INITIATING_CLASSLOADER_STRING = Attribute
 840                         .canonicalize(new Attribute<String>("initiatingClassLoader.string", //$NON-NLS-1$
 841                                         Messages.getString(Messages.ATTR_CLASS_INITIATING_CLASSLOADER), null, PLAIN_TEXT) {
 842                                 @Override
 843                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 844                                         final IMemberAccessor<IMCClassLoader, U> accessor = CLASS_INITIATING_CLASSLOADER.getAccessor(type);
 845                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 846                                                 @Override
 847                                                 public String getMember(U i) {
 848                                                         IMCClassLoader cl = accessor.getMember(i);
 849                                                         return cl == null ? null : FormatToolkit.getHumanReadable(cl);
 850                                                 }
 851                                         };
 852                                 }
 853                         });
 854         public static final IAttribute<String> PARENT_CLASSLOADER_STRING = Attribute
 855                         .canonicalize(new Attribute<String>("parentClassLoader.string", //$NON-NLS-1$
 856                                         Messages.getString(Messages.ATTR_PARENT_CLASSLOADER), null, PLAIN_TEXT) {
 857                                 @Override
 858                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 859                                         final IMemberAccessor<IMCClassLoader, U> accessor = PARENT_CLASSLOADER.getAccessor(type);
 860                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 861                                                 @Override
 862                                                 public String getMember(U i) {
 863                                                         IMCClassLoader cl = accessor.getMember(i);
 864                                                         return cl == null ? null : FormatToolkit.getHumanReadable(cl);
 865                                                 }
 866                                         };
 867                                 }
 868                         });
 869 
 870         public static final IAttribute<String> CLASSLOADER_STRING = Attribute
 871                         .canonicalize(new Attribute<String>("classLoader.string", //$NON-NLS-1$
 872                                         Messages.getString(Messages.ATTR_CLASSLOADER), null, PLAIN_TEXT) {
 873                                 @Override
 874                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 875                                         final IMemberAccessor<IMCClassLoader, U> accessor = CLASSLOADER.getAccessor(type);
 876                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 877                                                 @Override
 878                                                 public String getMember(U i) {
 879                                                         IMCClassLoader cl = accessor.getMember(i);
 880                                                         return cl == null ? null : FormatToolkit.getHumanReadable(cl);
 881                                                 }
 882                                         };
 883                                 }
 884                         });
 885 
 886         public static final IAttribute<IMCType> CLASS_LOADED = attr("loadedClass", //$NON-NLS-1$
 887                         Messages.getString(Messages.ATTR_CLASS_LOADED), CLASS);
 888         public static final IAttribute<IMCType> CLASS_UNLOADED = attr("unloadedClass", //$NON-NLS-1$
 889                         Messages.getString(Messages.ATTR_CLASS_UNLOADED), CLASS);
 890         public static final IAttribute<IMCType> CLASS_DEFINED = attr("definedClass", //$NON-NLS-1$
 891                         Messages.getString(Messages.ATTR_CLASS_DEFINED), CLASS);
 892         public static final IAttribute<IQuantity> ANONYMOUS_BLOCK_SIZE = attr("anonymousBlockSize", //$NON-NLS-1$
 893                         Messages.getString(Messages.ATTR_ANONYMOUS_BLOCK_SIZE), MEMORY);
 894         public static final IAttribute<IQuantity> ANONYMOUS_CHUNK_SIZE = attr("anonymousChunkSize", //$NON-NLS-1$ 
 895                         Messages.getString(Messages.ATTR_ANONYMOUS_CHUNK_SIZE), MEMORY);
 896         public static final IAttribute<IQuantity> ANONYMOUS_CLASS_COUNT = attr("anonymousClassCount", //$NON-NLS-1$
 897                         Messages.getString(Messages.ATTR_ANONYMOUS_CLASS_COUNT), NUMBER);
 898         public static final IAttribute<IQuantity> BLOCK_SIZE = attr("blockSize", //$NON-NLS-1$
 899                         Messages.getString(Messages.ATTR_BLOCK_SIZE), MEMORY);
 900         public static final IAttribute<IQuantity> CHUNK_SIZE = attr("chunkSize", //$NON-NLS-1$
 901                         Messages.getString(Messages.ATTR_CHUNK_SIZE), MEMORY);
 902         public static final IAttribute<IQuantity> CLASS_COUNT = attr("classCount", //$NON-NLS-1$
 903                         Messages.getString(Messages.ATTR_CLASS_COUNT), NUMBER);
 904         public static final IAttribute<IQuantity> CLASS_LOADER_DATA = attr("classLoaderData", //$NON-NLS-1$
 905                         Messages.getString(Messages.ATTR_CLASSLOADER_DATA), ADDRESS);   
 906 
 907         public static final IAttribute<IQuantity> COMPILER_COMPILATION_ID = attr("compileId", //$NON-NLS-1$
 908                         Messages.getString(Messages.ATTR_COMPILER_COMPILATION_ID), NUMBER);
 909         public static final IAttribute<IQuantity> COMPILER_CODE_SIZE = attr("codeSize", //$NON-NLS-1$
 910                         Messages.getString(Messages.ATTR_COMPILER_CODE_SIZE), MEMORY);
 911         public static final IAttribute<IQuantity> COMPILER_INLINED_SIZE = attr("inlinedBytes", //$NON-NLS-1$
 912                         Messages.getString(Messages.ATTR_COMPILER_INLINED_SIZE), MEMORY);
 913         public static final IAttribute<IMCMethod> COMPILER_METHOD = attr("method", //$NON-NLS-1$
 914                         Messages.getString(Messages.ATTR_COMPILER_METHOD), METHOD);
 915         public static final IAttribute<String> COMPILER_METHOD_STRING = Attribute.canonicalize(
 916                         new Attribute<String>("method.humanreadable", Messages.getString(Messages.ATTR_COMPILER_METHOD_HUMAN), //$NON-NLS-1$
 917                                         Messages.getString(Messages.ATTR_COMPILER_METHOD_HUMAN_DESC), PLAIN_TEXT) {
 918                                 @Override
 919                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
 920                                         final IMemberAccessor<IMCMethod, U> accessor = COMPILER_METHOD.getAccessor(type);
 921                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
 922                                                 @Override
 923                                                 public String getMember(U i) {
 924                                                         IMCMethod method = accessor.getMember(i);
 925                                                         return method == null ? null : FormatToolkit.getHumanReadable(method);
 926                                                 }
 927                                         };
 928                                 }
 929                         });
 930         public static final IAttribute<String> COMPILER_FAILED_MESSAGE = attr("failureMessage", //$NON-NLS-1$
 931                         Messages.getString(Messages.ATTR_COMPILER_FAILED_MESSAGE), PLAIN_TEXT);
 932         public static final IAttribute<IQuantity> COMPILER_STANDARD_COUNT = attr("standardCompileCount", //$NON-NLS-1$
 933                         Messages.getString(Messages.ATTR_COMPILER_STANDARD_COUNT), NUMBER);
 934         public static final IAttribute<IQuantity> COMPILER_OSR_COUNT = attr("osrCompileCount", //$NON-NLS-1$
 935                         Messages.getString(Messages.ATTR_COMPILER_OSR_COUNT), NUMBER);
 936         public static final IAttribute<IQuantity> COMPILER_COMPILATION_LEVEL = attr("compileLevel", //$NON-NLS-1$
 937                         Messages.getString(Messages.ATTR_COMPILER_COMPILATION_LEVEL), NUMBER);
 938         public static final IAttribute<Boolean> COMPILER_COMPILATION_SUCCEEDED = attr("succeded", //$NON-NLS-1$
 939                         Messages.getString(Messages.ATTR_COMPILER_COMPILATION_SUCCEEDED), FLAG);
 940         public static final IAttribute<Boolean> COMPILER_IS_OSR = attr("isOsr", //$NON-NLS-1$
 941                         Messages.getString(Messages.ATTR_COMPILER_IS_OSR), FLAG);
 942 
 943         public static final IAttribute<IQuantity> START_ADDRESS = attr("startAddress", //$NON-NLS-1$
 944                         Messages.getString(Messages.ATTR_START_ADDRESS), ADDRESS);
 945         public static final IAttribute<IQuantity> COMMITTED_TOP = attr("commitedTopAddress", //$NON-NLS-1$
 946                         Messages.getString(Messages.ATTR_COMMITTED_TOP), ADDRESS);
 947         public static final IAttribute<IQuantity> RESERVED_TOP = attr("reservedTopAddress", //$NON-NLS-1$
 948                         Messages.getString(Messages.ATTR_RESERVED_TOP), ADDRESS);
 949         public static final IAttribute<IQuantity> ENTRIES = attr("entryCount", Messages.getString(Messages.ATTR_ENTRIES), //$NON-NLS-1$
 950                         NUMBER);
 951         public static final IAttribute<IQuantity> METHODS = attr("methodCount", Messages.getString(Messages.ATTR_METHODS), //$NON-NLS-1$
 952                         NUMBER);
 953         public static final IAttribute<IQuantity> ADAPTORS = attr("adaptorCount", //$NON-NLS-1$
 954                         Messages.getString(Messages.ATTR_ADAPTORS), NUMBER);
 955         public static final IAttribute<IQuantity> FULL_COUNT = attr("fullCount", //$NON-NLS-1$
 956                         Messages.getString(Messages.ATTR_FULL_COUNT), NUMBER);
 957         public static final IAttribute<IQuantity> UNALLOCATED = attr("unallocatedCapacity", //$NON-NLS-1$
 958                         Messages.getString(Messages.ATTR_UNALLOCATED), MEMORY);
 959 
 960         private static final String CODE_HEAP_NON_NMETHODS = "CodeHeap 'non-nmethods'"; //$NON-NLS-1$
 961         private static final String CODE_HEAP_NON_PROFILED_NMETHODS = "CodeHeap 'non-profiled nmethods'"; //$NON-NLS-1$
 962         private static final String CODE_HEAP_PROFILED_NMETHODS = "CodeHeap 'profiled nmethods'"; //$NON-NLS-1$
 963 
 964         public static final IAttribute<IQuantity> PROFILED_UNALLOCATED = Attribute
 965                         .canonicalize(createCodeHeapAttribute(UNALLOCATED, CODE_HEAP_PROFILED_NMETHODS, "profiledUnallocated", //$NON-NLS-1$
 966                                         Messages.getString(Messages.ATTR_PROFILED_NMETHODS_UNALLOCATED),
 967                                         Messages.getString(Messages.ATTR_PROFILED_NMETHODS_UNALLOCATED_DESCRIPTION), MEMORY));
 968         public static final IAttribute<IQuantity> PROFILED_ENTRIES = Attribute
 969                         .canonicalize(createCodeHeapAttribute(ENTRIES, CODE_HEAP_PROFILED_NMETHODS, "profiledEntries", //$NON-NLS-1$
 970                                         Messages.getString(Messages.ATTR_PROFILED_NMETHODS_ENTRIES),
 971                                         Messages.getString(Messages.ATTR_PROFILED_NMETHODS_ENTRIES_DESCRIPTION), NUMBER));
 972         public static final IAttribute<IQuantity> PROFILED_METHODS = Attribute
 973                         .canonicalize(createCodeHeapAttribute(METHODS, CODE_HEAP_PROFILED_NMETHODS, "profiledMethods", //$NON-NLS-1$
 974                                         Messages.getString(Messages.ATTR_PROFILED_NMETHODS_METHODS),
 975                                         Messages.getString(Messages.ATTR_PROFILED_NMETHODS_METHODS_DESCRIPTION), NUMBER));
 976         public static final IAttribute<IQuantity> NON_PROFILED_NMETHODS_UNALLOCATED = Attribute
 977                         .canonicalize(createCodeHeapAttribute(UNALLOCATED, CODE_HEAP_NON_PROFILED_NMETHODS,
 978                                         "nonProfiledUnallocated", Messages.getString(Messages.ATTR_NON_PROFILED_NMETHODS_UNALLOCATED), //$NON-NLS-1$
 979                                         Messages.getString(Messages.ATTR_NON_PROFILED_NMETHODS_UNALLOCATED_DESCRIPTION), MEMORY));
 980         public static final IAttribute<IQuantity> NON_PROFILED_NMETHODS_ENTRIES = Attribute
 981                         .canonicalize(createCodeHeapAttribute(ENTRIES, CODE_HEAP_NON_PROFILED_NMETHODS, "nonProfiledEntries", //$NON-NLS-1$
 982                                         Messages.getString(Messages.ATTR_NON_PROFILED_NMETHODS_ENTRIES),
 983                                         Messages.getString(Messages.ATTR_NON_PROFILED_NMETHODS_ENTRIES_DESCRIPTION), NUMBER));
 984         public static final IAttribute<IQuantity> NON_PROFILED_METHODS = Attribute
 985                         .canonicalize(createCodeHeapAttribute(METHODS, CODE_HEAP_NON_PROFILED_NMETHODS, "nonProfiledMethods", //$NON-NLS-1$
 986                                         Messages.getString(Messages.ATTR_NON_PROFILED_NMETHODS_METHODS),
 987                                         Messages.getString(Messages.ATTR_NON_PROFILED_NMETHODS_METHODS_DESCRIPTION), NUMBER));
 988         public static final IAttribute<IQuantity> NON_NMETHODS_UNALLOCATED = Attribute
 989                         .canonicalize(createCodeHeapAttribute(UNALLOCATED, CODE_HEAP_NON_NMETHODS, "nonNmethodsUnallocated", //$NON-NLS-1$
 990                                         Messages.getString(Messages.ATTR_NON_NMETHODS_UNALLOCATED),
 991                                         Messages.getString(Messages.ATTR_NON_NMETHODS_UNALLOCATED_DESCRIPTION), MEMORY));
 992         public static final IAttribute<IQuantity> NON_NMETHODS_ENTRIES = Attribute
 993                         .canonicalize(createCodeHeapAttribute(ENTRIES, CODE_HEAP_NON_NMETHODS, "nonNmethodsEntries", //$NON-NLS-1$
 994                                         Messages.getString(Messages.ATTR_NON_NMETHODS_ENTRIES),
 995                                         Messages.getString(Messages.ATTR_NON_NMETHODS_ENTRIES_DESCRIPTION), NUMBER));
 996         public static final IAttribute<IQuantity> NON_NMETHODS_ADAPTORS = Attribute
 997                         .canonicalize(createCodeHeapAttribute(ADAPTORS, CODE_HEAP_NON_NMETHODS, "nonNmethodsAdaptors", //$NON-NLS-1$
 998                                         Messages.getString(Messages.ATTR_NON_NMETHODS_ADAPTORS),
 999                                         Messages.getString(Messages.ATTR_NON_NMETHODS_ADAPTORS_DESCRIPTION), NUMBER));
1000 
1001         /**
1002          * Workaround for badly constructed JDK 9 segmented code cache events. Creates a synthetic
1003          * attributes for specific code heaps.
1004          *
1005          * @param attribute
1006          *            the attribute to convert
1007          * @param codeHeap
1008          *            the code heap for the new attribute to be for
1009          * @param identifier
1010          *            the identifier of the new attribute
1011          * @param name
1012          *            the name of the new attribute
1013          * @param description
1014          *            the description of the new attribute
1015          * @param contentType
1016          *            the content type of the new attribute
1017          * @return the wrapped attribute for the specified code heap and attribute
1018          */
1019         private static Attribute<IQuantity> createCodeHeapAttribute(
1020                 final IAttribute<IQuantity> attribute, final String codeHeap, String identifier, String name,
1021                 String description, ContentType<IQuantity> contentType) {
1022                 return new Attribute<IQuantity>(identifier, name, description, contentType) {
1023                         @Override
1024                         public <U> IMemberAccessor<IQuantity, U> customAccessor(IType<U> type) {
1025                                 final IMemberAccessor<IQuantity, U> attributeAccessor = attribute.getAccessor(type);
1026                                 final IMemberAccessor<String, U> codeHeapAccessor = CODE_HEAP.getAccessor(type);
1027                                 return attributeAccessor == null || codeHeapAccessor == null ? null
1028                                                 : new IMemberAccessor<IQuantity, U>() {
1029                                                         @Override
1030                                                         public IQuantity getMember(U i) {
1031                                                                 return codeHeapAccessor.getMember(i).equals(codeHeap) ? attributeAccessor.getMember(i)
1032                                                                                 : null;
1033                                                         }
1034                                                 };
1035                         }
1036                 };
1037         }
1038 
1039         public static final IAttribute<String> CODE_HEAP = attr("codeBlobType", Messages.getString(Messages.ATTR_CODE_HEAP), //$NON-NLS-1$
1040                         PLAIN_TEXT);
1041 
1042         public static final IAttribute<IQuantity> SWEEP_INDEX = attr("sweepId", //$NON-NLS-1$
1043                         Messages.getString(Messages.ATTR_SWEEP_INDEX), NUMBER);
1044         public static final IAttribute<IQuantity> SWEEP_FRACTION_INDEX = attr("sweepFractionIndex", //$NON-NLS-1$
1045                         Messages.getString(Messages.ATTR_SWEEP_FRACTION_INDEX), NUMBER);
1046         public static final IAttribute<IQuantity> SWEEP_METHOD_SWEPT = attr("sweptCount", //$NON-NLS-1$
1047                         Messages.getString(Messages.ATTR_SWEEP_METHOD_SWEPT), NUMBER);
1048         public static final IAttribute<IQuantity> SWEEP_METHOD_FLUSHED = attr("flushedCount", //$NON-NLS-1$
1049                         Messages.getString(Messages.ATTR_SWEEP_METHOD_FLUSHED), NUMBER);
1050         public static final IAttribute<IQuantity> SWEEP_METHOD_RECLAIMED = attr("markedCount", //$NON-NLS-1$
1051                         Messages.getString(Messages.ATTR_SWEEP_METHOD_RECLAIMED), NUMBER);
1052         public static final IAttribute<IQuantity> SWEEP_METHOD_ZOMBIFIED = attr("zombifiedCount", //$NON-NLS-1$
1053                         Messages.getString(Messages.ATTR_SWEEP_METHOD_ZOMBIFIED), NUMBER);
1054 
1055         public static final IAttribute<IQuantity> INITIAL_SIZE = attr("initialSize", //$NON-NLS-1$
1056                         Messages.getString(Messages.ATTR_INITIAL_SIZE), MEMORY);
1057         public static final IAttribute<IQuantity> RESERVED_SIZE = attr("reservedSize", //$NON-NLS-1$
1058                         Messages.getString(Messages.ATTR_RESERVED_SIZE), MEMORY);
1059         public static final IAttribute<IQuantity> EXPANSION_SIZE = attr("expansionSize", //$NON-NLS-1$
1060                         Messages.getString(Messages.ATTR_EXPANSION_SIZE), MEMORY);
1061         public static final IAttribute<IQuantity> NON_PROFILED_SIZE = attr("nonProfiledSize", //$NON-NLS-1$
1062                         Messages.getString(Messages.ATTR_NON_PROFILED_SIZE), MEMORY);
1063         public static final IAttribute<IQuantity> PROFILED_SIZE = attr("profiledSize", //$NON-NLS-1$
1064                         Messages.getString(Messages.ATTR_PROFILED_SIZE), MEMORY);
1065         public static final IAttribute<IQuantity> NON_NMETHOD_SIZE = attr("nonNMethodSize", //$NON-NLS-1$
1066                         Messages.getString(Messages.ATTR_NON_NMETHOD_SIZE), MEMORY);
1067 
1068         public static final IAttribute<String> ENVIRONMENT_KEY = attr("key", //$NON-NLS-1$
1069                         Messages.getString(Messages.ATTR_ENVIRONMENT_KEY), PLAIN_TEXT);
1070         public static final IAttribute<String> ENVIRONMENT_VALUE = attr("value", //$NON-NLS-1$
1071                         Messages.getString(Messages.ATTR_ENVIRONMENT_VALUE), PLAIN_TEXT);
1072 
1073         public static final IAttribute<IQuantity> EXCEPTION_THROWABLES_COUNT = attr("throwables", //$NON-NLS-1$
1074                         Messages.getString(Messages.ATTR_EXCEPTION_THROWABLES_COUNT),
1075                         Messages.getString(Messages.ATTR_EXCEPTION_THROWABLES_COUNT_DESC), NUMBER);
1076         public static final IAttribute<IMCType> EXCEPTION_THROWNCLASS = attr("thrownClass", //$NON-NLS-1$
1077                         Messages.getString(Messages.ATTR_EXCEPTION_THROWNCLASS), CLASS);
1078         public static final IAttribute<String> EXCEPTION_THROWNCLASS_NAME = Attribute.canonicalize(
1079                         new Attribute<String>("thrownClassName", Messages.getString(Messages.ATTR_EXCEPTION_THROWNCLASS_NAME), //$NON-NLS-1$
1080                                         Messages.getString(Messages.ATTR_EXCEPTION_THROWNCLASS_NAME_DESC), PLAIN_TEXT) {
1081                                 @Override
1082                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
1083                                         final IMemberAccessor<IMCType, U> accessor = EXCEPTION_THROWNCLASS.getAccessor(type);
1084                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
1085                                                 @Override
1086                                                 public String getMember(U i) {
1087                                                         IMCType type = accessor.getMember(i);
1088                                                         return type == null ? null : type.getFullName();
1089                                                 }
1090                                         };
1091                                 }
1092                         });
1093 
1094         public static final IAttribute<String> EXCEPTION_MESSAGE = attr("message", //$NON-NLS-1$
1095                         Messages.getString(Messages.ATTR_EXCEPTION_MESSAGE), PLAIN_TEXT);
1096 
1097         public static final IAttribute<IQuantity> MONITOR_ADDRESS = attr("address", //$NON-NLS-1$
1098                         Messages.getString(Messages.ATTR_MONITOR_ADDRESS), ADDRESS);
1099         public static final IAttribute<IMCType> MONITOR_CLASS = attr("monitorClass", //$NON-NLS-1$
1100                         Messages.getString(Messages.ATTR_MONITOR_CLASS), CLASS);
1101         public static final IAttribute<IMCThread> MONITOR_PREVIOUS_OWNER = attr("previousOwner", //$NON-NLS-1$
1102                         Messages.getString(Messages.ATTR_MONITOR_PREVIOUS_OWNER), THREAD);
1103 
1104         public static final IAttribute<IQuantity> OS_SWITCH_RATE = attr("switchRate", //$NON-NLS-1$
1105                         Messages.getString(Messages.ATTR_OS_SWITCH_RATE), NUMBER);
1106         public static final IAttribute<String> REFERENCE_STATISTICS_TYPE = attr("type", //$NON-NLS-1$
1107                         Messages.getString(Messages.ATTR_REFERENCE_STATISTICS_TYPE), PLAIN_TEXT);
1108         public static final IAttribute<IQuantity> REFERENCE_STATISTICS_COUNT = attr("count", //$NON-NLS-1$
1109                         Messages.getString(Messages.ATTR_REFERENCE_STATISTICS_COUNT), NUMBER);
1110         public static final IAttribute<IQuantity> GC_SUM_OF_PAUSES = attr("sumOfPauses", //$NON-NLS-1$
1111                         Messages.getString(Messages.ATTR_GC_SUM_OF_PAUSES), Messages.getString(Messages.ATTR_GC_SUM_OF_PAUSES_DESC),
1112                         TIMESPAN);
1113         public static final IAttribute<IQuantity> GC_LONGEST_PAUSE = attr("longestPause", //$NON-NLS-1$
1114                         Messages.getString(Messages.ATTR_GC_LONGEST_PAUSE), Messages.getString(Messages.ATTR_GC_LONGEST_PAUSE_DESC),
1115                         TIMESPAN);
1116         public static final IAttribute<String> GC_NAME = attr("name", Messages.getString(Messages.ATTR_GC_NAME), //$NON-NLS-1$
1117                         Messages.getString(Messages.ATTR_GC_NAME_DESC), PLAIN_TEXT);
1118         public static final IAttribute<String> GC_CAUSE = attr("cause", Messages.getString(Messages.ATTR_GC_CAUSE), //$NON-NLS-1$
1119                         Messages.getString(Messages.ATTR_GC_CAUSE_DESC), PLAIN_TEXT);
1120 
1121         public static final IAttribute<IMCOldObject> OBJECT = attr("object", Messages.getString(Messages.ATTR_REFERRER), //$NON-NLS-1$
1122                         Messages.getString(Messages.ATTR_REFERRER_DESC), OLD_OBJECT);
1123         public static final IAttribute<IQuantity> ALLOCATION_TIME = attr("allocationTime", //$NON-NLS-1$
1124                         Messages.getString(Messages.ATTR_REFERRER), Messages.getString(Messages.ATTR_REFERRER_DESC), TIMESTAMP);
1125         public static final IAttribute<IMCOldObjectGcRoot> GC_ROOT = attr("root", Messages.getString(Messages.ATTR_GC_ROOT), //$NON-NLS-1$
1126                         Messages.getString(Messages.ATTR_GC_ROOT_DESC), UnitLookup.OLD_OBJECT_GC_ROOT);
1127         public static final IAttribute<IMCType> OLD_OBJECT_CLASS = Attribute
1128                         .canonicalize(new Attribute<IMCType>("oldObjectClass", Messages.getString(Messages.ATTR_OLD_OBJECT_CLASS), //$NON-NLS-1$
1129                                         Messages.getString(Messages.ATTR_OLD_OBJECT_CLASS_DESC), CLASS) {
1130                                 @Override
1131                                 public <U> IMemberAccessor<IMCType, U> customAccessor(IType<U> type) {
1132                                         final IMemberAccessor<IMCOldObject, U> accessor = OBJECT.getAccessor(type);
1133                                         return accessor == null ? null : new IMemberAccessor<IMCType, U>() {
1134                                                 @Override
1135                                                 public IMCType getMember(U i) {
1136                                                         IMCOldObject object = accessor.getMember(i);
1137                                                         return object == null ? null : object.getType();
1138                                                 }
1139                                         };
1140                                 }
1141                         });
1142         public static final IAttribute<String> OLD_OBJECT_DESCRIPTION = Attribute.canonicalize(
1143                         new Attribute<String>("oldObjectDescription", Messages.getString(Messages.ATTR_OLD_OBJECT_DESCRIPTION), //$NON-NLS-1$
1144                                         Messages.getString(Messages.ATTR_OLD_OBJECT_DESCRIPTION_DESC), PLAIN_TEXT) {
1145                                 @Override
1146                                 public <U> IMemberAccessor<String, U> customAccessor(IType<U> type) {
1147                                         final IMemberAccessor<IMCOldObject, U> accessor = OBJECT.getAccessor(type);
1148                                         return accessor == null ? null : new IMemberAccessor<String, U>() {
1149                                                 @Override
1150                                                 public String getMember(U i) {
1151                                                         IMCOldObject object = accessor.getMember(i);
1152                                                         return object == null ? null : object.getDescription();
1153                                                 }
1154                                         };
1155                                 }
1156                         });
1157         public static final IAttribute<Long> OLD_OBJECT_ARRAY_SIZE = Attribute.canonicalize(
1158                         new Attribute<Long>("oldObjectArraySize", Messages.getString(Messages.ATTR_OLD_OBJECT_ARRAY_SIZE), //$NON-NLS-1$
1159                                         Messages.getString(Messages.ATTR_OLD_OBJECT_ARRAY_SIZE_DESC), UnitLookup.RAW_LONG) {
1160                                 @Override
1161                                 public <U> IMemberAccessor<Long, U> customAccessor(IType<U> type) {
1162                                         final IMemberAccessor<IMCOldObject, U> accessor = OBJECT.getAccessor(type);
1163                                         return accessor == null ? null : new IMemberAccessor<Long, U>() {
1164                                                 @Override
1165                                                 public Long getMember(U i) {
1166                                                         IMCOldObject object = accessor.getMember(i);
1167                                                         return object != null && object.getReferrerArray() != null
1168                                                                         ? object.getReferrerArray().getSize() : null;
1169                                                 }
1170                                         };
1171                                 }
1172                         });
1173         public static final IAttribute<IQuantity> OLD_OBJECT_ADDRESS = Attribute.canonicalize(
1174                         new Attribute<IQuantity>("oldObjectAddress", Messages.getString(Messages.ATTR_OLD_OBJECT_ADDRESS), //$NON-NLS-1$
1175                                         Messages.getString(Messages.ATTR_OLD_OBJECT_ADDRESS_DESC), ADDRESS) {
1176                                 @Override
1177                                 public <U> IMemberAccessor<IQuantity, U> customAccessor(IType<U> type) {
1178                                         final IMemberAccessor<IMCOldObject, U> accessor = OBJECT.getAccessor(type);
1179                                         return accessor == null ? null : new IMemberAccessor<IQuantity, U>() {
1180                                                 @Override
1181                                                 public IQuantity getMember(U i) {
1182                                                         IMCOldObject object = accessor.getMember(i);
1183                                                         return object == null ? null : object.getAddress();
1184                                                 }
1185                                         };
1186                                 }
1187                         });
1188 
1189         public static final IAttribute<String> OS_VERSION = attr("osVersion", Messages.getString(Messages.ATTR_OS_VERSION), //$NON-NLS-1$
1190                         PLAIN_TEXT);
1191         public static final IAttribute<IQuantity> NUMBER_OF_SOCKETS = attr("sockets", //$NON-NLS-1$
1192                         Messages.getString(Messages.ATTR_NUMBER_OF_SOCKETS),
1193                         Messages.getString(Messages.ATTR_NUMBER_OF_SOCKETS_DESC), NUMBER);
1194         public static final IAttribute<String> CPU_DESCRIPTION = attr("description", //$NON-NLS-1$
1195                         Messages.getString(Messages.ATTR_CPU_DESCRIPTION), Messages.getString(Messages.ATTR_CPU_DESCRIPTION_DESC),
1196                         PLAIN_TEXT);
1197         public static final IAttribute<String> CPU_TYPE = attr("cpu", Messages.getString(Messages.ATTR_CPU_TYPE), //$NON-NLS-1$
1198                         PLAIN_TEXT);
1199         public static final IAttribute<IQuantity> NUMBER_OF_CORES = attr("cores", //$NON-NLS-1$
1200                         Messages.getString(Messages.ATTR_NUMBER_OF_CORES), Messages.getString(Messages.ATTR_NUMBER_OF_CORES_DESC),
1201                         NUMBER);
1202         public static final IAttribute<Boolean> BLOCKING = attr("blocking", Messages.getString(Messages.ATTR_BLOCKING), //$NON-NLS-1$
1203                         Messages.getString(Messages.ATTR_BLOCKING_DESC), FLAG);
1204         public static final IAttribute<Boolean> SAFEPOINT = attr("safepoint", Messages.getString(Messages.ATTR_SAFEPOINT), //$NON-NLS-1$
1205                         Messages.getString(Messages.ATTR_SAFEPOINT_DESC), FLAG);
1206         public static final IAttribute<String> OPERATION = attr("operation", Messages.getString(Messages.ATTR_OPERATION), //$NON-NLS-1$
1207                         Messages.getString(Messages.ATTR_OPERATION_DESC), PLAIN_TEXT);
1208         public static final IAttribute<IMCThread> CALLER = attr("caller", Messages.getString(Messages.ATTR_CALLER), //$NON-NLS-1$
1209                         Messages.getString(Messages.ATTR_CALLER_DESC), THREAD);
1210         public static final IAttribute<IMCType> BIASED_REVOCATION_LOCK_CLASS = attr("lockClass", //$NON-NLS-1$
1211                         Messages.getString(Messages.ATTR_REVOKATION_LOCK_CLASS),
1212                         Messages.getString(Messages.ATTR_REVOKATION_LOCK_CLASS_DESC), CLASS);
1213         public static final IAttribute<IMCType> BIASED_REVOCATION_CLASS = attr("revokedClass", //$NON-NLS-1$
1214                         Messages.getString(Messages.ATTR_REVOKED_CLASS), Messages.getString(Messages.ATTR_REVOKED_CLASS_DESC),
1215                         CLASS);
1216         public static final IAttribute<Boolean> BIASED_REVOCATION_DISABLE_BIASING = attr("disableBiasing", //$NON-NLS-1$
1217                         Messages.getString(Messages.ATTR_DISABLE_BIASING), FLAG);
1218 }