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

Add Bytecode test (ASM-based) to partest. #2014

Merged
merged 1 commit into from Jan 31, 2013

Conversation

gkossakowski
Copy link
Member

This commit introduces a new kind of test Bytecode that allows
one to inspect bytecode generated for given piece of Scala code.

The bytecode inspection is achieved by inspection of ASM trees.
See the included example for details.

NOTE: This commit does not introduce a new category of pratest tests.
Bytecode tests should be run in jvm category of partest tests.

Specific list of changes:

  • Add BytecodeTest that contains common utilities to partest
  • Add asm to classpath when compiling partest. That's not a
    new dependency as it's being already done for javac task
    we were running while compiling partest.
  • Add an example test that shows how to count null checks in
    given method.

This commit introduces a new kind of test `Bytecode` that allows
one to inspect bytecode generated for given piece of Scala code.

The bytecode inspection is achieved by inspection of ASM trees.
See the included example for details.

NOTE: This commit does not introduce a new category of pratest tests.
Bytecode tests should be run in `jvm` category of partest tests.

Specific list of changes:
  * Add BytecodeTest that contains common utilities to partest
  * Add asm to classpath when compiling partest. That's not a
    new dependency as it's being already done for javac task
    we were running while compiling partest.
  * Add an example test that shows how to count null checks in
    given method.
@gkossakowski
Copy link
Member Author

Requested by @adriaanm for testing his pattern matcher improvements. No more excuses for not improving byte code size generated by pattern matcher! :-)

Review by @JamesIry
//cc @magarciaEPFL that might be interested in low-level, bytecode testing

@gkossakowski
Copy link
Member Author

Also, in case you are guys wondering why I'm not just dumping bytecode and doing textual diff. The reason is that we want to test specific things about bytecode and not it overall shape.

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/1715/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/2450/

@JamesIry
Copy link
Contributor

I bet we find some nice abstractions over raw ASM as we use this, but LGTM as a start.

@scala-jenkins
Copy link

Started jenkins job pr-rangepos at https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/1716/

@scala-jenkins
Copy link

Started jenkins job pr-scala-testsuite-linux-opt at https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/2451/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/1715/

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/2450/

@scala-jenkins
Copy link

jenkins job pr-rangepos: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-rangepos/1716/

@scala-jenkins
Copy link

jenkins job pr-scala-testsuite-linux-opt: Success - https://scala-webapps.epfl.ch/jenkins/job/pr-scala-testsuite-linux-opt/2451/

*/
def isNullCheck(node: asm.tree.AbstractInsnNode): Boolean = {
val opcode = node.getOpcode
(opcode == asm.Opcodes.IFNULL) || (opcode == asm.Opcodes.IFNONNULL)
Copy link
Member

Choose a reason for hiding this comment

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

Micro-review-note:

I prefer to deduplicate the == with Set(asm.Opcodes.IFNULL, asm.Opcodes.IFNONNULL)(node.getOpcode)

Copy link
Contributor

Choose a reason for hiding this comment

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

...which is potentially pretty expensive, so lift the Set into a val in object Test. It's only a test, but still.

Copy link
Member

Choose a reason for hiding this comment

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

It's one of those areas where I cross my fingers and wait for escape analysis to kick in. If it inlines to Set2#contains, we're golden.

Copy link
Member Author

Choose a reason for hiding this comment

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

I did it the way I did for reason @paulp pointed out.

@retronym
Copy link
Member

A general question: if we are testing the pattern matcher, rather than the byte-code emitter, wouldn't it be better to to test Trees instead?

In cases when we want to integration test the whole chain, or compiler transforms that operate only on bytecode (e.g. code gen, the experimental optimizer, the recently proposed alternative try-expression transform), bytecode testing makes perfect sense.

@magarciaEPFL
Copy link
Contributor

This is a useful addition to our tool chest. Just a comment: it may end up being used to test transforms in a JVM-dependent way, when the transform itself is platform-independent.

@adriaanm
Copy link
Contributor

testing tree equality is a bit harder than bytecode as the trees emitted by patmat are not expressible in source level
I agree that's another useful tool to have, though

@gkossakowski
Copy link
Member Author

@retronym yes, it's more about the whole chain/integration testing. If you care about every byte we spend on translating pattern matches then it makes sense to test the final outcome.

@gkossakowski
Copy link
Member Author

I got the LGTM from @JamesIry so I'll offload @adriaanm and merge myself (as I did with a few more PRs today).

gkossakowski added a commit that referenced this pull request Jan 31, 2013
Add Bytecode test (ASM-based) to partest.
@gkossakowski gkossakowski merged commit c4f4975 into scala:2.10.x Jan 31, 2013
@gkossakowski gkossakowski deleted the bytecode-testing branch May 7, 2014 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants