From: Matthew Khouzam Date: Wed, 18 May 2016 00:44:05 +0000 (-0400) Subject: linux.core: Intern SystemCall name string X-Git-Url: http://git.efficios.com/?p=deliverable%2Ftracecompass.git;a=commitdiff_plain;h=4eec2dc5012a554724f98237ddc8a1d0bc7adb0e linux.core: Intern SystemCall name string This patch makes SystemCall mutable. This is a tricky situation. This object is serializable. In order to internalize the string (name) the object needs to have a custom readObject(). This means we need to either make the name field mutable or use reflexion to make the field modifyable. If we are using reflexion, the point of making an object immutable is moot. Here are the main reasons for an immutable object: * immutable objects are simpler to construct, test, and use * truly immutable objects are always thread-safe * they help to avoid temporal coupling * their usage is side-effect free (no defensive copies) * identity mutability problem is avoided * they always have failure atomicity * they are much easier to cache * they prevent NULL references, which are bad As SystemCall has no setters, and the class is now final, its fields are in practice immutable. This begs the question though, would having no "final" keyword on a field affect performance. Unfortunately no. Final classes can be inlined, but final fields yield no advantage other than code clarity. We should still strive to have final fields whenever it is possible, but this should not cause ideological objections, as it breaks clean serialization. This partially addresses bug 489217 Change-Id: I80a99128dffebe1fb3c0561ab76beabea2cc7775 Signed-off-by: Matthew Khouzam Reviewed-on: https://git.eclipse.org/r/72995 Reviewed-by: Hudson CI --- diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/SystemCall.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/SystemCall.java index 0b72c10289..3233fc08af 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/SystemCall.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/SystemCall.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir + * Copyright (c) 2015, 2016 EfficiOS Inc., Alexandre Montplaisir and others * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -9,7 +9,9 @@ package org.eclipse.tracecompass.internal.analysis.os.linux.core.latency; -import java.io.Serializable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.segmentstore.core.ISegment; @@ -20,19 +22,17 @@ import org.eclipse.tracecompass.segmentstore.core.ISegment; * @author Alexandre Montplaisir * @since 2.0 */ -public class SystemCall implements ISegment { +public final class SystemCall implements ISegment { private static final long serialVersionUID = 1554494342105208730L; /** * The subset of information that is available from the syscall entry event. */ - public static class InitialInfo implements Serializable { + public static class InitialInfo { - private static final long serialVersionUID = -5009710718804983721L; - - private final long fStartTime; - private final String fName; + private long fStartTime; + private String fName; /** * @param startTime @@ -44,12 +44,13 @@ public class SystemCall implements ISegment { long startTime, String name) { fStartTime = startTime; - fName = name; + fName = name.intern(); } } - private final InitialInfo fInfo; - private final long fEndTime; + private long fStartTime; + private long fEndTime; + private String fName; /** * @param info @@ -60,13 +61,26 @@ public class SystemCall implements ISegment { public SystemCall( InitialInfo info, long endTime) { - fInfo = info; + fStartTime = info.fStartTime; + fName = info.fName; fEndTime = endTime; } + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeLong(fStartTime); + out.writeLong(fEndTime); + out.writeUTF(fName); + } + + private void readObject(ObjectInputStream in) throws IOException { + fStartTime = in.readLong(); + fEndTime = in.readLong(); + fName = in.readUTF().intern(); + } + @Override public long getStart() { - return fInfo.fStartTime; + return fStartTime; } @Override @@ -80,7 +94,7 @@ public class SystemCall implements ISegment { * @return Name */ public String getName() { - return fInfo.fName; + return fName; } @Override