JOL Hotspot SA Support and Compressed References Implementation

Serkan ÖZAL serkanozal86 at hotmail.com
Tue Jan 6 11:15:10 UTC 2015


Hi Volker,

Thats right. There is a specific workaround for Debin/Ubuntu. Maybe 
there are more for other UNIX based operating systems.
Therefore, I just advice "sudo" for general solution (At least, it works 
for Ubuntu and MacOSX).

But if we can found another solution for this particular problem, it 
will be great.
I am willing to listen all ideas.

Regards.

--

Serkan ÖZAL
> On Sun, Jan 4, 2015 at 3:24 PM, Serkan ÖZAL <serkanozal86 at hotmail.com> wrote:
>   
>> Hi Aleksey,
>>
>> I have prepared a patch (sending as attahced to this mail) about for
>> embedded Hotspot SA support infrastructure and compressed reference
>> implementation on top of it for JOL.
>> I implemented Hotspot SA support with no compile-time dependency to
>> "sa-jdi.jar" as we talked before. At first, required classes is searched at
>> current classpath. If not found, then looks to <JAVA_HOME>.
>> If it still couldn't be found, Hotspot SA support is skipped gracefully with
>> an information message and goes on before.
>>
>> There is an interface named "HotspotServiceabilityAgentProcessor" for
>> executing any business logic on Hotspot SA process and all required
>> instances such as "sun.jvm.hotspot.HotSpotAgent" and
>> "sun.jvm.hotspot.HotSpotAgent" are passed to "process" method of this
>> interface typed implementation in a context instance typed
>> "HotspotServiceabilityAgentContext". All processors return their result as
>> "HotspotServiceabilityAgentResult" typed response. All requests, processors
>> and reponses are serialized/deserialized between current process and Hotspot
>> SA process via pipeline.
>>
>> So for possible future cases, I think we can easily use all magics of
>> Hotspot SA API and also JOL API users can implement their own Hotspot SA
>> processors and runs on our infrastructure via
>> "HotspotServiceabilityAgentSupport" class.
>>
>> Also, I implemented finding compressed references on top of this
>> infrastructure and integrated with "VMSupport" class.
>>
>> IMPORTANT NOTE:
>>
>> On some UNIX based operating systems and MacOSX operation system, Hotspot
>> Serviceability Agent (SA) process attach may fail due to insufficient
>> privilege. So, on these operating systems, user (runs the application) must
>> be super user and  must be already authenticated for example with "sudo"
>> command (also with password) to "/etc/sudoers" file.
>>
>>     
>
> At least on Debian/Ubuntu this is a known problem which can easily be
> fixed by doing:
>
> echo 0 > /proc/sys/kernel/yama/ptrace_scope
>
> or set ptrace_scope to 0 in /etc/sysctl.d/10-ptrace.conf
>
> See https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace_Protection
> for more details.
>
> Regards,
> Volker
>
>   
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7129704
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7050524
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7112802
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7160774
>>
>>
>> I hope it is OK. Waiting for your comments about patch.
>>
>> Regards.
>>
>> --
>>
>> Serkan ÖZAL
>>
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/HotspotServiceabilityAgentSupport.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/HotspotServiceabilityAgentSupport.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,604 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util;
>> +
>> +import java.io.ByteArrayOutputStream;
>> +import java.io.File;
>> +import java.io.IOException;
>> +import java.io.ObjectInputStream;
>> +import java.io.ObjectOutputStream;
>> +import java.io.Serializable;
>> +import java.lang.management.ManagementFactory;
>> +import java.lang.management.RuntimeMXBean;
>> +import java.lang.reflect.Field;
>> +import java.lang.reflect.InvocationTargetException;
>> +import java.lang.reflect.Method;
>> +import java.util.ArrayList;
>> +import java.util.List;
>> +
>> +import org.openjdk.jol.util.sa.HotspotServiceabilityAgentContext;
>> +import org.openjdk.jol.util.sa.HotspotServiceabilityAgentProcessor;
>> +import org.openjdk.jol.util.sa.HotspotServiceabilityAgentResult;
>> +import org.openjdk.jol.util.sa.impl.HotspotServiceabilityAgentUtil;
>> +import
>> org.openjdk.jol.util.sa.impl.compressedrefs.HotspotSACompressedReferencesProcessor;
>> +import
>> org.openjdk.jol.util.sa.impl.compressedrefs.HotspotSACompressedReferencesResult;
>> +
>> +import sun.management.VMManagement;
>> +
>> +/**
>> + * Hotspot Serviceability Agent support.
>> + *
>> + * IMPORTANT NOTE:
>> + *      On some UNIX based operating systems and MacOSX operation system,
>> + *      Hotspot Serviceability Agent (SA) process attach may fail due to
>> insufficient privilege.
>> + *      So, on these operating systems, user (runs the application) must be
>> super user and  must be already authenticated
>> + *      for example with <code>"sudo"</code> command (also with password)
>> to <code>"/etc/sudoers"</code> file.
>> + *
>> + *      For more information about <code>"sudo"</code>, please have a look:
>> + *          @link http://en.wikipedia.org/wiki/Sudo
>> + *          @link http://linux.about.com/od/commands/l/blcmdl8_sudo.htm
>> + *
>> + * @see HotspotServiceabilityAgentProcessor
>> + * @see HotspotServiceabilityAgentResult
>> + *
>> + * @see HotspotSACompressedReferencesProcessor
>> + * @see HotspotSACompressedReferencesResult
>> + *
>> + * @author Serkan Ozal
>> + */
>> +public class HotspotServiceabilityAgentSupport {
>> +
>> +    private static final String SKIP_HOTSPOT_SA_ATTACH_FLAG =
>> "jol.skipHotspotSAAttach";
>> +
>> +    private static final int DEFAULT_TIMEOUT_IN_MSECS = 10000; // 10
>> seconds
>> +    private static final int VM_CHECK_PERIOD_SENSITIVITY_IN_MSECS = 1000;
>> // 1 seconds
>> +
>> +       private static final boolean enable;
>> +       private static final int processId;
>> +       private static final String classpathForAgent;
>> +       private static final String errorMessage;
>> +
>> +       static {
>> +           boolean active = true;
>> +           int currentProcId = -1;
>> +           String classpathForAgentProc = null;
>> +           String errorMsg = null;
>> +
>> +           if (Boolean.getBoolean(SKIP_HOTSPOT_SA_ATTACH_FLAG)) {
>> +               active = false;
>> +               errorMsg = "Hotspot SA attach skip flag (" +
>> SKIP_HOTSPOT_SA_ATTACH_FLAG + ") is set. " +
>> +                       "So skipping Hotspot SA support ...";
>> +        } else {
>> +
>> +               final String jvmName =
>> System.getProperty("java.vm.name").toLowerCase();
>> +               // Hotspot Serviceability Agent is only supported on Hotspot
>> JVM
>> +               if (!jvmName.contains("hotspot") &&
>> !jvmName.contains("openjdk")) {
>> +                   active = false;
>> +                   errorMsg = "Hotspot Serviceabiliy Agent is only
>> supported on Hotspot JVM. " +
>> +                              "So skipping Hotspot SA support ...";
>> +               } else {
>> +                       try {
>> +                           // Find current process id to connect via
>> Hotspot agent
>> +                    RuntimeMXBean mxbean =
>> ManagementFactory.getRuntimeMXBean();
>> +                    Field jvmField =
>> mxbean.getClass().getDeclaredField("jvm");
>> +                    jvmField.setAccessible(true);
>> +
>> +                    VMManagement management = (VMManagement)
>> jvmField.get(mxbean);
>> +                    Method method =
>> management.getClass().getDeclaredMethod("getProcessId");
>> +                    method.setAccessible(true);
>> +                    currentProcId = (Integer) method.invoke(management);
>> +                } catch (Throwable t) {
>> +                    active = false;
>> +                    errorMsg = "Couldn't find id of current JVM process. "
>> +
>> +                               "So skipping Hotspot SA support ...";
>> +                }
>> +               }
>> +
>> +               final String currentClasspath =
>> normalizePath(ManagementFactory.getRuntimeMXBean().getClassPath());
>> +               try {
>> +                   // Search it at classpath
>> +
>> Class.forName(HotspotServiceabilityAgentUtil.HOTSPOT_AGENT_CLASSNAME);
>> +
>> +                   // Use current classpath for agent process
>> +                   classpathForAgentProc = currentClasspath;
>> +               } catch (ClassNotFoundException e1) {
>> +                   try {
>> +                           // If it couldn't be found at classpath, try to
>> find it at
>> +                           File hotspotAgentLib =
>> +                                   new
>> File(normalizePath(System.getProperty("java.home")) + "/../lib/sa-jdi.jar");
>> +                           if (hotspotAgentLib.exists()) {
>> +                               classpathForAgentProc =
>> +                                       currentClasspath +
>> File.pathSeparator +
>> +
>> normalizePath(hotspotAgentLib.getAbsolutePath());
>> +                           } else {
>> +                               active = false;
>> +                        errorMsg = "Couldn't find Hotspot SA library
>> (sa-jdi.jar) in both classpath and <JAVA_HOME>/../lib/ directory. " +
>> +                                   "So skipping Hotspot SA support ...";
>> +                           }
>> +                   } catch (Throwable t2) {
>> +                       active = false;
>> +                    errorMsg = "Couldn't find Hotspot SA library
>> (sa-jdi.jar) in both classpath and <JAVA_HOME>/../lib/ directory. " +
>> +                               "So skipping Hotspot SA support ...";
>> +                   }
>> +               }
>> +        }
>> +
>> +               enable = active;
>> +               processId = currentProcId;
>> +               classpathForAgent = classpathForAgentProc;
>> +               errorMessage = errorMsg;
>> +       }
>> +
>> +       private HotspotServiceabilityAgentSupport() {
>> +
>> +       }
>> +
>> +       private static String normalizePath(String path) {
>> +           return path.replace('\\', '/');
>> +       }
>> +
>> +       private static void checkEnable() {
>> +           if (!enable) {
>> +               throw new IllegalStateException(errorMessage);
>> +           }
>> +       }
>> +
>> +       /**
>> +        * Checks and gets the condition about if "sudo" command is required
>> +        * for creating external Java process to connect current process as
>> Hotspot agent.
>> +        * On some UNIX based and MacOSX based operations systems,
>> +        * Hotspot Serviceability Agent (SA) process attach fails due to
>> insufficient privilege.
>> +        * So these processes must be execute as super user.
>> +        *
>> +        * See also JVM Bug reports:
>> +        *     @link
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7129704
>> +        *     @link
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7050524
>> +        *     @link
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7112802
>> +        *     @link
>> http://bugs.java.com/bugdatabase/view_bug.do?bug_id=7160774
>> +        *     @link https://bugs.openjdk.java.net/browse/JDK-7129704
>> +        *     @link https://bugs.openjdk.java.net/browse/JDK-7050524
>> +        *     @link https://bugs.openjdk.java.net/browse/JDK-7112802
>> +        *     @link https://bugs.openjdk.java.net/browse/JDK-7160774
>> +        *
>> +        * @return <code>true</code> if "sudo" command is required,
>> otherwise <code>false</code>
>> +        */
>> +    private static boolean isSudoRequired() {
>> +        String osName = System.getProperty("os.name").toLowerCase();
>> +        if (osName.indexOf("nix") >= 0 || osName.indexOf("nux") >= 0 ||
>> osName.indexOf("aix") > 0) { // UNIX based operation system
>> +            return true;
>> +        } else if (osName.indexOf("mac") >= 0) { // MacOSX based operation
>> system
>> +            return true;
>> +        } else {
>> +            return false;
>> +        }
>> +    }
>> +
>> +    private static <R extends HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>>
>> +               R executeOnHotspotSAInternal(P processor, int
>> timeoutInMsecs) {
>> +           checkEnable();
>> +
>> +           // Generate required arguments to create an external Java
>> process
>> +           List<String> args = new ArrayList<String>();
>> +           if (isSudoRequired()) {
>> +               args.add("sudo");
>> +           }
>> +        args.add(normalizePath(System.getProperty("java.home")) + "/" +
>> "bin" + "/" + "java");
>> +        args.add("-cp");
>> +        args.add(classpathForAgent);
>> +        args.add(HotspotServiceabilityAgentSupport.class.getName());
>> +        args.add(String.valueOf(processId));
>> +
>> +        Process agentProcess = null;
>> +        try {
>> +            // Create an external Java process to connect this process as
>> Hotspot agent
>> +            agentProcess = new ProcessBuilder(args).start();
>> +
>> +            HotspotServiceabilityAgentRequest<P> request =
>> +                    new HotspotServiceabilityAgentRequest<P>(processId,
>> processor, timeoutInMsecs);
>> +            AgentConnectionHandlerThread<R, P> agentConnectionHandlerThread
>> =
>> +                    new AgentConnectionHandlerThread<R, P>(agentProcess,
>> request);
>> +
>> +            // Start handler thread to manage pipeline between current
>> process and Hotspot agent process
>> +            agentConnectionHandlerThread.start();
>> +
>> +            // Wait as timeout duration at most
>> +            agentConnectionHandlerThread.join(timeoutInMsecs);
>> +
>> +            // Check about if there is a timeout
>> +            if (!agentConnectionHandlerThread.isFinished()) {
>> +                agentConnectionHandlerThread.destroy();
>> +                throw new RuntimeException("Timeout " + "(" +
>> timeoutInMsecs + " milliseconds" + ")" +
>> +                                           " reached for processor " +
>> processor);
>> +            }
>> +
>> +            // Get response from Hotspot agent process
>> +            HotspotServiceabilityAgentResponse<R> response =
>> agentConnectionHandlerThread.getResponse();
>> +            if (response.getError() != null) {
>> +                Throwable error = response.getError();
>> +                throw new RuntimeException(error.getMessage(), error);
>> +            }
>> +            R result = response.getResult();
>> +
>> +            return result;
>> +        } catch (Throwable t) {
>> +            throw new RuntimeException(t.getMessage(), t);
>> +        } finally {
>> +            if (agentProcess != null) {
>> +                agentProcess.destroy();
>> +            }
>> +        }
>> +       }
>> +
>> +    private static <P extends HotspotServiceabilityAgentProcessor<?>> P
>> createInstance(Class<P> processorClass) {
>> +        try {
>> +            return processorClass.newInstance();
>> +        } catch (Throwable t) {
>> +            throw new IllegalArgumentException("Could not create instance
>> of " + processorClass.getName(), t);
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Manages pipeline (I/O) between current process and Hotspot agent
>> process.
>> +     *
>> +     * @param <R> the type of {@link HotspotServiceabilityAgentResult}
>> +     * @param <P> the type of {@link HotspotServiceabilityAgentProcessor}
>> +     */
>> +       private static class AgentConnectionHandlerThread<R extends
>> HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>>
>> +               extends Thread {
>> +
>> +           private Process agentProcess;
>> +           private HotspotServiceabilityAgentRequest<P> request;
>> +           private HotspotServiceabilityAgentResponse<R> response;
>> +           private ObjectInputStream in;
>> +           private ObjectOutputStream out;
>> +           private volatile boolean finished;
>> +
>> +           private AgentConnectionHandlerThread(Process agentProcess,
>> HotspotServiceabilityAgentRequest<P> request) {
>> +               this.agentProcess = agentProcess;
>> +               this.request = request;
>> +           }
>> +
>> +           @SuppressWarnings("unchecked")
>> +        @Override
>> +           public void run() {
>> +               try {
>> +                   // Send request Hotspot agent process to execute
>> +                   out = new
>> ObjectOutputStream(agentProcess.getOutputStream());
>> +                   out.writeObject(request);
>> +                   out.flush();
>> +
>> +                   // Get response from Hotspot agent process
>> +                   in = new
>> ObjectInputStream(agentProcess.getInputStream());
>> +                   response = (HotspotServiceabilityAgentResponse<R>)
>> in.readObject();
>> +
>> +                   finished = true;
>> +               } catch (Throwable t) {
>> +                   finished = true;
>> +
>> +                   throw new RuntimeException(t.getMessage(), t);
>> +               }
>> +           }
>> +
>> +           @SuppressWarnings("deprecation")
>> +        @Override
>> +           public void destroy() {
>> +               if (in != null) {
>> +                   try {
>> +                    in.close();
>> +                } catch (IOException e) {
>> +                    // There is nothing to do, so just ignore
>> +                }
>> +               }
>> +               if (out != null) {
>> +                try {
>> +                    out.flush();
>> +                    out.close();
>> +                } catch (IOException e) {
>> +                    // There is nothing to do, so just ignore
>> +                }
>> +            }
>> +               super.destroy();
>> +           }
>> +
>> +           public HotspotServiceabilityAgentResponse<R> getResponse() {
>> +            return response;
>> +        }
>> +
>> +           public boolean isFinished() {
>> +            return finished;
>> +        }
>> +
>> +       }
>> +
>> +       /**
>> +        * Represents request to Hotspot agent process by holding process
>> id, timeout and
>> +        * {@link HotspotServiceabilityAgentProcessor} to execute.
>> +        *
>> +        * @param <P> the type of {@link
>> HotspotServiceabilityAgentProcessor}
>> +        */
>> +       @SuppressWarnings("serial")
>> +    private static class HotspotServiceabilityAgentRequest<P extends
>> HotspotServiceabilityAgentProcessor<?>>
>> +               implements Serializable {
>> +
>> +           private int processId;
>> +           private P processor;
>> +           private int timeout = DEFAULT_TIMEOUT_IN_MSECS;
>> +
>> +           private HotspotServiceabilityAgentRequest() {
>> +
>> +           }
>> +
>> +           private HotspotServiceabilityAgentRequest(int processId, P
>> processor) {
>> +            this.processId = processId;
>> +            this.processor = processor;
>> +        }
>> +
>> +           private HotspotServiceabilityAgentRequest(int processId, P
>> processor, int timeout) {
>> +            this.processId = processId;
>> +            this.processor = processor;
>> +            this.timeout = timeout;
>> +        }
>> +
>> +           public int getProcessId() {
>> +            return processId;
>> +        }
>> +
>> +           public P getProcessor() {
>> +            return processor;
>> +        }
>> +
>> +        public int getTimeout() {
>> +            return timeout;
>> +        }
>> +
>> +       }
>> +
>> +       /**
>> +     * Represents response from Hotspot agent process by holding {@link
>> HotspotServiceabilityAgentResult} and
>> +     * error if occurred.
>> +     *
>> +     * @param <R> the type of {@link HotspotServiceabilityAgentResult}
>> +     */
>> +       @SuppressWarnings("serial")
>> +       private static class HotspotServiceabilityAgentResponse<R extends
>> HotspotServiceabilityAgentResult>
>> +               implements Serializable {
>> +
>> +           private R result;
>> +           private Throwable error;
>> +
>> +           private HotspotServiceabilityAgentResponse() {
>> +
>> +           }
>> +
>> +           private HotspotServiceabilityAgentResponse(R result) {
>> +            this.result = result;
>> +        }
>> +
>> +           private HotspotServiceabilityAgentResponse(Throwable error) {
>> +            this.error = error;
>> +        }
>> +
>> +           public R getResult() {
>> +            return result;
>> +        }
>> +
>> +           public void setResult(R result) {
>> +            this.result = result;
>> +        }
>> +
>> +           public Throwable getError() {
>> +            return error;
>> +        }
>> +
>> +           public void setError(Throwable error) {
>> +            this.error = error;
>> +        }
>> +
>> +    }
>> +
>> +       @SuppressWarnings({ "unchecked", "rawtypes" })
>> +    public static <R extends HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>> void main(final String[] args) {
>> +           final HotspotServiceabilityAgentResponse<R> response = new
>> HotspotServiceabilityAgentResponse();
>> +           ByteArrayOutputStream bos = new ByteArrayOutputStream();
>> +           ObjectInputStream in = null;
>> +        ObjectOutputStream out = null;
>> +        Object hotspotAgent = null;
>> +        Method detachMethod = null;
>> +
>> +       try {
>> +           // Gets request from caller process over standard input
>> +           in = new ObjectInputStream(System.in);
>> +           out = new ObjectOutputStream(bos);
>> +
>> +           System.setProperty("sun.jvm.hotspot.debugger.useProcDebugger",
>> "true");
>> +
>> System.setProperty("sun.jvm.hotspot.debugger.useWindbgDebugger", "true");
>> +
>> +            final HotspotServiceabilityAgentRequest<P> request =
>> (HotspotServiceabilityAgentRequest<P>) in.readObject();
>> +
>> +            final Class<?> hotspotAgentClass =
>> HotspotServiceabilityAgentUtil.getHotspotAgentClass();
>> +            hotspotAgent =
>> HotspotServiceabilityAgentUtil.createHotspotAgentInstance();
>> +            final Method attachMethod =
>> hotspotAgentClass.getMethod("attach", int.class);
>> +            detachMethod = hotspotAgentClass.getMethod("detach");
>> +
>> +            Object vm = null;
>> +
>> +            final Object agent = hotspotAgent;
>> +            Thread t = new Thread() {
>> +                public void run() {
>> +                    try {
>> +                        // Attach to the caller process as Hotspot agent
>> +                        attachMethod.invoke(agent, request.getProcessId());
>> +                    } catch (IllegalArgumentException e) {
>> +                        throw new RuntimeException("Cannot attach to
>> process as Hotspot SA", e);
>> +                    } catch (IllegalAccessException e) {
>> +                        throw new RuntimeException("Cannot attach to
>> process as Hotspot SA", e);
>> +                    } catch (InvocationTargetException e) {
>> +                        throw new RuntimeException("Cannot attach to
>> process as Hotspot SA", e);
>> +                    }
>> +                };
>> +            };
>> +            t.start();
>> +
>> +            // Check until timeout
>> +            for (int i = 0; i < request.getTimeout(); i +=
>> VM_CHECK_PERIOD_SENSITIVITY_IN_MSECS) {
>> +                Thread.sleep(VM_CHECK_PERIOD_SENSITIVITY_IN_MSECS); // Wait
>> a little before an attempt
>> +                try {
>> +                    if ((vm =
>> HotspotServiceabilityAgentUtil.getVMInstance()) != null) {
>> +                        break;
>> +                    }
>> +                } catch (Throwable err) {
>> +                    // There is nothing to do, try another
>> +                }
>> +            }
>> +
>> +            // Check about if VM is initialized and ready to use
>> +            if (vm != null) {
>> +                final P processor = request.getProcessor();
>> +                // Execute processor and gets its result
>> +                final R result = processor.process(new
>> HotspotServiceabilityAgentContext(hotspotAgent, vm));
>> +                response.setResult(result);
>> +            } else {
>> +                throw new IllegalStateException("VM couldn't be initialized
>> !");
>> +            }
>> +       } catch (Throwable t) {
>> +           // If there is an error, attach it to response
>> +           response.setError(t);
>> +       } finally {
>> +           if (out != null) {
>> +               try {
>> +                   // Send response back to caller process over standard
>> output
>> +                    out.writeObject(response);
>> +                    out.flush();
>> +                    System.out.write(bos.toByteArray());
>> +                } catch (IOException e) {
>> +                    // There is nothing to do, so just ignore
>> +                }
>> +           }
>> +           if (hotspotAgent != null && detachMethod != null) {
>> +               try {
>> +                    detachMethod.invoke(hotspotAgent);
>> +                } catch (IllegalArgumentException e) {
>> +                    // There is nothing to do, so just ignore
>> +                } catch (IllegalAccessException e) {
>> +                    // There is nothing to do, so just ignore
>> +                } catch (InvocationTargetException e) {
>> +                    // There is nothing to do, so just ignore
>> +                }
>> +           }
>> +       }
>> +    }
>> +
>> +       /**
>> +        * Returns <code>true</code> if Hotspot Serviceability Agent support
>> is enable, otherwise <code>false</code>.
>> +        *
>> +        * @return the enable state of Hotspot Serviceability Agent support
>> +        */
>> +    public static boolean isEnable() {
>> +        return enable;
>> +    }
>> +
>> +    /**
>> +     * Executes given typed {@link HotspotServiceabilityAgentProcessor} on
>> Hotspot agent process and returns
>> +     * {@link HotspotServiceabilityAgentResult} as result.
>> +     *
>> +     * @param <R> the type of {@link HotspotServiceabilityAgentResult}
>> +     * @param <P> the type of {@link HotspotServiceabilityAgentProcessor}
>> +     * @param processorClass the type of {@link
>> HotspotServiceabilityAgentProcessor} instance to execute
>> +     * @return the {@link HotspotServiceabilityAgentProcessor} instance as
>> result of processor execution
>> +     */
>> +       public static <R extends HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>>
>> +           R executeOnHotspotSA(Class<P> processorClass) {
>> +       return executeOnHotspotSA(createInstance(processorClass),
>> DEFAULT_TIMEOUT_IN_MSECS);
>> +    }
>> +
>> +       /**
>> +     * Executes given {@link HotspotServiceabilityAgentProcessor} on
>> Hotspot agent process and returns
>> +     * {@link HotspotServiceabilityAgentResult} instance as result.
>> +     *
>> +     * @param <R> the type of {@link HotspotServiceabilityAgentResult}
>> +     * @param <P> the type of {@link HotspotServiceabilityAgentProcessor}
>> +     * @param processor the {@link HotspotServiceabilityAgentProcessor}
>> instance to execute
>> +     * @return the {@link HotspotServiceabilityAgentProcessor} instance as
>> result of processor execution
>> +     */
>> +    public static <R extends HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>>
>> +           R executeOnHotspotSA(P processor) {
>> +       return executeOnHotspotSAInternal(processor,
>> DEFAULT_TIMEOUT_IN_MSECS);
>> +    }
>> +
>> +    /**
>> +     * Executes given typed {@link HotspotServiceabilityAgentProcessor} on
>> Hotspot agent process and returns
>> +     * {@link HotspotServiceabilityAgentResult} as result.
>> +     *
>> +     * @param <R> the type of {@link HotspotServiceabilityAgentResult}
>> +     * @param <P> the type of {@link HotspotServiceabilityAgentProcessor}
>> +     * @param processorClass the type of {@link
>> HotspotServiceabilityAgentProcessor} instance to execute
>> +     * @param timeoutInMsecs the timeout in milliseconds to wait at most
>> for terminating connection
>> +     *                       between current process and Hotspot agent
>> process.
>> +     * @return the {@link HotspotServiceabilityAgentProcessor} instance as
>> result of processor execution
>> +     */
>> +    public static <R extends HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>>
>> +           R executeOnHotspotSA(Class<P> processorClass, int
>> timeoutInMsecs) {
>> +       return executeOnHotspotSA(createInstance(processorClass),
>> timeoutInMsecs);
>> +    }
>> +
>> +    /**
>> +     * Executes given {@link HotspotServiceabilityAgentProcessor} on
>> Hotspot agent process and returns
>> +     * {@link HotspotServiceabilityAgentResult} instance as result.
>> +     *
>> +     * @param <R> the type of {@link HotspotServiceabilityAgentResult}
>> +     * @param <P> the type of {@link HotspotServiceabilityAgentProcessor}
>> +     * @param processor the {@link HotspotServiceabilityAgentProcessor}
>> instance to execute
>> +     * @param timeoutInMsecs the timeout in milliseconds to wait at most
>> for terminating connection
>> +     *                       between current process and Hotspot agent
>> process.
>> +     * @return the {@link HotspotServiceabilityAgentProcessor} instance as
>> result of processor execution
>> +     */
>> +    public static <R extends HotspotServiceabilityAgentResult, P extends
>> HotspotServiceabilityAgentProcessor<R>>
>> +           R executeOnHotspotSA(P processor, int timeoutInMsecs) {
>> +       return executeOnHotspotSAInternal(processor, timeoutInMsecs);
>> +    }
>> +
>> +    /**
>> +     * Gets the compressed references information as {@link
>> HotspotSACompressedReferencesResult} instance.
>> +     *
>> +     * @return the compressed references information as {@link
>> HotspotSACompressedReferencesResult} instance
>> +     */
>> +    public static HotspotSACompressedReferencesResult
>> getCompressedReferences() {
>> +        return
>> executeOnHotspotSA(HotspotSACompressedReferencesProcessor.class);
>> +    }
>> +
>> +    /**
>> +     * Gives details about Hotspot Serviceability Agent support.
>> +     *
>> +     * @return the string representation of Hotspot Serviceability Agent
>> support
>> +     */
>> +       public static String details() {
>> +           return "HotspotServiceabilityAgentSupport [" +
>> +                   "enable=" + enable + ", " +
>> +                    "processId=" + processId  + ", " +
>> +                    "classpathForAgent=" + classpathForAgent + ", " +
>> +                    "errorMessage=" + errorMessage + "]";
>> +       }
>> +
>> +}
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/VMSupport.java
>> --- a/jol-core/src/main/java/org/openjdk/jol/util/VMSupport.java        Fri
>> Dec 19 01:45:21 2014 +0300
>> +++ b/jol-core/src/main/java/org/openjdk/jol/util/VMSupport.java        Sun
>> Jan 04 16:03:47 2015 +0200
>> @@ -27,12 +27,15 @@
>>  import org.openjdk.jol.info.ClassData;
>>  import org.openjdk.jol.info.ClassLayout;
>>  import org.openjdk.jol.layouters.CurrentLayouter;
>> +import
>> org.openjdk.jol.util.sa.impl.compressedrefs.HotspotSACompressedReferencesResult;
>> +
>>  import sun.misc.Unsafe;
>>
>>  import javax.management.MBeanServer;
>>  import javax.management.ObjectName;
>>  import javax.management.RuntimeMBeanException;
>>  import javax.management.openmbean.CompositeDataSupport;
>> +
>>  import java.io.PrintWriter;
>>  import java.io.StringWriter;
>>  import java.lang.management.ManagementFactory;
>> @@ -56,12 +59,24 @@
>>
>>      public static final String VM_NAME;
>>      public static final int ADDRESS_SIZE;
>> +    public static final int REF_SIZE;
>>      public static final int OBJ_ALIGNMENT;
>>      public static final int OBJ_HEADER_SIZE;
>> +
>>      public static final boolean USE_COMPRESSED_REFS;
>> +    public static final long COMPRESSED_REF_BASE;
>>      public static final int COMPRESSED_REF_SHIFT;
>> -
>> -    public static final int REF_SIZE;
>> +
>> +    public static final int OOP_SIZE;
>> +    public static final boolean USE_COMPRESSED_OOP;
>> +    public static final long COMPRESSED_OOP_BASE;
>> +    public static final int COMPRESSED_OOP_SHIFT;
>> +
>> +    public static final int KLASS_PTR_SIZE;
>> +    public static final boolean USE_COMPRESSED_KLASS;
>> +    public static final long COMPRESSED_KLASS_BASE;
>> +    public static final int COMPRESSED_KLASS_SHIFT;
>> +
>>      public static final int BOOLEAN_SIZE;
>>      public static final int BYTE_SIZE;
>>      public static final int CHAR_SIZE;
>> @@ -107,16 +122,32 @@
>>              headerSize = -1;
>>          }
>>
>> +        ADDRESS_SIZE = U.addressSize();
>> +
>>          VMOptions opts = VMOptions.getOptions();
>>
>> -        ADDRESS_SIZE = U.addressSize();
>> +        VM_NAME = opts.name;
>> +        REF_SIZE = opts.sizeReference;
>> +        OBJ_ALIGNMENT = opts.objectAlignment;
>>          OBJ_HEADER_SIZE = headerSize;
>> +
>> +        // For backward compatibility, OOP compressed reference mode can be
>> used as default compressed reference mode
>> +        USE_COMPRESSED_REFS = opts.compressedOopRef;
>> +        // For backward compatibility, OOP compressed base address can be
>> used as default compressed reference base address
>> +        COMPRESSED_REF_BASE = opts.compressedOopBase;
>> +        // For backward compatibility, OOP compressed shift size can be
>> used as default compressed reference shift size
>> +        COMPRESSED_REF_SHIFT = opts.compressedOopShift;
>> +
>> +        OOP_SIZE = opts.oopSize;
>> +        USE_COMPRESSED_OOP = opts.compressedOopRef;
>> +        COMPRESSED_OOP_BASE = opts.compressedOopBase;
>> +        COMPRESSED_OOP_SHIFT = opts.compressedOopShift;
>> +
>> +        KLASS_PTR_SIZE = opts.klassPtrSize;
>> +        USE_COMPRESSED_KLASS = opts.compressedKlassRef;
>> +        COMPRESSED_KLASS_BASE = opts.compressedKlassBase;
>> +        COMPRESSED_KLASS_SHIFT = opts.compressedKlassShift;
>>
>> -        VM_NAME = opts.name;
>> -        USE_COMPRESSED_REFS = opts.compressedRef;
>> -        COMPRESSED_REF_SHIFT = opts.compressRefShift;
>> -        OBJ_ALIGNMENT = opts.objectAlignment;
>> -        REF_SIZE = opts.sizeReference;
>>          BOOLEAN_SIZE = opts.sizeBoolean;
>>          BYTE_SIZE = opts.sizeByte;
>>          CHAR_SIZE = opts.sizeChar;
>> @@ -129,7 +160,47 @@
>>
>>      public static long toNativeAddress(long address) {
>>          if (USE_COMPRESSED_REFS) {
>> -            return address << COMPRESSED_REF_SHIFT;
>> +            return COMPRESSED_REF_BASE + (address << COMPRESSED_REF_SHIFT);
>> +        } else {
>> +            return address;
>> +        }
>> +    }
>> +
>> +    public static long toJvmAddress(long address) {
>> +        if (USE_COMPRESSED_REFS) {
>> +            return (address >> COMPRESSED_REF_SHIFT) - COMPRESSED_REF_BASE;
>> +        } else {
>> +            return address;
>> +        }
>> +    }
>> +
>> +    public static long toNativeOopAddress(long address) {
>> +        if (USE_COMPRESSED_OOP) {
>> +            return COMPRESSED_OOP_BASE + (address << COMPRESSED_OOP_SHIFT);
>> +        } else {
>> +            return address;
>> +        }
>> +    }
>> +
>> +    public static long toJvmOopAddress(long address) {
>> +        if (USE_COMPRESSED_OOP) {
>> +            return (address >> COMPRESSED_OOP_SHIFT) - COMPRESSED_OOP_BASE;
>> +        } else {
>> +            return address;
>> +        }
>> +    }
>> +
>> +    public static long toNativeKlassAddress(long address) {
>> +        if (USE_COMPRESSED_KLASS) {
>> +            return COMPRESSED_KLASS_BASE + (address <<
>> COMPRESSED_KLASS_SHIFT);
>> +        } else {
>> +            return address;
>> +        }
>> +    }
>> +
>> +    public static long toJvmKlassAddress(long address) {
>> +        if (USE_COMPRESSED_KLASS) {
>> +            return (address >> COMPRESSED_KLASS_SHIFT) -
>> COMPRESSED_KLASS_BASE;
>>          } else {
>>              return address;
>>          }
>> @@ -144,8 +215,39 @@
>>          PrintWriter out = new PrintWriter(sw);
>>
>>          out.println("Running " + (ADDRESS_SIZE * 8) + "-bit " + VM_NAME + "
>> VM.");
>> -        if (USE_COMPRESSED_REFS)
>> -            out.println("Using compressed references with " +
>> COMPRESSED_REF_SHIFT + "-bit shift.");
>> +
>> +        String javaSpecVersion =
>> System.getProperty("java.specification.version");
>> +        // Since Java 8 (Java 8 and Java 9) has different compressed
>> reference configuration for OOP and Klass
>> +        if (javaSpecVersion.equals("1.8") || javaSpecVersion.equals("1.9"))
>> {
>> +            if (USE_COMPRESSED_OOP) {
>> +                if (COMPRESSED_OOP_BASE != 0) {
>> +                    out.println("Using compressed oop with " +
>> +
>> formatAddressAsHexByAddressSize(COMPRESSED_OOP_BASE) + " base address and "
>> +
>> +                                COMPRESSED_OOP_SHIFT + "-bit shift.");
>> +                } else {
>> +                    out.println("Using compressed oop with " +
>> COMPRESSED_OOP_SHIFT + "-bit shift.");
>> +                }
>> +            }
>> +            if (USE_COMPRESSED_KLASS) {
>> +                if (COMPRESSED_KLASS_BASE != 0) {
>> +                    out.println("Using compressed klass with " +
>> +
>> formatAddressAsHexByAddressSize(COMPRESSED_KLASS_BASE) + " base address and
>> " +
>> +                                COMPRESSED_KLASS_SHIFT + "-bit shift.");
>> +                } else {
>> +                    out.println("Using compressed klass with " +
>> COMPRESSED_KLASS_SHIFT + "-bit shift.");
>> +                }
>> +            }
>> +        } else {
>> +            if (USE_COMPRESSED_REFS) {
>> +                if (COMPRESSED_REF_BASE != 0) {
>> +                    out.println("Using compressed references with " +
>> +
>> formatAddressAsHexByAddressSize(COMPRESSED_REF_BASE) + " base address and "
>> +
>> +                            COMPRESSED_REF_SHIFT + "-bit shift.");
>> +                } else {
>> +                    out.println("Using compressed references with " +
>> COMPRESSED_REF_SHIFT + "-bit shift.");
>> +                }
>> +            }
>> +        }
>>          out.println("Objects are " + OBJ_ALIGNMENT + " bytes aligned.");
>>
>>          out.printf("%-19s: %d, %d, %d, %d, %d, %d, %d, %d, %d [bytes]%n",
>> @@ -177,6 +279,11 @@
>>          out.close();
>>          return sw.toString();
>>      }
>> +
>> +    private static String formatAddressAsHexByAddressSize(long address) {
>> +        return "0x" + String.format("%" + (ADDRESS_SIZE * 2) + "s",
>> +
>> Long.toHexString(COMPRESSED_KLASS_BASE).toUpperCase()).replace(' ', '0');
>> +    }
>>
>>      private static Object instantiateType(int type) {
>>          switch (type) {
>> @@ -261,10 +368,16 @@
>>
>>      private static class VMOptions {
>>          private final String name;
>> -        private final boolean compressedRef;
>> -        private final int compressRefShift;
>>          private final int objectAlignment;
>> -
>> +        private final int oopSize;
>> +        private final boolean compressedOopRef;
>> +        private final long compressedOopBase;
>> +        private final int compressedOopShift;
>> +        private final int klassPtrSize;
>> +        private final boolean compressedKlassRef;
>> +        private final long compressedKlassBase;
>> +        private final int compressedKlassShift;
>> +
>>          private final int sizeReference;
>>          private final int sizeBoolean = getMinDiff(MyBooleans4.class);
>>          private final int sizeByte = getMinDiff(MyBytes4.class);
>> @@ -291,26 +404,60 @@
>>              this.name = name;
>>              this.sizeReference = U.addressSize();
>>              this.objectAlignment = guessAlignment(this.sizeReference);
>> -            this.compressedRef = false;
>> -            this.compressRefShift = 1;
>> +            this.oopSize = sizeReference;
>> +            this.compressedOopRef = false;
>> +            this.compressedOopBase = 0L;
>> +            this.compressedOopShift = 0;
>> +            this.klassPtrSize = sizeReference;
>> +            this.compressedKlassRef = false;
>> +            this.compressedKlassBase = 0L;
>> +            this.compressedKlassShift = 0;
>>          }
>>
>>          public VMOptions(String name, int align) {
>>              this.name = name;
>>              this.sizeReference = 4;
>>              this.objectAlignment = align;
>> -            this.compressedRef = true;
>> -            this.compressRefShift = MathUtil.log2p(align);
>> +            this.oopSize = sizeReference;
>> +            this.compressedOopRef = true;
>> +            this.compressedOopBase = 0L;
>> +            this.compressedOopShift = MathUtil.log2p(align);
>> +            this.klassPtrSize = sizeReference;
>> +            this.compressedKlassRef = true;
>> +            this.compressedKlassBase = 0L;
>> +            this.compressedKlassShift = MathUtil.log2p(align);
>>          }
>>
>>          public VMOptions(String name, int align, int compRefShift) {
>>              this.name = name;
>>              this.sizeReference = 4;
>>              this.objectAlignment = align;
>> -            this.compressedRef = true;
>> -            this.compressRefShift = compRefShift;
>> +            this.oopSize = sizeReference;
>> +            this.compressedOopRef = true;
>> +            this.compressedOopBase = 0L;
>> +            this.compressedOopShift = compRefShift;
>> +            this.klassPtrSize = sizeReference;
>> +            this.compressedKlassRef = true;
>> +            this.compressedKlassBase = 0L;
>> +            this.compressedKlassShift = compRefShift;
>>          }
>> -
>> +
>> +        public VMOptions(String name, int align, int oopSize, boolean
>> compOopRef, long compOopBase, int compOopShift,
>> +                int klassPtrSize, boolean compKlassRef, long compKlassBase,
>> int compKlassShift) {
>> +            this.name = name;
>> +            // Use OOP size as reference size
>> +            this.sizeReference = oopSize;
>> +            this.objectAlignment = align;
>> +            this.oopSize = oopSize;
>> +            this.compressedOopRef = compOopRef;
>> +            this.compressedOopBase = compOopBase;
>> +            this.compressedOopShift = compOopShift;
>> +            this.klassPtrSize = klassPtrSize;
>> +            this.compressedKlassRef = compKlassRef;
>> +            this.compressedKlassBase = compKlassBase;
>> +            this.compressedKlassShift = compKlassShift;
>> +        }
>> +
>>          private static VMOptions getOptions() {
>>              // try Hotspot
>>              VMOptions hsOpts = getHotspotSpecifics();
>> @@ -346,6 +493,29 @@
>>              }
>>
>>              try {
>> +                try {
>> +                    HotspotSACompressedReferencesResult
>> compressedReferencesInfo =
>> +
>> HotspotServiceabilityAgentSupport.getCompressedReferences();
>> +                    if (compressedReferencesInfo != null) {
>> +                        return new VMOptions("HotSpot",
>> +
>> compressedReferencesInfo.getObjectAlignment(),
>> +
>> compressedReferencesInfo.getOopSize(),
>> +
>> compressedReferencesInfo.isCompressedOopsEnabled(),
>> +
>> compressedReferencesInfo.getNarrowOopBase(),
>> +
>> compressedReferencesInfo.getNarrowOopShift(),
>> +
>> compressedReferencesInfo.getKlassPtrSize(),
>> +
>> compressedReferencesInfo.isCompressedKlassPointersEnabled(),
>> +
>> compressedReferencesInfo.getNarrowKlassBase(),
>> +
>> compressedReferencesInfo.getNarrowKlassShift());
>> +                    } else {
>> +                        System.out.println("Compressed references
>> information couldn't be found via Hotspot SA.");
>> +                        System.out.println("So skipping Hotspot SA support
>> to find compressed references ...");
>> +                    }
>> +                } catch (Throwable t) {
>> +                    System.err.println(t.getMessage());
>> +                    System.out.println("So skipping Hotspot SA support to
>> find compressed references ...");
>> +                }
>> +
>>                  MBeanServer server =
>> ManagementFactory.getPlatformMBeanServer();
>>
>>                  try {
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/sa/HotspotServiceabilityAgentContext.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/sa/HotspotServiceabilityAgentContext.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,81 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util.sa;
>> +
>> +/**
>> + * Wrapper class to hold common necessary objects for Hotspot
>> Serviceability Agent API Usage.
>> + * It is passed to {@link
>> HotspotServiceabilityAgentProcessor#process(HotspotServiceabilityAgentContext)}
>> method
>> + * as parameter and designed for no-change on signature of this method
>> + * since other objects may be added to context at the next versions.
>> + *
>> + * @see sun.jvm.hotspot.HotSpotAgent
>> + * @see sun.jvm.hotspot.runtime.VM
>> + *
>> + * @author Serkan Ozal
>> + */
>> +public final class HotspotServiceabilityAgentContext {
>> +
>> +    /**
>> +     * The <code>hotspotAgent<code> property is defined as {@link Object}
>> because of no compile time dependency to
>> +     * {@link sun.jvm.hotspot.HotSpotAgent} class in Hotspot Serviceability
>> Agent (sa-jdi.jar).
>> +     * So the actual type of this property is {@link
>> sun.jvm.hotspot.HotSpotAgent}.
>> +     */
>> +    private Object hotspotAgent;
>> +
>> +    /**
>> +     * The <code>vm<code> property is defined as {@link Object} because of
>> no compile time dependency to
>> +     * {@link sun.jvm.hotspot.runtime.VM} class in Hotspot Serviceability
>> Agent (sa-jdi.jar).
>> +     * So the actual type of this property is {@link
>> sun.jvm.hotspot.runtime.VM}.
>> +     */
>> +    private Object vm;
>> +
>> +    public HotspotServiceabilityAgentContext() {
>> +
>> +    }
>> +
>> +    public HotspotServiceabilityAgentContext(Object hotspotAgent, Object
>> vm) {
>> +        this.hotspotAgent = hotspotAgent;
>> +        this.vm = vm;
>> +    }
>> +
>> +    public Object getHotspotAgent() {
>> +        return hotspotAgent;
>> +    }
>> +
>> +    public HotspotServiceabilityAgentContext setHotspotAgent(Object
>> hotspotAgent) {
>> +        this.hotspotAgent = hotspotAgent;
>> +        return this;
>> +    }
>> +
>> +    public Object getVm() {
>> +        return vm;
>> +    }
>> +
>> +    public HotspotServiceabilityAgentContext setVm(Object vm) {
>> +        this.vm = vm;
>> +        return this;
>> +    }
>> +
>> +}
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/sa/HotspotServiceabilityAgentProcessor.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/sa/HotspotServiceabilityAgentProcessor.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,53 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util.sa;
>> +
>> +import java.io.Serializable;
>> +
>> +/**
>> + * Interface for processors which do some stuff via Hotspot Serviceability
>> Agent API on Hotspot internals.
>> + *
>> + * {@link HotspotServiceabilityAgentProcessor} implementations must be
>> fully (including its fields) serializable.
>> + * So if there is any field will not be serialized, it must be ignored or
>> serialization logic must be customized.
>> + * Please see {@link
>> http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html} for
>> more details.
>> + * In addition, since processors is serialized/deserialized, they must have
>> default constructor.
>> + *
>> + * @see HotspotServiceabilityAgentContext
>> + * @see HotspotServiceabilityAgentResult
>> + *
>> + * @author Serkan Ozal
>> + */
>> +public interface HotspotServiceabilityAgentProcessor<O extends
>> HotspotServiceabilityAgentResult> extends Serializable {
>> +
>> +    /**
>> +     * Takes the {@link HotspotServiceabilityAgentContext} instance and
>> processes its
>> +     * own logic over this instance.
>> +     *
>> +     * @param context the {@link HotspotServiceabilityAgentContext}
>> instance wraps all necessary objects.
>> +     * @return the {@link HotspotServiceabilityAgentResult} as result
>> +     */
>> +    O process(HotspotServiceabilityAgentContext context);
>> +
>> +}
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/sa/HotspotServiceabilityAgentResult.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/sa/HotspotServiceabilityAgentResult.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,42 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util.sa;
>> +
>> +import java.io.Serializable;
>> +
>> +/**
>> + * Interface for types of {@link
>> HotspotServiceabilityAgentProcessor#process(HotspotServiceabilityAgentContext)}
>> return.
>> + * It is designed to hold all results under a hierarchy.
>> + *
>> + * {@link HotspotServiceabilityAgentResult} implementations must be fully
>> (including its fields) serializable.
>> + * So if there is any field will not be serialized, it must be ignored or
>> serialization logic must be customized.
>> + * Please see {@link
>> http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html} for
>> more details.
>> + * In addition, since processors is serialized/deserialized, they must have
>> default constructor.
>> + *
>> + * @author Serkan Ozal
>> + */
>> +public interface HotspotServiceabilityAgentResult extends Serializable {
>> +
>> +}
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/sa/impl/HotspotServiceabilityAgentUtil.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/sa/impl/HotspotServiceabilityAgentUtil.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,75 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util.sa.impl;
>> +
>> +import java.lang.reflect.InvocationTargetException;
>> +import java.lang.reflect.Method;
>> +
>> +import org.openjdk.jol.util.HotspotServiceabilityAgentSupport;
>> +
>> +/**
>> + * Hotspot Serviceability Agent utility.
>> + * It was designed for doing some utility stuff without touching {@link
>> HotspotServiceabilityAgentSupport}
>> + * class because of its static initializer.
>> + *
>> + * @author Serkan Ozal
>> + */
>> +public class HotspotServiceabilityAgentUtil {
>> +
>> +    public static final String HOTSPOT_AGENT_CLASSNAME =
>> "sun.jvm.hotspot.HotSpotAgent";
>> +    public static final String VM_CLASSNAME = "sun.jvm.hotspot.runtime.VM";
>> +    public static final String UNIVERSE_CLASSNAME =
>> "sun.jvm.hotspot.memory.Universe";
>> +
>> +       private HotspotServiceabilityAgentUtil() {
>> +
>> +       }
>> +
>> +       public static Class<?> getHotspotAgentClass() throws
>> ClassNotFoundException {
>> +           return Class.forName(HOTSPOT_AGENT_CLASSNAME);
>> +       }
>> +
>> +       public static Object createHotspotAgentInstance()
>> +               throws ClassNotFoundException, InstantiationException,
>> IllegalAccessException {
>> +           Class<?> hotspotAgentClass =
>> Class.forName(HOTSPOT_AGENT_CLASSNAME);
>> +           return hotspotAgentClass.newInstance();
>> +       }
>> +
>> +       public static Class<?> getVmClass() throws ClassNotFoundException {
>> +        return Class.forName(VM_CLASSNAME);
>> +    }
>> +
>> +       public static Object getVMInstance()
>> +               throws ClassNotFoundException, InstantiationException,
>> IllegalAccessException,
>> +                      SecurityException, NoSuchMethodException,
>> IllegalArgumentException, InvocationTargetException {
>> +           Class<?> vmClass = Class.forName(VM_CLASSNAME);
>> +           Method getVmMethod = vmClass.getMethod("getVM");
>> +        return getVmMethod.invoke(null);
>> +    }
>> +
>> +       public static Class<?> getUniverseClass() throws
>> ClassNotFoundException {
>> +           return Class.forName(UNIVERSE_CLASSNAME);
>> +       }
>> +
>> +}
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/sa/impl/compressedrefs/HotspotSACompressedReferencesProcessor.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/sa/impl/compressedrefs/HotspotSACompressedReferencesProcessor.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,105 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util.sa.impl.compressedrefs;
>> +
>> +import java.lang.reflect.Method;
>> +
>> +import org.openjdk.jol.util.sa.HotspotServiceabilityAgentContext;
>> +import org.openjdk.jol.util.sa.HotspotServiceabilityAgentProcessor;
>> +import org.openjdk.jol.util.sa.impl.HotspotServiceabilityAgentUtil;
>> +
>> +/**
>> + * {@link HotspotServiceabilityAgentProcessor} implementation to find
>> compressed reference informations.
>> + *
>> + * @author Serkan Ozal
>> + */
>> + at SuppressWarnings("serial")
>> +public class HotspotSACompressedReferencesProcessor
>> +        implements
>> HotspotServiceabilityAgentProcessor<HotspotSACompressedReferencesResult> {
>> +
>> +    @Override
>> +    public HotspotSACompressedReferencesResult
>> process(HotspotServiceabilityAgentContext context) {
>> +        try {
>> +            Class<?> universeClass =
>> HotspotServiceabilityAgentUtil.getUniverseClass();
>> +            Class<?> vmClass = HotspotServiceabilityAgentUtil.getVmClass();
>> +            Object vm = HotspotServiceabilityAgentUtil.getVMInstance();
>> +
>> +            Method getOopSizeMethod = vmClass.getMethod("getOopSize");
>> +            Method getObjectAlignmentInBytesMethod =
>> vmClass.getMethod("getObjectAlignmentInBytes");
>> +
>> +            Method getHeapOopSizeMethod =
>> vmClass.getMethod("getHeapOopSize");
>> +            Method isCompressedOopsEnabledMethod =
>> vmClass.getMethod("isCompressedOopsEnabled");
>> +            Method getNarrowOopBaseMethod =
>> universeClass.getMethod("getNarrowOopBase");
>> +            Method getNarrowOopShiftMethod =
>> universeClass.getMethod("getNarrowOopShift");
>> +
>> +            Method getKlassPtrSizeMethod = null;
>> +            Method isCompressedKlassPointersEnabledMethod = null;
>> +            Method getNarrowKlassBaseMethod = null;
>> +            Method getNarrowKlassShiftMethod = null;
>> +
>> +            try {
>> +                getKlassPtrSizeMethod =
>> vmClass.getMethod("getKlassPtrSize");
>> +                isCompressedKlassPointersEnabledMethod =
>> vmClass.getMethod("isCompressedKlassPointersEnabled");
>> +                getNarrowKlassBaseMethod =
>> universeClass.getMethod("getNarrowKlassBase");
>> +                getNarrowKlassShiftMethod =
>> universeClass.getMethod("getNarrowKlassShift");
>> +            } catch (NoSuchMethodException e) {
>> +                // There is nothing to do, seems target JVM is not Java 8
>> +            }
>> +
>> +            int addressSize = ((Long)
>> getOopSizeMethod.invoke(vm)).intValue();
>> +            int objectAlignment = (Integer)
>> getObjectAlignmentInBytesMethod.invoke(vm);
>> +
>> +            int oopSize = (Integer) getHeapOopSizeMethod.invoke(vm);
>> +            boolean compressedOopsEnabled = (Boolean)
>> isCompressedOopsEnabledMethod.invoke(vm);
>> +            long narrowOopBase = (Long)
>> getNarrowOopBaseMethod.invoke(null);
>> +            int narrowOopShift = (Integer)
>> getNarrowOopShiftMethod.invoke(null);
>> +
>> +            /*
>> +             * If compressed klass references is not supported (before Java
>> 8),
>> +             * use compressed oop references values instead of them.
>> +             */
>> +
>> +            int klassPtrSize = getKlassPtrSizeMethod != null ? (Integer
>> )getKlassPtrSizeMethod.invoke(vm) : oopSize;
>> +            boolean compressedKlassPointersEnabled =
>> isCompressedKlassPointersEnabledMethod != null
>> +                    ? (Boolean)
>> isCompressedKlassPointersEnabledMethod.invoke(vm) : compressedOopsEnabled;
>> +            long narrowKlassBase = getNarrowKlassBaseMethod != null ?
>> (Long) getNarrowKlassBaseMethod.invoke(null) : narrowOopBase;
>> +            int narrowKlassShift = getNarrowKlassShiftMethod != null ?
>> (Integer) getNarrowKlassShiftMethod.invoke(null) : narrowOopShift;
>> +
>> +            return new HotspotSACompressedReferencesResult(addressSize,
>> +                                                           objectAlignment,
>> +                                                           oopSize,
>> +
>> compressedOopsEnabled,
>> +                                                           narrowOopBase,
>> +                                                           narrowOopShift,
>> +                                                           klassPtrSize,
>> +
>> compressedKlassPointersEnabled,
>> +                                                           narrowKlassBase,
>> +
>> narrowKlassShift);
>> +        } catch (Throwable t) {
>> +            throw new RuntimeException(t.getMessage(), t);
>> +        }
>> +    }
>> +
>> +}
>> diff -r be8776814beb
>> jol-core/src/main/java/org/openjdk/jol/util/sa/impl/compressedrefs/HotspotSACompressedReferencesResult.java
>> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
>> +++
>> b/jol-core/src/main/java/org/openjdk/jol/util/sa/impl/compressedrefs/HotspotSACompressedReferencesResult.java
>> Sun Jan 04 16:03:47 2015 +0200
>> @@ -0,0 +1,181 @@
>> +/*
>> + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights
>> reserved.
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>> + *
>> + * This code is free software; you can redistribute it and/or modify it
>> + * under the terms of the GNU General Public License version 2 only, as
>> + * published by the Free Software Foundation.  Oracle designates this
>> + * particular file as subject to the "Classpath" exception as provided
>> + * by Oracle in the LICENSE file that accompanied this code.
>> + *
>> + * This code is distributed in the hope that it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> + * version 2 for more details (a copy is included in the LICENSE file that
>> + * accompanied this code).
>> + *
>> + * You should have received a copy of the GNU General Public License
>> version
>> + * 2 along with this work; if not, write to the Free Software Foundation,
>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
>> + * or visit www.oracle.com if you need additional information or have any
>> + * questions.
>> + */
>> +package org.openjdk.jol.util.sa.impl.compressedrefs;
>> +
>> +import org.openjdk.jol.util.sa.HotspotServiceabilityAgentResult;
>> +
>> +/**
>> + * {@link HotspotServiceabilityAgentResult} implementation for representing
>> compressed reference informations as result.
>> + *
>> + * @author Serkan Ozal
>> + */
>> + at SuppressWarnings("serial")
>> +public class HotspotSACompressedReferencesResult implements
>> HotspotServiceabilityAgentResult {
>> +
>> +    private int addressSize;
>> +    private int objectAlignment;
>> +
>> +    private int oopSize;
>> +    private boolean compressedOopsEnabled;
>> +    private long narrowOopBase;
>> +    private int narrowOopShift;
>> +
>> +    private int klassPtrSize;
>> +    private boolean compressedKlassPointersEnabled;
>> +    private long narrowKlassBase;
>> +    private int narrowKlassShift;
>> +
>> +
>> +    public HotspotSACompressedReferencesResult() {
>> +
>> +    }
>> +
>> +    public HotspotSACompressedReferencesResult(int addressSize, int
>> objectAlignment, int refSize,
>> +            boolean compressedRefsEnabled, long narrowBase, int
>> narrowShift) {
>> +        this.addressSize = addressSize;
>> +        this.objectAlignment = objectAlignment;
>> +        this.oopSize = refSize;
>> +        this.compressedOopsEnabled = compressedRefsEnabled;
>> +        this.narrowOopBase = narrowBase;
>> +        this.narrowOopShift = narrowShift;
>> +        this.klassPtrSize = refSize;
>> +        this.compressedKlassPointersEnabled = compressedRefsEnabled;
>> +        this.narrowKlassBase = narrowBase;
>> +        this.narrowKlassShift = narrowShift;
>> +    }
>> +
>> +    public HotspotSACompressedReferencesResult(int addressSize, int
>> objectAlignment, int oopSize, boolean compressedOopsEnabled,
>> +            long narrowOopBase, int narrowOopShift, int klassPtrSize,
>> boolean compressedKlassPointersEnabled,
>> +            long narrowKlassBase, int narrowKlassShift) {
>> +        this.addressSize = addressSize;
>> +        this.objectAlignment = objectAlignment;
>> +        this.oopSize = oopSize;
>> +        this.compressedOopsEnabled = compressedOopsEnabled;
>> +        this.narrowOopBase = narrowOopBase;
>> +        this.narrowOopShift = narrowOopShift;
>> +        this.klassPtrSize = klassPtrSize;
>> +        this.compressedKlassPointersEnabled =
>> compressedKlassPointersEnabled;
>> +        this.narrowKlassBase = narrowKlassBase;
>> +        this.narrowKlassShift = narrowKlassShift;
>> +    }
>> +
>> +    public int getAddressSize() {
>> +        return addressSize;
>> +    }
>> +
>> +    public void setAddressSize(int addressSize) {
>> +        this.addressSize = addressSize;
>> +    }
>> +
>> +    public int getObjectAlignment() {
>> +        return objectAlignment;
>> +    }
>> +
>> +    public void setObjectAlignment(int objectAlignment) {
>> +        this.objectAlignment = objectAlignment;
>> +    }
>> +
>> +    public int getOopSize() {
>> +        return oopSize;
>> +    }
>> +
>> +    public void setOopSize(int oopSize) {
>> +        this.oopSize = oopSize;
>> +    }
>> +
>> +    public boolean isCompressedOopsEnabled() {
>> +        return compressedOopsEnabled;
>> +    }
>> +
>> +    public void setCompressedOopsEnabled(boolean compressedOopsEnabled) {
>> +        this.compressedOopsEnabled = compressedOopsEnabled;
>> +    }
>> +
>> +    public long getNarrowOopBase() {
>> +        return narrowOopBase;
>> +    }
>> +
>> +    public void setNarrowOopBase(long narrowOopBase) {
>> +        this.narrowOopBase = narrowOopBase;
>> +    }
>> +
>> +    public int getNarrowOopShift() {
>> +        return narrowOopShift;
>> +    }
>> +
>> +    public void setNarrowOopShift(int narrowOopShift) {
>> +        this.narrowOopShift = narrowOopShift;
>> +    }
>> +
>> +    public int getKlassPtrSize() {
>> +        return klassPtrSize;
>> +    }
>> +
>> +    public void setKlassPtrSize(int klassPtrSize) {
>> +        this.klassPtrSize = klassPtrSize;
>> +    }
>> +
>> +    public boolean isCompressedKlassPointersEnabled() {
>> +        return compressedKlassPointersEnabled;
>> +    }
>> +
>> +    public void setCompressedKlassPointersEnabled(boolean
>> compressedKlassPointersEnabled) {
>> +        this.compressedKlassPointersEnabled =
>> compressedKlassPointersEnabled;
>> +    }
>> +
>> +    public long getNarrowKlassBase() {
>> +        return narrowKlassBase;
>> +    }
>> +
>> +    public void setNarrowKlassBase(long narrowKlassBase) {
>> +        this.narrowKlassBase = narrowKlassBase;
>> +    }
>> +
>> +    public int getNarrowKlassShift() {
>> +        return narrowKlassShift;
>> +    }
>> +
>> +    public void setNarrowKlassShift(int narrowKlassShift) {
>> +        this.narrowKlassShift = narrowKlassShift;
>> +    }
>> +
>> +    @Override
>> +    public String toString() {
>> +        return "HotspotSACompressedOopsResult [" +
>> +                    "addressSize=" + addressSize + ", " +
>> +                    "objectAlignment=" + objectAlignment + ", " +
>> +                    "oopSize=" + oopSize + ", " +
>> +                    "compressedOopsEnabled=" + compressedOopsEnabled + ", "
>> +
>> +                    "narrowOopBase=" + "0x" +
>> +                        String.format("%" + (addressSize * 2) + "s",
>> Long.toHexString(narrowOopBase).toUpperCase()).replace(' ', '0') +  ", " +
>> +                    "narrowOopShift=" + narrowOopShift +  ", " +
>> +                    "klassPtrSize=" + klassPtrSize +  ", " +
>> +                    "compressedKlassPointersEnabled=" +
>> compressedKlassPointersEnabled + ", " +
>> +                    "narrowKlassBase=" + "0x" +
>> +                        String.format("%" + (addressSize * 2) + "s",
>> Long.toHexString(narrowKlassBase).toUpperCase()).replace(' ', '0') +  ", " +
>> +                    "narrowKlassShift=" + narrowKlassShift + "]";
>> +    }
>> +
>> +}
>>
>> ...
>>
>> [Message clipped]
>>     
>
>
>   



More information about the jol-dev mailing list