-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Use a java static to throw IndexOutOfBoundsException #7086
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
Conversation
def createSwitchMethod(name: Name, range: Seq[Int], returnType: Type)(f: Int => Tree) = { | ||
createMethod(name, List(IntTpe), returnType) { m => | ||
val arg0 = Ident(m.firstParam) | ||
val default = DEFAULT ==> Throw(IndexOutOfBoundsExceptionClass.tpe_*, fn(arg0, nme.toString_)) | ||
val default = DEFAULT ==> callStaticsGenericMethod("aioobe", returnType)(arg0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should add a val aioobe = "aioobe"
to nme
in StdNames
rather than calling newTermName
every time.
Apply(TypeApply(gen.mkAttributedRef(method), List(TypeTree(returnType))), args.toList) | ||
} | ||
|
||
def callStaticsGenericMethod(name: String, returnType: Type)(args: Tree*): Tree = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... and then you won't be needing this.
Nice! Another possible avenue to shave off further bytes is to skip generating |
Just noticed that we should actually throw Fixing now. |
@@ -76,10 +76,15 @@ trait MethodSynthesis { | |||
def forwardMethod(original: Symbol, newMethod: Symbol)(transformArgs: List[Tree] => List[Tree]): Tree = | |||
createMethod(original)(m => gen.mkMethodCall(newMethod, transformArgs(m.paramss.head map Ident))) | |||
|
|||
def callStaticsGenericMethod(name: TermName, returnType: Type)(args: Tree*): Tree = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is args a vararg - its always one param?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method is based on this method in SyntheticMethods
. Over there it made more sense for it to have varargs.
To be honest, this method is only used in one place so we could just inline it if you're worried about performance. I would either do that, or leave it as it is for the sake of readability, but I don't have a strong opinion either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think inlining it would be too bad, personally.
@@ -307,13 +314,13 @@ trait SyntheticMethods extends ast.TreeDSL { | |||
Any_equals -> (() => equalsDerivedValueClassMethod) | |||
) | |||
|
|||
def caseClassMethods = productMethods ++ /*productNMethods ++*/ Seq( | |||
def caseClassMethods = productClassMethods ++ /*productNMethods ++*/ Seq( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can remove the intermediate collections easily here either in this PR or another - just to remove some CPU/memory in the compile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I'm poking at this file; there's some room for improvement
@cb372 I reviewed this and pushed my review feedback as a commit. If it LGTY we can squash and merge. |
@lrytz Thanks for the feedback. Your changes LGTM. The Travis build failed with a StackOverflowError in the typer. I'm not sure if that's caused by the changes in this PR? I just ran the tests locally and I couldn't reproduce it. |
This reduces the bytecode cost of the synthetic `productElement` and `productElementName` implementations in case classes.
Squashed and rebased. Will see if Travis is any happier this time. |
You can ignore travis for now, scala/scala-dev#570 |
Follow-up to #6972.
As suggested by @retronym, this reduces the bytecode fixed cost of the synthetic
productElement
andproductElementName
implementations in case classes.Measured the difference using a simple case class:
Before (
2.13.0-pre-b739165
):After:
So a saving of 105 bytes.
The new bytecode looks like this:
If we care about saving another 3 bytes, we could make the
ioobe
returnString
instead of having it generic. That happens to work because it's only called in these two places (productElement
, which returnsAny
, andproductElementName
, which returnsString
) but it seems a bit naughty.Also removed the synthetic
productElementName
for case objects. A bridge method is generated instead, but it's slightly smaller than the synthetic so we save about 16 bytes on case objects.