diff options
author | Eric Holk <eholk@google.com> | 2018-10-26 16:08:09 -0700 |
---|---|---|
committer | Eric Holk <eholk@google.com> | 2018-11-08 21:14:32 +0000 |
commit | d683f9fa3123cb618311f7164a6aedad42e730fd (patch) | |
tree | dda192faa417ed2859973c70f4d29553b0d523c6 /startop/view_compiler/dex_testcase_generator.cc | |
parent | 93bf21dad4279db75c321c141b07c6409d6bcade (diff) |
[view_compiler] Add end-to-end DexBuilder tests
These tests verify that code produced by DexBuilder can be loaded and run on
device. It works by introducing a new tool, dex_testcase_generator, which writes
out a couple of DEX files with test cases. This tool runs as a build step. The
generated DEX are then copied over to the device where they are loaded and run
the on-device DexBuilderTest.
Bug: 111895153
Change-Id: I06f5edd0e3e2f4e9ec2d14a0db7d22b75b424119
Diffstat (limited to 'startop/view_compiler/dex_testcase_generator.cc')
-rw-r--r-- | startop/view_compiler/dex_testcase_generator.cc | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc new file mode 100644 index 000000000000..898817b4768c --- /dev/null +++ b/startop/view_compiler/dex_testcase_generator.cc @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "android-base/logging.h" +#include "dex_builder.h" + +#include <fstream> +#include <string> + +// Adding tests here requires changes in several other places. See README.md in +// the view_compiler directory for more information. + +using namespace startop::dex; +using namespace std; + +void GenerateTrivialDexFile(const string& outdir) { + DexBuilder dex_file; + + ClassBuilder cbuilder{dex_file.MakeClass("android.startop.test.testcases.Trivial")}; + cbuilder.set_source_file("dex_testcase_generator.cc#GenerateTrivialDexFile"); + + slicer::MemView image{dex_file.CreateImage()}; + std::ofstream out_file(outdir + "/trivial.dex"); + out_file.write(image.ptr<const char>(), image.size()); +} + +// Generates test cases that test around 1 instruction. +void GenerateSimpleTestCases(const string& outdir) { + DexBuilder dex_file; + + ClassBuilder cbuilder{dex_file.MakeClass("android.startop.test.testcases.SimpleTests")}; + cbuilder.set_source_file("dex_testcase_generator.cc#GenerateSimpleTestCases"); + + // int return5() { return 5; } + auto return5{cbuilder.CreateMethod("return5", Prototype{TypeDescriptor::Int()})}; + Value r{return5.MakeRegister()}; + return5.BuildConst4(r, 5); + return5.BuildReturn(r); + return5.Encode(); + + // // int returnParam(int x) { return x; } + auto returnParam{cbuilder.CreateMethod("returnParam", + Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})}; + returnParam.BuildReturn(Value::Parameter(0)); + returnParam.Encode(); + + // int returnStringLength(String x) { return x.length(); } + auto string_type{TypeDescriptor::FromClassname("java.lang.String")}; + MethodDeclData string_length{ + dex_file.GetOrDeclareMethod(string_type, "length", Prototype{TypeDescriptor::Int()})}; + + auto returnStringLength{ + cbuilder.CreateMethod("returnStringLength", Prototype{TypeDescriptor::Int(), string_type})}; + Value result = returnStringLength.MakeRegister(); + returnStringLength.AddInstruction( + Instruction::InvokeVirtual(string_length.id, result, Value::Parameter(0))); + returnStringLength.BuildReturn(result); + returnStringLength.Encode(); + + slicer::MemView image{dex_file.CreateImage()}; + std::ofstream out_file(outdir + "/simple.dex"); + out_file.write(image.ptr<const char>(), image.size()); +} + +int main(int argc, char** argv) { + CHECK_EQ(argc, 2); + + string outdir = argv[1]; + + GenerateTrivialDexFile(outdir); + GenerateSimpleTestCases(outdir); +} |