linux.core: Intern SystemCall name string
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 18 May 2016 00:44:05 +0000 (20:44 -0400)
committerMatthew Khouzam <matthew.khouzam@ericsson.com>
Wed, 25 May 2016 20:47:57 +0000 (16:47 -0400)
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 <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/72995
Reviewed-by: Hudson CI
analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/SystemCall.java

index 0b72c10289dffcdf3a03eb00df7868d961e21494..3233fc08af9f32397aa4b0f7e4eec477b48669f5 100644 (file)
@@ -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
This page took 0.028805 seconds and 5 git commands to generate.