Skip to content

Fix/pickle homogenization #475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 23, 2015

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Apr 14, 2015

Standardize types pickled by packages as agreed in conversation with @VladimirNik.

Review by @VladimirNik, @xeno-by

odersky added 2 commits April 14, 2015 14:38
Needed for next commit. Also homogenize types used in prefixes, and never drop "scala.", "Predef." in homogenized view.
Previously, package references could also be pickled as ThisTypes, which
presented a problem for the scalac pickler.
@@ -187,8 +187,14 @@ class TreePickler(pickler: TastyPickler) {
pickleName(tpe.name); pickleType(tpe.prefix)
}
case tpe: ThisType =>
writeByte(THIS)
pickleType(tpe.tref)
if (tpe.cls.is(Flags.Package) && !tpe.cls.isEffectiveRoot) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this normalization also affect modules?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, why not do this for RootClass?

@odersky
Copy link
Contributor Author

odersky commented Apr 14, 2015

@xeno-by: For modules we need the distinction: From inside a module, we prefer ThisType because
its the type of this and it is more efficient than selecting a lazy val coming from the outside.
For "<"root">" and "<"empty">" we have the concention that they are represented as ThisTypes.

@VladimirNik
Copy link
Contributor

The changes related to type pickling didn't help with the type duplication problem during the pickling.
Here's the example:

class Test2 {
  def x: Int = 5
}

Even using the updated version we have two pickled types that represent 'package scala'.

This type is pickled during the processing of tpt of init (scala.Unit):
ThisType(TypeRef(NoPrefix,scala))

This type is pickled during the processing of tpt of def x:
TermRef(ThisType(TypeRef(NoPrefix,)),scala)

The issue is that each of these types is already added to pickledTypes before the invocation of def pickleNewType, and has its address.

Here is a part from the pickling log file:

//Unit processing
pickleName: Unit
astTag: TERMREFpkg (67)
//at this moment ThisType(TypeRef(NoPrefix,scala)) is already in the *pickledTypes* map
pickleName(*): Simple(scala)
...
astTag: DEFDEF (130)
pickleName: x
astTag: TYPEREF (117)
pickleName: Int
astTag: TERMREF (115)
//at this moment TermRef(ThisType(TypeRef(NoPrefix,<root>)),scala) also is in the *pickledTypes* map
pickleNameAndSig, name: scala
                  params: List()
                  result: 
pickleName(*): Signed(NameRef(14),List(),NameRef(2))

To have only one instance of the type, the second passed type should be transformed to its equivalent to be found in the pickledTypes map during the invocation of pickleType.

@odersky
Copy link
Contributor Author

odersky commented Apr 16, 2015

I see, thanks. I will be away from my computer for a couple of days. If you
have time for a PR to fix this, that would accelerate things. If not, I'll
get to it next week.

On Thu, Apr 16, 2015 at 3:39 AM, Vladimir Nikolaev <[email protected]

wrote:

The changes related to type pickling didn't help with the type duplication
problem during the pickling.
Here's the example:

class Test2 {
def x: Int = 5
}

Even using the updated version we have two pickled types that represent 'package
scala'
.

This type is pickled during the processing of tpt of init (scala.Unit):
ThisType(TypeRef(NoPrefix,scala))

This type is pickled during the processing of tpt of def x:
TermRef(ThisType(TypeRef(NoPrefix,)),scala)

The issue is that each of these types is already added to pickledTypes
before the invocation of def pickleNewType, and has its address.

Here is a part from the pickling log file:

//Unit processing
pickleName: Unit
astTag: TERMREFpkg (67)
//at this moment ThisType(TypeRef(NoPrefix,scala)) is already in the pickledTypes map
pickleName(): Simple(scala)
...
astTag: DEFDEF (130)
pickleName: x
astTag: TYPEREF (117)
pickleName: Int
astTag: TERMREF (115)
//at this moment TermRef(ThisType(TypeRef(NoPrefix,)),scala) also is in the *pickledTypes
map
pickleNameAndSig, name: scala
params: List()
result:
pickleName(*): Signed(NameRef(14),List(),NameRef(2))

To have only one instance of the type, the second passed type should be
transformed to its equivalent to be found in the pickledTypes map
during the invocation of pickleType.


Reply to this email directly or view it on GitHub
#475 (comment).

Martin Odersky
EPFL

@VladimirNik
Copy link
Contributor

The problem with this task is how to transform one type to its counterpart before its processing inside def pickleType (before the addition to pickledTypes map) . If we want to pickle only types of one definite form (for packages), the other form should be mapped to the first one.

Previously, some references used TermRef and a name with signature,
which gave  two different ways to represent a package.
@odersky
Copy link
Contributor Author

odersky commented Apr 20, 2015

@VladimirNik can you check whether the last commit is what you need?

@VladimirNik
Copy link
Contributor

I checked the same example:

class Test {
  def x: Int = 5
}

With these changes for Dotty we have:

//pickling for scala.Unit in the constructor
astTag: TYPEREF (117)
pickleName: Unit
astTag: TERMREFpkg (67)
pickleName(*): Simple(scala)
...
//pickling for tpt of the method
astTag: TYPEREF (117)
pickleName: Int
//scala package processing
astTag: TERMREFpkg (67)
pickleName(*): Simple(scala)

Two instances (two forms) of scala package are represented similarly during the pickling, but they are both pickled and have their addresses in pickledTypes map.

And in Scala log:

//pickling for scala.Unit in the constructor
astTag: TYPEREF (117)
pickleName: Unit
astTag: TERMREFpkg (67)
pickleName(*): Simple(scala)
...
//pickling for tpt of the method
astTag: TYPEREF (117)
pickleName: Int
//scala package processing
astTag: SHARED (64) // No new type pickling

The type for scala package is shared. There is only one address for this type.

Maybe we should allow the different pickling results for Dotty and Scala?

@odersky
Copy link
Contributor Author

odersky commented Apr 20, 2015

Yes, I think we should allow. Sharing is strictly an optimization; we
should not rely on the fact that it happens.

  • Martin

On Mon, Apr 20, 2015 at 12:42 PM, Vladimir Nikolaev <
[email protected]> wrote:

I checked the same example:

class Test {
def x: Int = 5
}

With these changes for Dotty we have:

//pickling for scala.Unit in the constructor
astTag: TYPEREF (117)
pickleName: Unit
astTag: TERMREFpkg (67)
pickleName(): Simple(scala)
...
//pickling for tpt of the method
astTag: TYPEREF (117)
pickleName: Int
//scala package processing
astTag: TERMREFpkg (67)
pickleName(
): Simple(scala)

Two instances (two forms) of scala package are represented similarly
during the pickling, but they are both pickled and have their addresses in
pickledTypes map.

And in Scala log:

//pickling for scala.Unit in the constructor
astTag: TYPEREF (117)
pickleName: Unit
astTag: TERMREFpkg (67)
pickleName(*): Simple(scala)
...
//pickling for tpt of the method
astTag: TYPEREF (117)
pickleName: Int
//scala package processing
astTag: SHARED (64) // No new type pickling

The type for scala package is shared. There is only one address for
this type.

Maybe we should allow the different pickling results for Dotty and Scala?


Reply to this email directly or view it on GitHub
#475 (comment).

Martin Odersky
EPFL

@odersky
Copy link
Contributor Author

odersky commented Apr 23, 2015

@VladimirNik Good to merge?

@VladimirNik
Copy link
Contributor

@odersky LGTM, thank you!

odersky added a commit that referenced this pull request Apr 23, 2015
@odersky odersky merged commit 4efcfa6 into scala:master Apr 23, 2015
@allanrenucci allanrenucci deleted the fix/pickle-homogenization branch December 14, 2017 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants