diff options
author | Eric Holk <eholk@google.com> | 2019-07-25 15:14:01 -0700 |
---|---|---|
committer | Eric Holk <eholk@google.com> | 2019-07-26 09:42:41 -0700 |
commit | 3092f99ae63f12f5c18d40f21616c98f2b6c62af (patch) | |
tree | 7b0114acfb0a8d85c1688ddca0c3913353de7d8b /startop/view_compiler/dex_builder.cc | |
parent | a0b2086373140496b131233ea44979098b9dedff (diff) |
[viewcompiler] Add static field get instructions to DexBuilder
This allows us to generate code that can read static fields in a class. Once we
include several other field operations, we will be able to generate more
specialized inflation code in the view compiler.
Bug: 111895153
Change-Id: Ia11195b1cea6d5a3ddbc60d972922586a062c853
Diffstat (limited to 'startop/view_compiler/dex_builder.cc')
-rw-r--r-- | startop/view_compiler/dex_builder.cc | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc index 6047e8c74e38..66bc698e2136 100644 --- a/startop/view_compiler/dex_builder.cc +++ b/startop/view_compiler/dex_builder.cc @@ -102,6 +102,9 @@ std::ostream& operator<<(std::ostream& out, const Instruction::Op& opcode) { case Instruction::Op::kCheckCast: out << "kCheckCast"; return out; + case Instruction::Op::kGetStaticField: + out << "kGetStaticField"; + return out; } } @@ -229,6 +232,22 @@ ir::Type* DexBuilder::GetOrAddType(const std::string& descriptor) { return type; } +ir::FieldDecl* DexBuilder::GetOrAddField(TypeDescriptor parent, const std::string& name, + TypeDescriptor type) { + const auto key = std::make_tuple(parent, name); + if (field_decls_by_key_.find(key) != field_decls_by_key_.end()) { + return field_decls_by_key_[key]; + } + + ir::FieldDecl* field = Alloc<ir::FieldDecl>(); + field->parent = GetOrAddType(parent); + field->name = GetOrAddString(name); + field->type = GetOrAddType(type); + dex_file_->fields_map[field->orig_index] = field; + field_decls_by_key_[key] = field; + return field; +} + ir::Proto* Prototype::Encode(DexBuilder* dex) const { auto* proto = dex->Alloc<ir::Proto>(); proto->shorty = dex->GetOrAddString(Shorty()); @@ -360,6 +379,8 @@ void MethodBuilder::EncodeInstruction(const Instruction& instruction) { return EncodeNew(instruction); case Instruction::Op::kCheckCast: return EncodeCast(instruction); + case Instruction::Op::kGetStaticField: + return EncodeStaticFieldOp(instruction); } } @@ -428,7 +449,7 @@ void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruct // first move all the arguments into contiguous temporary registers. std::array<Value, kMaxArgs> scratch = GetScratchRegisters<kMaxArgs>(); - const auto& prototype = dex_->GetPrototypeByMethodId(instruction.method_id()); + const auto& prototype = dex_->GetPrototypeByMethodId(instruction.index_argument()); CHECK(prototype.has_value()); for (size_t i = 0; i < instruction.args().size(); ++i) { @@ -452,12 +473,12 @@ void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruct Encode3rc(InvokeToInvokeRange(opcode), instruction.args().size(), - instruction.method_id(), + instruction.index_argument(), RegisterValue(scratch[0])); } else { Encode35c(opcode, instruction.args().size(), - instruction.method_id(), + instruction.index_argument(), arguments[0], arguments[1], arguments[2], @@ -514,6 +535,16 @@ void MethodBuilder::EncodeCast(const Instruction& instruction) { Encode21c(::art::Instruction::CHECK_CAST, RegisterValue(*instruction.dest()), type.value()); } +void MethodBuilder::EncodeStaticFieldOp(const Instruction& instruction) { + CHECK_EQ(Instruction::Op::kGetStaticField, instruction.opcode()); + CHECK(instruction.dest().has_value()); + CHECK(instruction.dest()->is_variable()); + CHECK_EQ(0, instruction.args().size()); + + Encode21c( + ::art::Instruction::SGET, RegisterValue(*instruction.dest()), instruction.index_argument()); +} + size_t MethodBuilder::RegisterValue(const Value& value) const { if (value.is_register()) { return value.value(); |