Skip to content
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

Optimize away ClassTags and ArrayBuilders #1669

Merged
merged 10 commits into from May 20, 2015

Conversation

sjrd
Copy link
Member

@sjrd sjrd commented May 16, 2015

No description provided.

@sjrd
Copy link
Member Author

sjrd commented May 16, 2015

CI for now.

@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1698/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2201/
Test PASSed.

@scala-jenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1699/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2202/
Test FAILed.

@sjrd sjrd force-pushed the optimize-away-classtags-and-array-builders branch from c41293a to 1c99868 Compare May 16, 2015 23:27
@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1702/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2205/
Test PASSed.

@sjrd sjrd force-pushed the optimize-away-classtags-and-array-builders branch from 1c99868 to d229654 Compare May 17, 2015 06:50
@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1703/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2207/
Test PASSed.

@sjrd sjrd force-pushed the optimize-away-classtags-and-array-builders branch 2 times, most recently from 9c5926a to 0969fe2 Compare May 17, 2015 12:24
@sjrd sjrd changed the title DO NOT MERGE Optimize away ClassTags and ArrayBuilders Optimize away ClassTags and ArrayBuilders May 17, 2015
@sjrd
Copy link
Member Author

sjrd commented May 17, 2015

OK, I'm done with this one.
Review by @gzm0 please.

@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1705/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2209/
Test PASSed.

@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1704/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2208/
Test PASSed.

@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1706/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2210/
Test PASSed.

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

What is Intf?

isSubclass(lhsBase, rhsBase)
/* All things must be considered subclasses of Object for this
* purpose, even raw JS types and interfaces that do not have
* Object in their ancestors, strictly speaking.
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you mean by "strictly speaking"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hum, nothing, really. I guess when I wrote that I was still surprised myself to rediscover that interfaces did not have Object in their ancestors.

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

Also, why is not every class type subtype of Object anyways?

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

Why not generalize Select elimination to any target?

@@ -0,0 +1,72 @@
/* __ *\
** ________ ___ / / ___ __ ____ Scala.js Test Suite **
Copy link
Contributor

Choose a reason for hiding this comment

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

This file should be ReflectArrayTest.scala.

@sjrd
Copy link
Member Author

sjrd commented May 17, 2015

What is Intf?

Short for Interface. Isn't that the standard shorthand?

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

Short for Interface. Isn't that the standard shorthand?

Hahahaha, I have no idea. But I though its something like Int and Float :P Let's have google decide.

@sjrd
Copy link
Member Author

sjrd commented May 17, 2015

Also, why is not every class type subtype of Object anyways?

For raw JS types, because they're not. They're subtypes of Any, but not of Object, which is only supertype of all Scala.js classes + hijacked classes.

For interfaces, well, it might be an accident of history, because interfaces in .class files do not list Object as their superclass. So sjsir files do not either. But I guess we could instead decide that Object is part of the ancestors of interfaces once in a LinkedClass. That might make more sense.

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

Intf vs Iface:

"intf java": 89k
"iface java": 238k
"inft scala": 6k
"iface scala": 587k

@sjrd
Copy link
Member Author

sjrd commented May 17, 2015

Why not generalize Select elimination to any target?

Because the qualifier could be null. Although, arguably, the optimizer already ignores that possibility in some cases (when inlining a method, for example). So yes, we could.

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

Because the qualifier could be null. Although, arguably, the optimizer already ignores that possibility in some cases (when inlining a method, for example). So yes, we could.

Seems like we need a semantic flag :)

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

For raw JS types, because they're not. They're subtypes of Any, but not of Object, which is only supertype of all Scala.js classes + hijacked classes.

Hmmm... nevertheless you can call all methods of Object on a raw JS type...

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

For interfaces, well, it might be an accident of history, because interfaces in .class files do not list Object as their superclass. So sjsir files do not either. But I guess we could instead decide that Object is part of the ancestors of interfaces once in a LinkedClass. That might make more sense.

I think we should do that. Doesn't this also apply in other (non-array) cases? We know that any non raw interface is a subtype of Object right?

@sjrd
Copy link
Member Author

sjrd commented May 17, 2015

Seems like we need a semantic flag :)

Even without optimizer, we never truly respect NPEs, and we never will, even under a flag, because

  • NPEs are TypeErrors in the first place
  • In a method call, the time at which a TypeError is thrown (before evaluating the arguments) is different than that at which an NPE is thrown (after evaluating the arguments).

Checking things accurately would be so awful, from both a performance perspective than a maintenance of JSDesaguring perspective, that this will never happen.

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

Oh. OK for NPEs. If they are officially undefined behavior, we can do whatever we want :) So let's elide Select all the time.

genericArrayBuilderResult(
if (classOf[Unit] == elementClass) classOf[BoxedUnit]
else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object]
else elementClass,
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider making a tmp var with this (except if it hinders inlining). It is hard to read.

Copy link
Member Author

Choose a reason for hiding this comment

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

It does not do harm to inlining, no. It just produces a bit more JS code in the case where the runtimeClass is not known statically.
(edit: so I'll change it)

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

I'll leave that change out of this PR, anyway.

OK.

I'll continue this later. The Array inlining tests were too much :)

@gzm0
Copy link
Contributor

gzm0 commented May 17, 2015

By the way, I think this PR is a good candidate for running a partest on it.

@sjrd
Copy link
Member Author

sjrd commented May 17, 2015

By the way, I think this PR is a good candidate for running a partest on it.

Already did locally (that's how I found out that classOf[Null] and classOf[Nothing] had to be replaced by classOf[Object]). I'll schedule a nightly on the CI when the PR otherwise LGTY.

}
cont(PreTransTree(CallHelper("makeNativeArrayWrapper",
CallHelper("arrayDataOf",
CallHelper("classDataOf", runtimeClass)(AnyType))(AnyType),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like this since it exposes the existence of class data to the optimizer. Could we make a single dummy that takes a j.l.Class and a js.Array and produces the wrapped array?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Well yes... but the bracket part of it... Let's leave it. Probably not doable differently.

@gzm0
Copy link
Contributor

gzm0 commented May 18, 2015

That's all.

sjrd added 4 commits May 18, 2015 13:00
The side effects of `qualifier` are kept, obviously. We can do
this because NPE is undefined behavior.
LoadModule, NewArray, ArrayValue, GetClass and ClassOf always return
non-nullable values of an exact type. This can help some other
optimizations, the most obvious being optimizing away a test
LoadModule(_) === Null().
@sjrd sjrd force-pushed the optimize-away-classtags-and-array-builders branch 2 times, most recently from 8c738ff to a85b6e4 Compare May 18, 2015 11:52
@sjrd
Copy link
Member Author

sjrd commented May 18, 2015

Updated.

sjrd added 6 commits May 18, 2015 13:53
* GetClass(expr) when expr has an exact type
* clazz.getComponentType()
* j.l.reflect.Array.newInstance(clazz, length)
* Inline ScalaRunTime.{arrayClass,arrayElementClass}
This allows inlining of `Array.tabulate(x, y)`, for example,
which is implemented as

  def tabulate[T: ClassTag](n1: Int, n2: Int)(
      f: (Int, Int) => T): Array[Array[T]] =
    tabulate(n1)(i1 => tabulate(n2)(f(i1, _)))

in which the tabulate_1 method is called with a lambda that itself
calls tabulate_1.
@scala-jenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):

https://scala-webapps.epfl.ch/jenkins/job/scalajs-pr/1709/
https://scala-webapps.epfl.ch/jenkins/job/scalajs-matrix-build/2214/
Test PASSed.

@sjrd
Copy link
Member Author

sjrd commented May 18, 2015

@sjrd
Copy link
Member Author

sjrd commented May 19, 2015

Nightly passed on a85b6e4

@gzm0
Copy link
Contributor

gzm0 commented May 20, 2015

LGTM

gzm0 added a commit that referenced this pull request May 20, 2015
…builders

Optimize away ClassTags and ArrayBuilders
@gzm0 gzm0 merged commit 737a649 into scala-js:master May 20, 2015
@sjrd sjrd deleted the optimize-away-classtags-and-array-builders branch May 20, 2015 20:15
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.

None yet

3 participants