diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-03 10:38:37 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-03 17:09:22 +0100 |
commit | 4a34a428c6a2588e0857ef6baf88f1b73ce65958 (patch) | |
tree | a9f025c17752a175c4e6a203c01e935cb438efb1 /compiler/optimizing/builder.cc | |
parent | 8549cf9d83688f7decbbea2a8de761ce29e95f3c (diff) | |
download | art-4a34a428c6a2588e0857ef6baf88f1b73ce65958.zip art-4a34a428c6a2588e0857ef6baf88f1b73ce65958.tar.gz art-4a34a428c6a2588e0857ef6baf88f1b73ce65958.tar.bz2 |
Support passing arguments to invoke-static* instructions.
- Stop using the frame pointer for accessing locals.
- Stop emulating a stack when doing code generation. Instead,
rely on dex register model, where instructions only reference
registers.
Change-Id: Id51bd7d33ac430cb87a53c9f4b0c864eeb1006f9
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r-- | compiler/optimizing/builder.cc | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 64ecdb5..0554876 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -37,8 +37,6 @@ void HGraphBuilder::InitializeLocals(int count) { static bool CanHandleCodeItem(const DexFile::CodeItem& code_item) { if (code_item.tries_size_ > 0) { return false; - } else if (code_item.outs_size_ > 0) { - return false; } else if (code_item.ins_size_ > 0) { return false; } @@ -62,6 +60,7 @@ HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) { graph_->SetExitBlock(exit_block_); InitializeLocals(code_item.registers_size_); + graph_->UpdateMaximumNumberOfOutVRegs(code_item.outs_size_); // To avoid splitting blocks, we compute ahead of time the instructions that // start a new block, and create these blocks. @@ -200,14 +199,49 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx); const size_t number_of_arguments = instruction.VRegA_35c(); - if (number_of_arguments != 0) { + + if (Primitive::GetType(descriptor[0]) != Primitive::kPrimVoid) { return false; } + + HInvokeStatic* invoke = new (arena_) HInvokeStatic( + arena_, number_of_arguments, dex_offset, method_idx); + + uint32_t args[5]; + instruction.GetArgs(args); + + for (size_t i = 0; i < number_of_arguments; i++) { + HInstruction* arg = LoadLocal(args[i]); + HInstruction* push = new (arena_) HPushArgument(arg, i); + current_block_->AddInstruction(push); + invoke->SetArgumentAt(i, push); + } + + current_block_->AddInstruction(invoke); + break; + } + + case Instruction::INVOKE_STATIC_RANGE: { + uint32_t method_idx = instruction.VRegB_3rc(); + const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); + uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; + const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx); + const size_t number_of_arguments = instruction.VRegA_3rc(); + if (Primitive::GetType(descriptor[0]) != Primitive::kPrimVoid) { return false; } - current_block_->AddInstruction(new (arena_) HInvokeStatic( - arena_, number_of_arguments, dex_offset, method_idx)); + + HInvokeStatic* invoke = new (arena_) HInvokeStatic( + arena_, number_of_arguments, dex_offset, method_idx); + int32_t register_index = instruction.VRegC(); + for (size_t i = 0; i < number_of_arguments; i++) { + HInstruction* arg = LoadLocal(register_index + i); + HInstruction* push = new (arena_) HPushArgument(arg, i); + current_block_->AddInstruction(push); + invoke->SetArgumentAt(i, push); + } + current_block_->AddInstruction(invoke); break; } |