From volker.simonis at gmail.com Fri Jan 2 16:32:09 2015 From: volker.simonis at gmail.com (Volker Simonis) Date: Fri, 2 Jan 2015 17:32:09 +0100 Subject: Improve the creation of instance objects Message-ID: Hi Alexey, thanks for creating the JOL-tools - they are really nice. I've played around with them and I want to propose the following small patch which improves the creation of instance objects. Currently you are using Class.newInstane() but this will fail if the default constructor is not accessible. I'd like to propose the usage of Class.getDeclaredConstructor() to get the default constructor. If it is not accessible we can set it to 'true' with ctor.setAccessible(true). Afterwards we can simply call ctor.newInstance(). What do you think? With these small changes I could get some better results when calling MainObject{Internals, Externals, Footprint} on some classes which only had private constructors. S novem godom, Volker -------------- next part -------------- A non-text attachment was scrubbed... Name: jol.patch Type: text/x-patch Size: 3191 bytes Desc: not available URL: From serkanozal86 at hotmail.com Sun Jan 4 14:24:08 2015 From: serkanozal86 at hotmail.com (=?ISO-8859-9?Q?Serkan_=D6ZAL?=) Date: Sun, 4 Jan 2015 16:24:08 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation Message-ID: 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 . 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. 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 -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: hotspot_sa_support_and_compressed-refs_impl.patch URL: From volker.simonis at gmail.com Mon Jan 5 09:37:24 2015 From: volker.simonis at gmail.com (Volker Simonis) Date: Mon, 5 Jan 2015 10:37:24 +0100 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: Message-ID: On Sun, Jan 4, 2015 at 3:24 PM, Serkan ?ZAL 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 . > 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 "sudo" command (also with password) > to "/etc/sudoers" file. > + * > + * For more information about "sudo", 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 /../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 /../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 true if "sudo" command is required, > otherwise false > + */ > + 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 HotspotServiceabilityAgentProcessor> > + R executeOnHotspotSAInternal(P processor, int > timeoutInMsecs) { > + checkEnable(); > + > + // Generate required arguments to create an external Java > process > + List args = new ArrayList(); > + 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

request = > + new HotspotServiceabilityAgentRequest

(processId, > processor, timeoutInMsecs); > + AgentConnectionHandlerThread agentConnectionHandlerThread > = > + new AgentConnectionHandlerThread(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 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 > createInstance(Class

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 the type of {@link HotspotServiceabilityAgentResult} > + * @param

the type of {@link HotspotServiceabilityAgentProcessor} > + */ > + private static class AgentConnectionHandlerThread HotspotServiceabilityAgentResult, P extends > HotspotServiceabilityAgentProcessor> > + extends Thread { > + > + private Process agentProcess; > + private HotspotServiceabilityAgentRequest

request; > + private HotspotServiceabilityAgentResponse response; > + private ObjectInputStream in; > + private ObjectOutputStream out; > + private volatile boolean finished; > + > + private AgentConnectionHandlerThread(Process agentProcess, > HotspotServiceabilityAgentRequest

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) > 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 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

the type of {@link > HotspotServiceabilityAgentProcessor} > + */ > + @SuppressWarnings("serial") > + private static class HotspotServiceabilityAgentRequest

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 the type of {@link HotspotServiceabilityAgentResult} > + */ > + @SuppressWarnings("serial") > + private static class HotspotServiceabilityAgentResponse 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 HotspotServiceabilityAgentProcessor> void main(final String[] args) { > + final HotspotServiceabilityAgentResponse 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

request = > (HotspotServiceabilityAgentRequest

) 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 true if Hotspot Serviceability Agent support > is enable, otherwise false. > + * > + * @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 the type of {@link HotspotServiceabilityAgentResult} > + * @param

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 HotspotServiceabilityAgentProcessor> > + R executeOnHotspotSA(Class

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 the type of {@link HotspotServiceabilityAgentResult} > + * @param

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 HotspotServiceabilityAgentProcessor> > + 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 the type of {@link HotspotServiceabilityAgentResult} > + * @param

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 HotspotServiceabilityAgentProcessor> > + R executeOnHotspotSA(Class

processorClass, int > timeoutInMsecs) { > + return executeOnHotspotSA(createInstance(processorClass), > timeoutInMsecs); > + } > + > + /** > + * Executes given {@link HotspotServiceabilityAgentProcessor} on > Hotspot agent process and returns > + * {@link HotspotServiceabilityAgentResult} instance as result. > + * > + * @param the type of {@link HotspotServiceabilityAgentResult} > + * @param

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 HotspotServiceabilityAgentProcessor> > + 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 hotspotAgent 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 vm 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 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 { > + > + @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] From serkanozal86 at hotmail.com Tue Jan 6 11:06:05 2015 From: serkanozal86 at hotmail.com (=?ISO-8859-9?Q?Serkan_=D6ZAL?=) Date: Tue, 6 Jan 2015 13:06:05 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54A94D08.5040808@hotmail.com> References: <54A94D08.5040808@hotmail.com> Message-ID: Hi Aleksey, Any comments/reviews on this patch ? Regards. -- Serkan ?ZAL > 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 . > 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. > > 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 From serkanozal86 at hotmail.com Tue Jan 6 11:15:10 2015 From: serkanozal86 at hotmail.com (=?UTF-8?B?U2Vya2FuIMOWWkFM?=) Date: Tue, 6 Jan 2015 13:15:10 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: Message-ID: 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 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 . >> 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 "sudo" command (also with password) >> to "/etc/sudoers" file. >> + * >> + * For more information about "sudo", 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 /../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 /../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 true if "sudo" command is required, >> otherwise false >> + */ >> + 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 > HotspotServiceabilityAgentProcessor> >> + R executeOnHotspotSAInternal(P processor, int >> timeoutInMsecs) { >> + checkEnable(); >> + >> + // Generate required arguments to create an external Java >> process >> + List args = new ArrayList(); >> + 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

request = >> + new HotspotServiceabilityAgentRequest

(processId, >> processor, timeoutInMsecs); >> + AgentConnectionHandlerThread agentConnectionHandlerThread >> = >> + new AgentConnectionHandlerThread(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 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 >> createInstance(Class

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 the type of {@link HotspotServiceabilityAgentResult} >> + * @param

the type of {@link HotspotServiceabilityAgentProcessor} >> + */ >> + private static class AgentConnectionHandlerThread> HotspotServiceabilityAgentResult, P extends >> HotspotServiceabilityAgentProcessor> >> + extends Thread { >> + >> + private Process agentProcess; >> + private HotspotServiceabilityAgentRequest

request; >> + private HotspotServiceabilityAgentResponse response; >> + private ObjectInputStream in; >> + private ObjectOutputStream out; >> + private volatile boolean finished; >> + >> + private AgentConnectionHandlerThread(Process agentProcess, >> HotspotServiceabilityAgentRequest

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) >> 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 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

the type of {@link >> HotspotServiceabilityAgentProcessor} >> + */ >> + @SuppressWarnings("serial") >> + private static class HotspotServiceabilityAgentRequest

> 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 the type of {@link HotspotServiceabilityAgentResult} >> + */ >> + @SuppressWarnings("serial") >> + private static class HotspotServiceabilityAgentResponse> 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 > HotspotServiceabilityAgentProcessor> void main(final String[] args) { >> + final HotspotServiceabilityAgentResponse 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

request = >> (HotspotServiceabilityAgentRequest

) 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 true if Hotspot Serviceability Agent support >> is enable, otherwise false. >> + * >> + * @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 the type of {@link HotspotServiceabilityAgentResult} >> + * @param

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 > HotspotServiceabilityAgentProcessor> >> + R executeOnHotspotSA(Class

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 the type of {@link HotspotServiceabilityAgentResult} >> + * @param

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 > HotspotServiceabilityAgentProcessor> >> + 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 the type of {@link HotspotServiceabilityAgentResult} >> + * @param

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 > HotspotServiceabilityAgentProcessor> >> + R executeOnHotspotSA(Class

processorClass, int >> timeoutInMsecs) { >> + return executeOnHotspotSA(createInstance(processorClass), >> timeoutInMsecs); >> + } >> + >> + /** >> + * Executes given {@link HotspotServiceabilityAgentProcessor} on >> Hotspot agent process and returns >> + * {@link HotspotServiceabilityAgentResult} instance as result. >> + * >> + * @param the type of {@link HotspotServiceabilityAgentResult} >> + * @param

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 > HotspotServiceabilityAgentProcessor> >> + 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 hotspotAgent 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 vm 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> 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 { >> + >> + @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] >> > > > From aleksey.shipilev at oracle.com Tue Jan 6 15:39:26 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 06 Jan 2015 18:39:26 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> Message-ID: <54AC01AE.9010800@oracle.com> Hi Serkan, On 01/06/2015 02:06 PM, Serkan ?ZAL wrote: > Any comments/reviews on this patch ? Holidays here, so I trying to disconnect a bit. Skimmed briefly through the patch, it looks very promising. Please make the formatting consistent: 4-space tabulation. Thanks, -Aleksey. From serkanozal86 at hotmail.com Tue Jan 6 16:27:14 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Tue, 6 Jan 2015 18:27:14 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54AC01AE.9010800@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> Message-ID: Hi Aleksey, Sorry for distrubing you on your holiday. I have just reformated the code as 4-space instead of tabs and added the second version of the updated patch to this mail. There are too many feature can be added to JOL after Hotspot SA support since Hotspot SA has many hidden gems :) Have a nice holiday. Regards. -- Serkan ?ZAL > Hi Serkan, > > On 01/06/2015 02:06 PM, Serkan ?ZAL wrote: > >> Any comments/reviews on this patch ? >> > > Holidays here, so I trying to disconnect a bit. Skimmed briefly through > the patch, it looks very promising. Please make the formatting > consistent: 4-space tabulation. > > Thanks, > -Aleksey. > > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: hotspot_sa_support_and_compressed-refs_impl_v2.patch URL: From aleksey.shipilev at oracle.com Mon Jan 12 13:47:36 2015 From: aleksey.shipilev at oracle.com (aleksey.shipilev at oracle.com) Date: Mon, 12 Jan 2015 13:47:36 +0000 Subject: hg: code-tools/jol: 7901238: Improve the creation of instance objects Message-ID: <201501121347.t0CDlaiM027322@aojmv0008> Changeset: 2f3be1f10b0c Author: shade Date: 2015-01-12 16:47 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/2f3be1f10b0c 7901238: Improve the creation of instance objects Contributed-by: Volker Simonis ! jol-cli/src/main/java/org/openjdk/jol/MainObjectExternals.java ! jol-cli/src/main/java/org/openjdk/jol/MainObjectFootprint.java ! jol-cli/src/main/java/org/openjdk/jol/MainObjectInternals.java From aleksey.shipilev at oracle.com Mon Jan 12 13:49:00 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 12 Jan 2015 16:49:00 +0300 Subject: Improve the creation of instance objects In-Reply-To: References: Message-ID: <54B3D0CC.30706@oracle.com> Hi Volker, On 01/02/2015 07:32 PM, Volker Simonis wrote: > What do you think? With these small changes I could get some better > results when calling MainObject{Internals, Externals, Footprint} on > some classes which only had private constructors. Good idea, submitted: https://bugs.openjdk.java.net/browse/CODETOOLS-7901238 Fixed with: http://hg.openjdk.java.net/code-tools/jol/rev/2f3be1f10b0c (Note you have to also catch NoSuchMethodException to properly fallback to class-only introspection) Thanks, -Aleksey. From aleksey.shipilev at oracle.com Mon Jan 12 15:07:04 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 12 Jan 2015 18:07:04 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> Message-ID: <54B3E318.6040607@oracle.com> Hi again, On 01/06/2015 07:27 PM, Serkan ?ZAL wrote: > I have just reformated the code as 4-space instead of tabs and added the > second version of the updated patch to this mail. I think the approach is very sound, but the implementation seems to be overblown without a compelling reason to do so. Pro-tip: do not try to write the broadly generic code until you see the need for it. General things: * Try to build the project with JDK 8. Javadoc will complain a lot about the misuse of @link tags. * I think class names may be shorter: HS_SA_* is a reasonable shortcut. * I think the excess genericity is redundant at this point, and constitutes over-engineering. Inheritance, covariance, and some typechecks should work all right in these scenarios. Especially given that you can't enforce type safety across JVMs anyway. HotspotSA*: * Is there a way to try and attach without super-user privileges first, and the fall-back to "sudo" on failure? Asking for user password interactively is asking for trouble, especially for library users. Therefore, we are better off trying to attach automatically, and ask for the password if that fails *and* some user property is set. * Why do you need the additional AgentConnectionHandlerThread to deal with SA? Is this only to handle the timeouts? If so, you might as well ditch the additional thread, and timeout on Process.waitFor. * The tidbit with forking Java processes is that you need to consume both stdout/stderr, otherwise you may block indefinitely. This probably means you need to start Process, attach stdout+stderr scrubbers, waitFor process, and then process the results accumulated by scrubbers. See e.g. how JMH does it: http://hg.openjdk.java.net/code-tools/jmh/file/2053f4bab01b/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java#l692 * HotspotServiceabilityAgentRequest and HotspotServiceabilityAgentResponse have unused constructors? I think the lifecycle for at least the response is wrong. Instead of having setResult/setError, use the constructors, and make the fields final. * HotspotSACompressedReferencesResult -- why setters even exist? Fields should be final. toString() is the useless auto-generated stub? * What is the actual use for HotspotSAContext? I don't see it is used anywhere, except for a few declarations. It should be immutable as well anyhow. * osName.indexOf(...) >= 0 should be osName.contains(...) VMSupport: * Bug: formatAddressAsHexByAddressSize(long address) argument is unused * Naming: OOP_SIZE vs KLASS_PTR_SIZE. Should be KLASS_OOP_SIZE? * I fail to understand these comments: " // For backward compatibility, OOP compressed reference mode can be used as default compressed reference mode". Maybe you should provide a paragraph explaining what's going on? Thanks, -Aleksey From aleksey.shipilev at oracle.com Mon Jan 12 16:27:18 2015 From: aleksey.shipilev at oracle.com (aleksey.shipilev at oracle.com) Date: Mon, 12 Jan 2015 16:27:18 +0000 Subject: hg: code-tools/jol: Update copyright header templates to 2015. Message-ID: <201501121627.t0CGRI3w004082@aojmv0008> Changeset: 09841c3e171b Author: shade Date: 2015-01-12 19:27 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/09841c3e171b Update copyright header templates to 2015. ! src/license/bsd/header.txt ! src/license/gpl_cpe/header.txt From serkanozal86 at hotmail.com Mon Jan 12 17:03:28 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Mon, 12 Jan 2015 19:03:28 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B3E318.6040607@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> Message-ID: Inline. > Hi again, > > On 01/06/2015 07:27 PM, Serkan ?ZAL wrote: > >> I have just reformated the code as 4-space instead of tabs and added the >> second version of the updated patch to this mail. >> > > I think the approach is very sound, but the implementation seems to be > overblown without a compelling reason to do so. Pro-tip: do not try to > write the broadly generic code until you see the need for it. > > General things: > Thanks, I will fix all of the issues as soon as possible and will send new patch. > * Try to build the project with JDK 8. Javadoc will complain a lot > about the misuse of @link tags. > OK. Fixed > * I think class names may be shorter: HS_SA_* is a reasonable shortcut. > OK. Classs names has been updated as HS_SA_* > * I think the excess genericity is redundant at this point, and > constitutes over-engineering. Inheritance, covariance, and some > typechecks should work all right in these scenarios. Especially given > that you can't enforce type safety across JVMs anyway. > Even though, I generally prefer generic types :), I removed all of them from patch. So there is no generic type as you suggested. > HotspotSA*: > > * Is there a way to try and attach without super-user privileges first, > and the fall-back to "sudo" on failure? Asking for user password > interactively is asking for trouble, especially for library users. > Therefore, we are better off trying to attach automatically, and ask for > the password if that fails *and* some user property is set. > OK. I will work on getting password interactively. In addition, what about getting password also as VM argument ? WDYT ? > * Why do you need the additional AgentConnectionHandlerThread to deal > with SA? Is this only to handle the timeouts? If so, you might as well > ditch the additional thread, and timeout on Process.waitFor. > Right, I have thought again and understood that "AgentConnectionHandlerThread" is not necessary for only timeout handling. Just removed it and wait process to terminate with "waitFor" method. > * The tidbit with forking Java processes is that you need to consume > both stdout/stderr, otherwise you may block indefinitely. This probably > means you need to start Process, attach stdout+stderr scrubbers, waitFor > process, and then process the results accumulated by scrubbers. See e.g. > how JMH does it: > http://hg.openjdk.java.net/code-tools/jmh/file/2053f4bab01b/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java#l692 > Right. Also error stream has been drained if there is something to read as your suggested order. > * HotspotServiceabilityAgentRequest and > HotspotServiceabilityAgentResponse have unused constructors? I think the > lifecycle for at least the response is wrong. Instead of having > setResult/setError, use the constructors, and make the fields final. > OK. Setters have been removed and fields are now final. > * HotspotSACompressedReferencesResult -- why setters even exist? Fields > should be final. toString() is the useless auto-generated stub? > OK. Setters have been removed, fields are now final and "toString" method has been removed. > * What is the actual use for HotspotSAContext? I don't see it is used > anywhere, except for a few declarations. It should be immutable as well > "HotspotSAContext" is wrapper class to hold common necessary objects for Hotspot Serviceability Agent API Usage. It is passed to HS_SA_Processor's "process" 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. OK. I made it immutable. > anyhow. > > * osName.indexOf(...) >= 0 should be osName.contains(...) > OK. Refactored. > > VMSupport: > > * Bug: formatAddressAsHexByAddressSize(long address) argument is unused > OK. Good catch. Fixed as using "address" argument. > * Naming: OOP_SIZE vs KLASS_PTR_SIZE. Should be KLASS_OOP_SIZE? > "KLASS_PTR" term comes from Hotspot SA codes, not my choice. So should I update as "KLASS_OOP_SIZE" ? > * I fail to understand these comments: " // For backward compatibility, > OOP compressed reference mode can be used as default compressed > reference mode". Maybe you should provide a paragraph explaining what's > going on? > I mean that, there is two different compressed references (OOP and Klass) information since Java 8. For Java 6 and 7, there is only one (OOP) and this one is used both OOP and Klass. So I assume compressed-oop information as compressed-reference information for users of "USE_COMPRESSED_REFS" and "COMPRESSED_REF_SHIFT" properties. I hope this time it is more clear :) > Thanks, > -Aleksey > > > Regards. -- Serkan ?ZAL From aleksey.shipilev at oracle.com Mon Jan 12 17:12:17 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 12 Jan 2015 20:12:17 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> Message-ID: <54B40071.5090008@oracle.com> On 01/12/2015 08:03 PM, Serkan ?ZAL wrote: >> On 01/06/2015 07:27 PM, Serkan ?ZAL wrote: >> General things: >> > Thanks, I will fix all of the issues as soon as possible and will send > new patch. Cool. I was so into reviewing the patch, and I forgot to say thank you for this work. It sure one of the major improvements to JOL. >> * Is there a way to try and attach without super-user privileges first, >> and the fall-back to "sudo" on failure? Asking for user password >> interactively is asking for trouble, especially for library users. >> Therefore, we are better off trying to attach automatically, and ask for >> the password if that fails *and* some user property is set. >> > OK. I will work on getting password interactively. In addition, what > about getting password also as VM argument ? WDYT ? No, sorry, do not get passwords interactively. What I meant was this. Try to attach without superuser privileges. If it fails, print the warning message, check the user property (e.g. "jol.tryWithSudo"), and try the same command with "sudo". Let sudo do the interactive part. The point is to have completely non-interactive thing in the default mode. If users accept to get the interactive sudo (as communicated by the property), then do all the madness. > "HotspotSAContext" is wrapper class to hold common necessary objects for > Hotspot Serviceability Agent API Usage. > It is passed to HS_SA_Processor's "process" 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. Okay. Would it be simpler to drop now, and re-add later if actually needed (which may never happen)? Unused code contributes to cruft. >> * Naming: OOP_SIZE vs KLASS_PTR_SIZE. Should be KLASS_OOP_SIZE? >> > "KLASS_PTR" term comes from Hotspot SA codes, not my choice. So should I > update as "KLASS_OOP_SIZE" ? Yes, let it be KLASS_OOP_SIZE. >> * I fail to understand these comments: " // For backward compatibility, >> OOP compressed reference mode can be used as default compressed >> reference mode". Maybe you should provide a paragraph explaining what's >> going on? >> > I mean that, there is two different compressed references (OOP and > Klass) information since Java 8. For Java 6 and 7, there is only one > (OOP) and this one is used both OOP and Klass. > So I assume compressed-oop information as compressed-reference > information for users of "USE_COMPRESSED_REFS" and > "COMPRESSED_REF_SHIFT" properties. > I hope this time it is more clear :) Okay, you need to spell this out in comment block. Thanks, -Aleksey. From serkanozal86 at hotmail.com Mon Jan 12 19:05:02 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Mon, 12 Jan 2015 21:05:02 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B40071.5090008@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> Message-ID: Hi Aleksey, > On 01/12/2015 08:03 PM, Serkan ?ZAL wrote: > >>> On 01/06/2015 07:27 PM, Serkan ?ZAL wrote: >>> General things: >>> >>> >> Thanks, I will fix all of the issues as soon as possible and will send >> new patch. >> > > Cool. I was so into reviewing the patch, and I forgot to say thank you > for this work. It sure one of the major improvements to JOL. > You are welcome. No problem :) > >>> * Is there a way to try and attach without super-user privileges first, >>> and the fall-back to "sudo" on failure? Asking for user password >>> interactively is asking for trouble, especially for library users. >>> Therefore, we are better off trying to attach automatically, and ask for >>> the password if that fails *and* some user property is set. >>> >>> >> OK. I will work on getting password interactively. In addition, what >> about getting password also as VM argument ? WDYT ? >> > > No, sorry, do not get passwords interactively. > > What I meant was this. Try to attach without superuser privileges. If it > fails, print the warning message, check the user property (e.g. > "jol.tryWithSudo"), and try the same command with "sudo". Let sudo do > the interactive part. > > The point is to have completely non-interactive thing in the default > mode. If users accept to get the interactive sudo (as communicated by > the property), then do all the madness. > OK. But I couldn't manage this ("Let sudo do the interactive part") inside Java code. When I use "sudo -S java ....", it waits for an input but when I enter password and hit the enter, no action is taken. Still waits. The only way I could pass sudo is that get password from standard input and pass it to "echo | sudo -S ls" command and then run java with just "sudo". WDYT ? > >> "HotspotSAContext" is wrapper class to hold common necessary objects for >> Hotspot Serviceability Agent API Usage. >> It is passed to HS_SA_Processor's "process" 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. >> > > Okay. Would it be simpler to drop now, and re-add later if actually > needed (which may never happen)? Unused code contributes to cruft. > OK. I changed "Serializable process(HS_SA_Context context);" method signature to "Serializable process(Object hotspotAgent, Object vm);" and removed "HS_SA_Context". > >>> * Naming: OOP_SIZE vs KLASS_PTR_SIZE. Should be KLASS_OOP_SIZE? >>> >>> >> "KLASS_PTR" term comes from Hotspot SA codes, not my choice. So should I >> update as "KLASS_OOP_SIZE" ? >> > > Yes, let it be KLASS_OOP_SIZE. > OK. Updated "KLASS_PTR_SIZE" as "KLASS_OOP_SIZE". > >>> * I fail to understand these comments: " // For backward compatibility, >>> OOP compressed reference mode can be used as default compressed >>> reference mode". Maybe you should provide a paragraph explaining what's >>> going on? >>> >>> >> I mean that, there is two different compressed references (OOP and >> Klass) information since Java 8. For Java 6 and 7, there is only one >> (OOP) and this one is used both OOP and Klass. >> So I assume compressed-oop information as compressed-reference >> information for users of "USE_COMPRESSED_REFS" and >> "COMPRESSED_REF_SHIFT" properties. >> I hope this time it is more clear :) >> > > Okay, you need to spell this out in comment block. > OK. Will add a comment paragraph for better explanation. > Thanks, > -Aleksey. > > Regards. -- Serkan ?ZAL From aleksey.shipilev at oracle.com Mon Jan 12 19:22:06 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 12 Jan 2015 22:22:06 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> Message-ID: <54B41EDE.6040005@oracle.com> On 01/12/2015 10:05 PM, Serkan ?ZAL wrote: > OK. But I couldn't manage this ("Let sudo do the interactive part") > inside Java code. > When I use "sudo -S java ....", it waits for an input but when I enter > password and hit the enter, no action is taken. Still waits. > The only way I could pass sudo is that get password from standard input > and pass it to "echo | sudo -S ls" command and then run java > with just "sudo". > WDYT ? I think asking users for their password is just plain wrong. I would immediately Ctrl+C. I am confused now. Your current patch does the sudo part without any problems, right? It worked for me anyhow. Keep it that way. What I want is the *additional* step before that, that is, trying to attach without sudo. If that step fails, go for sudo only then, if user declares the intent with a property. In other words, do the attach twice: first time without superuser privileges, and second time with superuser privileges, if needed. This has a nice flow: the default mode will try to do as much non-interactively; if user wants to go further and provide JOL with superuser privileges, then (s)he can do that as well. >>> "HotspotSAContext" is wrapper class to hold common necessary objects for >>> Hotspot Serviceability Agent API Usage. >>> It is passed to HS_SA_Processor's "process" 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. >>> >> >> Okay. Would it be simpler to drop now, and re-add later if actually >> needed (which may never happen)? Unused code contributes to cruft. >> > OK. I changed "Serializable process(HS_SA_Context context);" method > signature to "Serializable process(Object hotspotAgent, Object vm);" and > removed "HS_SA_Context". Wait, do you actually use hotspotAgent and vm in your code? I don't see any field of HS_SA_Context used anywhere. Thanks, -Aleksey. From serkanozal86 at hotmail.com Mon Jan 12 19:38:36 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Mon, 12 Jan 2015 21:38:36 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B41EDE.6040005@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> Message-ID: > On 01/12/2015 10:05 PM, Serkan ?ZAL wrote: > >> OK. But I couldn't manage this ("Let sudo do the interactive part") >> inside Java code. >> When I use "sudo -S java ....", it waits for an input but when I enter >> password and hit the enter, no action is taken. Still waits. >> The only way I could pass sudo is that get password from standard input >> and pass it to "echo | sudo -S ls" command and then run java >> with just "sudo". >> WDYT ? >> > > I think asking users for their password is just plain wrong. I would > immediately Ctrl+C. > > I am confused now. Your current patch does the sudo part without any > problems, right? It worked for me anyhow. Keep it that way. > > What I want is the *additional* step before that, that is, trying to > attach without sudo. If that step fails, go for sudo only then, if user > declares the intent with a property. In other words, do the attach > twice: first time without superuser privileges, and second time with > superuser privileges, if needed. > > This has a nice flow: the default mode will try to do as much > non-interactively; if user wants to go further and provide JOL with > superuser privileges, then (s)he can do that as well. > I was saying that executing a Hotspot agent process just like this "sudo java -cp ..." is not enough for giving the responsibility of taking password from user to "sudo" command (or I couldn't manage it :)). It doesn't wait for an input from user and just says "no tty or askpass program specified" and fails. OK. I will run same code twice without "sudo" and with "sudo". If the first one fails, will try with "sudo". So in this case, should I look at the property "jol.tryWithSudo" for second try ? > >>>> "HotspotSAContext" is wrapper class to hold common necessary objects for >>>> Hotspot Serviceability Agent API Usage. >>>> It is passed to HS_SA_Processor's "process" 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. >>>> >>>> >>> Okay. Would it be simpler to drop now, and re-add later if actually >>> needed (which may never happen)? Unused code contributes to cruft. >>> >>> >> OK. I changed "Serializable process(HS_SA_Context context);" method >> signature to "Serializable process(Object hotspotAgent, Object vm);" and >> removed "HS_SA_Context". >> > > Wait, do you actually use hotspotAgent and vm in your code? I don't see > any field of HS_SA_Context used anywhere. > Looked again and "hotspotAgent" argument is not used currently. "vm" argument is taken by "HS_SA_Util.getVMInstance()" in "HS_SA_CompressedReferencesProcessor" but also can be used from argument. So maybe I should remove all of these arguments. WDYT ? > Thanks, > -Aleksey. > > > Regards. -- Serkan ?ZAL From aleksey.shipilev at oracle.com Mon Jan 12 20:06:06 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Mon, 12 Jan 2015 23:06:06 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> Message-ID: <54B4292E.70904@oracle.com> On 12.01.2015 22:38, Serkan ?ZAL wrote: > OK. I will run same code twice without "sudo" and with "sudo". If the > first one fails, will try with "sudo". > So in this case, should I look at the property "jol.tryWithSudo" for > second try ? Yes, and jol.tryWithSudo should be "false" by default. > Looked again and "hotspotAgent" argument is not used currently. "vm" > argument is taken by "HS_SA_Util.getVMInstance()" in > "HS_SA_CompressedReferencesProcessor" but also can be used from argument. > So maybe I should remove all of these arguments. WDYT ? Yes, that's my point, remove them completely. It is easier to introduce this back than to actually maintain the dead code. Thanks, -Aleksey. From serkanozal86 at hotmail.com Mon Jan 12 20:10:49 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Mon, 12 Jan 2015 22:10:49 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B4292E.70904@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> Message-ID: > On 12.01.2015 22:38, Serkan ?ZAL wrote: > >> OK. I will run same code twice without "sudo" and with "sudo". If the >> first one fails, will try with "sudo". >> So in this case, should I look at the property "jol.tryWithSudo" for >> second try ? >> > > Yes, and jol.tryWithSudo should be "false" by default. > > >> Looked again and "hotspotAgent" argument is not used currently. "vm" >> argument is taken by "HS_SA_Util.getVMInstance()" in >> "HS_SA_CompressedReferencesProcessor" but also can be used from argument. >> So maybe I should remove all of these arguments. WDYT ? >> > > Yes, that's my point, remove them completely. It is easier to introduce > this back than to actually maintain the dead code. > > Thanks, > -Aleksey. > > Ok, Thanks. Let me update the patch. Regards. -- Serkan ?ZAL From serkanozal86 at hotmail.com Mon Jan 12 21:55:35 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Mon, 12 Jan 2015 23:55:35 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> Message-ID: Hi Aleksey, I have just updated my patch as your suggestions. I hope it is OK. Waiting for your feedbacks. 3rd (latest) version of patch is attached to mail. Note: While testing the patch, to enable "sudo", you can use "jol.tryWithSudo" flag. Regards. -- Serkan ?ZAL -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: hotspot_sa_support_and_compressed-refs_impl_v3.patch URL: From serkanozal86 at hotmail.com Mon Jan 12 22:06:41 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Tue, 13 Jan 2015 00:06:41 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> Message-ID: Serkan ?ZAL yazm??: > Hi Aleksey, > > I have just updated my patch as your suggestions. I hope it is OK. > Waiting for your feedbacks. > > 3rd (latest) version of patch is attached to mail. > > Note: While testing the patch, to enable "sudo", you can use > "jol.tryWithSudo" flag. > > Regards. > > -- > > Serkan ?ZAL By the way, after this patch, I should also send a patch for sample usage of built-in Hotspot SA support to show how users can implement their custom Hotspot SA processors to do some stuff on Hotspot SA API. Regards. -- Serkan ?ZAL From aleksey.shipilev at oracle.com Tue Jan 13 09:54:54 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 13 Jan 2015 12:54:54 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> Message-ID: <54B4EB6E.4080501@oracle.com> On 01/13/2015 12:55 AM, Serkan ?ZAL wrote: > Hi Aleksey, > > I have just updated my patch as your suggestions. I hope it is OK. > Waiting for your feedbacks. > > 3rd (latest) version of patch is attached to mail. Thanks! * Still, Javadoc failures when building. * HS_SA_Support: sudo autodetection scheme is broken: you expect ProcessAttachFailedException, but getting it wrapped in RuntimeException instead. That's also why it prints "null": "Initial Hotspot SA process attach check failed (null) So skipping Hotspot SA support ..." * It would make sense to steal FileUtils.safelyClose from JMH: http://hg.openjdk.java.net/code-tools/jmh/file/d15ebde32b25/jmh-core/src/main/java/org/openjdk/jmh/util/FileUtils.java#l203 * I thought you better to return HS_SA_Result from execute* methods, not blank Serializable. Also, it may make sense to check the types before downcasting. Otherwise, it looks very good. I would need to do some deeper reading and testing of VMSupport changes before commit. Thanks, -Aleksey. From serkanozal86 at hotmail.com Tue Jan 13 16:06:18 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Tue, 13 Jan 2015 18:06:18 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B4EB6E.4080501@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> Message-ID: Hi Aleksey, > On 01/13/2015 12:55 AM, Serkan ?ZAL wrote: > >> Hi Aleksey, >> >> I have just updated my patch as your suggestions. I hope it is OK. >> Waiting for your feedbacks. >> >> 3rd (latest) version of patch is attached to mail. >> > > Thanks! > > * Still, Javadoc failures when building. > Weird, on my machine (using JDK 8), Javadoc is generated successfully just with 4 warnings about Unsafe API usage. Could you send Javadoc fail messages ? > * HS_SA_Support: sudo autodetection scheme is broken: you expect > ProcessAttachFailedException, but getting it wrapped in RuntimeException > instead. That's also why it prints "null": > "Initial Hotspot SA process attach check failed (null) So skipping > Hotspot SA support ... > Right. Fixed. > * It would make sense to steal FileUtils.safelyClose from JMH: > http://hg.openjdk.java.net/code-tools/jmh/file/d15ebde32b25/jmh-core/src/main/java/org/openjdk/jmh/util/FileUtils.java#l203 > OK. Copied the "safelyClose" methods to "HS_SA_Support" class. > * I thought you better to return HS_SA_Result from execute* methods, > not blank Serializable. Also, it may make sense to check the types > before downcasting. > In fact, I had removed them after your comments for first patch. Seems that I got you wrong :) So should I add "HS_SA_Result" (just a marker interface extends from Serializable) interface back ? WDYT ? > Otherwise, it looks very good. I would need to do some deeper reading > and testing of VMSupport changes before commit. > > Thanks, > -Aleksey. > Great. Regards. -- Serkan ?ZAL From aleksey.shipilev at oracle.com Tue Jan 13 16:10:07 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 13 Jan 2015 19:10:07 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> Message-ID: <54B5435F.1020808@oracle.com> Hi Serkan, On 01/13/2015 07:06 PM, Serkan ?ZAL wrote: >> * Still, Javadoc failures when building. >> > Weird, on my machine (using JDK 8), Javadoc is generated successfully > just with 4 warnings about Unsafe API usage. > Could you send Javadoc fail messages ? [ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.9:jar (attach-javadoc) on project jol-core: MavenReportException: Error while creating archive: [ERROR] Exit code: 1 - /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/HS_SA_Support.java:62: error: incorrect use of inline tag [ERROR] * @link http://en.wikipedia.org/wiki/Sudo [ERROR] ^ [ERROR] /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Processor.java:35: error: malformed HTML [ERROR] * Please see http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html for more details. [ERROR] ^ [ERROR] /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Processor.java:35: error: unexpected end tag: [ERROR] * Please see Serializable) interface back ? WDYT ? Yes, that's the sanest option, IMO. Thanks, -Aleksey. From serkanozal86 at hotmail.com Tue Jan 13 16:55:29 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Tue, 13 Jan 2015 18:55:29 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B5435F.1020808@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> <54B5435F.1020808@oracle.com> Message-ID: Hi Aleksey, Fixed javadoc failures and implemented results by implementing from "HS_SA_Result" So 4th version of the patch is attached to mail. Waiting for your review comments. Thanks in advance. Regards. -- Serkan ?ZAL > Hi Serkan, > > On 01/13/2015 07:06 PM, Serkan ?ZAL wrote: > >>> * Still, Javadoc failures when building. >>> >>> >> Weird, on my machine (using JDK 8), Javadoc is generated successfully >> just with 4 warnings about Unsafe API usage. >> Could you send Javadoc fail messages ? >> > > > [ERROR] Failed to execute goal > org.apache.maven.plugins:maven-javadoc-plugin:2.9:jar (attach-javadoc) > on project jol-core: MavenReportException: Error while creating archive: > [ERROR] Exit code: 1 - > /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/HS_SA_Support.java:62: > error: incorrect use of inline tag > [ERROR] * @link http://en.wikipedia.org/wiki/Sudo > [ERROR] ^ > [ERROR] > /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Processor.java:35: > error: malformed HTML > [ERROR] * Please see href="http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html>http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html > for more details. > [ERROR] ^ > [ERROR] > /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Processor.java:35: > error: bad use of '>' > [ERROR] * Please see href="http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html>http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html > for more details. > [ERROR] ^ > [ERROR] > /home/shade/projects/jol/jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Processor.java:35: > error: unexpected end tag: > [ERROR] * Please see href="http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html>http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html > for more details. > [ERROR] ^ > > >>> * I thought you better to return HS_SA_Result from execute* methods, >>> not blank Serializable. Also, it may make sense to check the types >>> before downcasting. >>> >>> >> In fact, I had removed them after your comments for first patch. Seems >> that I got you wrong :) >> So should I add "HS_SA_Result" (just a marker interface extends from >> Serializable) interface back ? WDYT ? >> > > Yes, that's the sanest option, IMO. > > Thanks, > -Aleksey. > > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: hotspot_sa_support_and_compressed-refs_impl_v4.patch URL: From aleksey.shipilev at oracle.com Tue Jan 13 20:25:35 2015 From: aleksey.shipilev at oracle.com (aleksey.shipilev at oracle.com) Date: Tue, 13 Jan 2015 20:25:35 +0000 Subject: hg: code-tools/jol: Add .hgignore. Message-ID: <201501132025.t0DKPZlY017424@aojmv0008> Changeset: e2f36a8d3c93 Author: shade Date: 2015-01-12 19:28 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/e2f36a8d3c93 Add .hgignore. + .hgignore From aleksey.shipilev at oracle.com Tue Jan 13 20:28:56 2015 From: aleksey.shipilev at oracle.com (aleksey.shipilev at oracle.com) Date: Tue, 13 Jan 2015 20:28:56 +0000 Subject: hg: code-tools/jol: 7901247: Support for Serviceability Agent Message-ID: <201501132028.t0DKSuhF018159@aojmv0008> Changeset: 8dcd6a0b9352 Author: shade Date: 2015-01-13 23:28 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/8dcd6a0b9352 7901247: Support for Serviceability Agent Contributed-by: Serkan Ozal + jol-core/src/main/java/org/openjdk/jol/util/HS_SA_Support.java ! jol-core/src/main/java/org/openjdk/jol/util/VMSupport.java + jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Processor.java + jol-core/src/main/java/org/openjdk/jol/util/sa/HS_SA_Result.java + jol-core/src/main/java/org/openjdk/jol/util/sa/impl/HS_SA_Util.java + jol-core/src/main/java/org/openjdk/jol/util/sa/impl/compressedrefs/HS_SA_CompressedReferencesProcessor.java + jol-core/src/main/java/org/openjdk/jol/util/sa/impl/compressedrefs/HS_SA_CompressedReferencesResult.java From aleksey.shipilev at oracle.com Tue Jan 13 20:31:51 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 13 Jan 2015 23:31:51 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> <54B5435F.1020808@oracle.com> Message-ID: <54B580B7.3060303@oracle.com> Hi Serkan, On 01/13/2015 07:55 PM, Serkan ?ZAL wrote: > Waiting for your review comments. No comments. I have polished the error messages a bit. Pushed: https://bugs.openjdk.java.net/browse/CODETOOLS-7901247 http://hg.openjdk.java.net/code-tools/jol/rev/8dcd6a0b9352 Thanks a lot for the contribution! -Aleksey. P.S. A true glory of this thing opens up if you try different compressed oops mode, e.g. "-XX:ObjectAlignmentInBytes=16 -Xmx2g" From serkanozal86 at hotmail.com Tue Jan 13 20:46:06 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Tue, 13 Jan 2015 22:46:06 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B580B7.3060303@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> <54B5435F.1020808@oracle.com> <54B580B7.3060303@oracle.com> Message-ID: Hi Aleksey, Great. You are welcome. After embedded built-in Hotspot SA support, there will be so many possible new feature points for JOL. I am glad about contributing to JOL. Thanks for your help and reviews. PS: Just ping me if there is another task for JOL that I can take :) Regards. -- Serkan ?ZAL > Hi Serkan, > > On 01/13/2015 07:55 PM, Serkan ?ZAL wrote: > >> Waiting for your review comments. >> > > No comments. I have polished the error messages a bit. > > Pushed: > https://bugs.openjdk.java.net/browse/CODETOOLS-7901247 > http://hg.openjdk.java.net/code-tools/jol/rev/8dcd6a0b9352 > > Thanks a lot for the contribution! > > -Aleksey. > > P.S. A true glory of this thing opens up if you try different compressed > oops mode, e.g. "-XX:ObjectAlignmentInBytes=16 -Xmx2g" > > From aleksey.shipilev at oracle.com Tue Jan 13 20:48:45 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Tue, 13 Jan 2015 23:48:45 +0300 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> <54B5435F.1020808@oracle.com> <54B580B7.3060303@oracle.com> Message-ID: <54B584AD.4000907@oracle.com> On 01/13/2015 11:46 PM, Serkan ?ZAL wrote: > After embedded built-in Hotspot SA support, there will be so many > possible new feature points for JOL. That's true. > PS: Just ping me if there is another task for JOL that I can take :) I think stabilization now takes priority. Wait for bug-reports about even the basic SA support not working properly everywhere :) Also, some refactoring is due in *Support classes, which someone (like me) should undertake at some point in the future. Thanks, -Aleksey. From serkanozal86 at hotmail.com Tue Jan 13 20:52:12 2015 From: serkanozal86 at hotmail.com (=?windows-1254?Q?Serkan_=D6ZAL?=) Date: Tue, 13 Jan 2015 22:52:12 +0200 Subject: JOL Hotspot SA Support and Compressed References Implementation In-Reply-To: <54B584AD.4000907@oracle.com> References: <54A94D08.5040808@hotmail.com> <54AC01AE.9010800@oracle.com> <54B3E318.6040607@oracle.com> <54B40071.5090008@oracle.com> <54B41EDE.6040005@oracle.com> <54B4292E.70904@oracle.com> <54B4EB6E.4080501@oracle.com> <54B5435F.1020808@oracle.com> <54B580B7.3060303@oracle.com> <54B584AD.4000907@oracle.com> Message-ID: OK. Will keep my eyes on SA support and its possible bugs :) Regards. -- Serkan ?ZAL > On 01/13/2015 11:46 PM, Serkan ?ZAL wrote: > >> After embedded built-in Hotspot SA support, there will be so many >> possible new feature points for JOL. >> > > That's true. > > >> PS: Just ping me if there is another task for JOL that I can take :) >> > > I think stabilization now takes priority. Wait for bug-reports about > even the basic SA support not working properly everywhere :) > > Also, some refactoring is due in *Support classes, which someone (like > me) should undertake at some point in the future. > > Thanks, > -Aleksey. > > From aleksey.shipilev at oracle.com Thu Jan 15 10:44:07 2015 From: aleksey.shipilev at oracle.com (aleksey.shipilev at oracle.com) Date: Thu, 15 Jan 2015 10:44:07 +0000 Subject: hg: code-tools/jol: 7901252: Single JAR for all CLI tools Message-ID: <201501151044.t0FAi7QL029240@aojmv0008> Changeset: e2b90b148915 Author: shade Date: 2015-01-15 13:43 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/e2b90b148915 7901252: Single JAR for all CLI tools ! jol-cli/pom.xml + jol-cli/src/main/java/org/openjdk/jol/Main.java - jol-cli/src/main/java/org/openjdk/jol/MainHeapDump.java - jol-cli/src/main/java/org/openjdk/jol/MainObjectEstimates.java - jol-cli/src/main/java/org/openjdk/jol/MainObjectExternals.java - jol-cli/src/main/java/org/openjdk/jol/MainObjectFootprint.java - jol-cli/src/main/java/org/openjdk/jol/MainObjectIdealPacking.java - jol-cli/src/main/java/org/openjdk/jol/MainObjectInternals.java - jol-cli/src/main/java/org/openjdk/jol/MainStringCompress.java + jol-cli/src/main/java/org/openjdk/jol/Operation.java + jol-cli/src/main/java/org/openjdk/jol/operations/HeapDump.java + jol-cli/src/main/java/org/openjdk/jol/operations/ObjectEstimates.java + jol-cli/src/main/java/org/openjdk/jol/operations/ObjectExternals.java + jol-cli/src/main/java/org/openjdk/jol/operations/ObjectFootprint.java + jol-cli/src/main/java/org/openjdk/jol/operations/ObjectIdealPacking.java + jol-cli/src/main/java/org/openjdk/jol/operations/ObjectInternals.java + jol-cli/src/main/java/org/openjdk/jol/operations/StringCompress.java From aleksey.shipilev at oracle.com Thu Jan 15 17:10:15 2015 From: aleksey.shipilev at oracle.com (Aleksey Shipilev) Date: Thu, 15 Jan 2015 20:10:15 +0300 Subject: JOL 0.3 Message-ID: <54B7F477.2070300@oracle.com> Hi, JOL 0.3 is released and available at Maven Central (thanks to Evgeny Mandrikov, as always!). This is a maintenance release, and it includes a few experimental features. Please give them a try, and report your experience back. Summary of changes: * JOL now has an experimental HotSpot Serviceability Agent (SA) support. At this point, we use SA to figure out the actual compressed references information from the running VM. This is much more accurate than guessing the compressed references base and shift, especially in non-trivial compressed references modes. SA support can be skipped with "-Djol.skipHotspotSAInit=true". Thanks goes to Serkan Ozal for this contribution: https://bugs.openjdk.java.net/browse/CODETOOLS-7901247 * JOL now tries to self-attach the Java Agent to get the Instrumentation API without forcing user to start the VM with -javaagent. This dynamic behavior can be disabled with "-Djol.skipDynamicAttach=true". Thanks to Rafael Winterhalter for this contribution: https://bugs.openjdk.java.net/browse/CODETOOLS-7901220 * We now also provide the synthetic data model with a given object alignment. This is useful in simulations, and "estimates" now uses the 16-byte alignment as additional case. Change: https://bugs.openjdk.java.net/browse/CODETOOLS-7901112 * CLI tools are now trying to invoke private constructors in addition to public constructors when they need a sample instance. Volker Simonis had contributed a simple patch for this: https://bugs.openjdk.java.net/browse/CODETOOLS-7901238 * String Compression estimator that we use for "More memory-efficient internal representation for Strings": $ jol-cli.jar string-compress *.hprof https://bugs.openjdk.java.net/browse/JDK-8054307 * CLI tools are now merged under the single executable JAR (jol-cli.jar). This helps to copy and use the uberjar on remote machines, and also we can attach it (in fact, we do) to the artifacts on Maven Central -- so people can pull the uberjar and run it right away. Change: https://bugs.openjdk.java.net/browse/CODETOOLS-7901252 * Bug: "estimates" mistreated arrays as ordinary classes, and therefore the footprint estimate was wrong. This bug was affecting the CLI tools, not the library itself: https://bugs.openjdk.java.net/browse/CODETOOLS-7901131 Additionally, JOL project page is updated to reflect the current status: http://openjdk.java.net/projects/code-tools/jol/ Enjoy! Thanks, -Aleksey. From aleksey.shipilev at oracle.com Thu Jan 15 17:10:42 2015 From: aleksey.shipilev at oracle.com (aleksey.shipilev at oracle.com) Date: Thu, 15 Jan 2015 17:10:42 +0000 Subject: hg: code-tools/jol: 3 new changesets Message-ID: <201501151710.t0FHAg9f026565@aojmv0008> Changeset: 07f113094557 Author: shade Date: 2015-01-15 13:44 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/07f113094557 JOL v0.3. ! jol-cli/pom.xml ! jol-core/pom.xml ! jol-samples/pom.xml ! pom.xml Changeset: 74fe3a88f833 Author: shade Date: 2015-01-15 13:44 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/74fe3a88f833 Added tag 0.3 for changeset 07f113094557 ! .hgtags Changeset: 6df1a9b2e5da Author: shade Date: 2015-01-15 13:45 +0300 URL: http://hg.openjdk.java.net/code-tools/jol/rev/6df1a9b2e5da Continue in 1.0-SNAPSHOT. ! jol-cli/pom.xml ! jol-core/pom.xml ! jol-samples/pom.xml ! pom.xml