Scala Programming Language
  1. Scala Programming Language
  2. SI-1591

Inner objects inside a class are not singletons

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Misc Compiler
    • Labels:
      None
    • Environment:

      inner object singleton multithread

      Description

      It is possible to create several instances of the same inner object in a multithreaded context which may cause inconsistent singleton access.

      This is best illustrated on the sample below.

      — Scala —

      abstract class MyType
      
      class InnerObjectTest {
        object unique extends MyType
      }
      
      

      — javap -private -c -l —

      private InnerObjectTest$$unique$$ unique$$module;
      ...
      public final InnerObjectTest$$unique$$ unique();
        Code:
         0:   aload_0
         1:   getfield        SI-18; //Field unique$$module:LInnerObjectTest$$unique$$;
         4:   ifnonnull       19
         7:   aload_0
         8:   new     SI-20; //class InnerObjectTest$$unique$$
         11:  dup
         12:  aload_0
         13:  invokespecial   SI-23; //Method InnerObjectTest$$unique$$."<init>":(LInnerObjectTest;)V
         16:  putfield        SI-18; //Field unique$$module:LInnerObjectTest$$unique$$;
         19:  aload_0
         20:  getfield        SI-18; //Field unique$$module:LInnerObjectTest$$unique$$;
         23:  areturn
       
      
      
      

      If you look at the bytecode generated by the compiler, the unique() method initializes a private field named "unique$$module" to a reference to a new instance of type "!InnerObjectTest$$unique$$" but there is no synchronization - if several threads access the 'unique()' method concurrently, there is a small chance that they get different objects.

      Object access/initialization code should be the same as lazy val access/initialization code

        Activity

        Hide
        Hubert Plociniczak added a comment -

        There was a recent discussion on the mailing list whether we should postpone 2.8 release to fix this bug. Given that there is a trivial temporary solution (i.e. using lazy values instead of inner objects) we will postpone fixing this bug until 2.8.1.
        I am aware that the bug is important but another long delay in 2.8 is hard to accept.

        Show
        Hubert Plociniczak added a comment - There was a recent discussion on the mailing list whether we should postpone 2.8 release to fix this bug. Given that there is a trivial temporary solution (i.e. using lazy values instead of inner objects) we will postpone fixing this bug until 2.8.1. I am aware that the bug is important but another long delay in 2.8 is hard to accept.
        Hide
        Hubert Plociniczak added a comment -

        (In r23059) Closes SI-1591. Treat nested objects as lazy vals. Updated some tests. Review by dragos

        Show
        Hubert Plociniczak added a comment - (In r23059) Closes SI-1591 . Treat nested objects as lazy vals. Updated some tests. Review by dragos
        Hide
        Hubert Plociniczak added a comment -

        Reverted, because it is causing SI-3879.

        Show
        Hubert Plociniczak added a comment - Reverted, because it is causing SI-3879 .
        Hide
        Hubert Plociniczak added a comment -

        Fixed in r23164.

        Show
        Hubert Plociniczak added a comment - Fixed in r23164.
        Hide
        Martin Kneissl added a comment -

        Looking at the byte code generated by Scala 2.8.1.final, it seems that this bug has not been fixed or reoccurred after the above commit.
        Inner objects in 2.8.1.final are NOT singletons in multi-threaded environments.

        2.9.0-1 looks ok.

        Show
        Martin Kneissl added a comment - Looking at the byte code generated by Scala 2.8.1.final, it seems that this bug has not been fixed or reoccurred after the above commit. Inner objects in 2.8.1.final are NOT singletons in multi-threaded environments. 2.9.0-1 looks ok.
        Show
        Martin Kneissl added a comment - Test program to reproduce this bug. See also https://github.com/mkneissl/scalabugs/blob/master/src/main/scala/eu/kneissl/scalabugs/InnerObjectInitialization.scala

          People

          • Assignee:
            Hubert Plociniczak
            Reporter:
            Sbastien Bocq
            TracCC:
            archontophoenix, Caoyuan Deng, Christos KK Loverdos, Erik Engbrecht, Ismael Juma, Johannes Rudolph, Jorge Ortiz, Josh Suereth, Seth Tisue, Stephen Haberman
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development