diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-10-22 16:07:05 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-10-29 13:01:48 +0000 |
commit | 19a19cffd197a28ae4c9c3e59eff6352fd392241 (patch) | |
tree | 265b971afd0e33afc8986317aea2f5a6fe817aec /compiler/optimizing/builder.cc | |
parent | 7c049c1f34220b0dc1a7f68f3b30f388bae7bdb9 (diff) | |
download | art-19a19cffd197a28ae4c9c3e59eff6352fd392241.tar.gz art-19a19cffd197a28ae4c9c3e59eff6352fd392241.tar.bz2 art-19a19cffd197a28ae4c9c3e59eff6352fd392241.zip |
Add support for static fields in optimizing compiler.
Change-Id: Id2f010589e2bd6faf42c05bb33abf6816ebe9fa9
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r-- | compiler/optimizing/builder.cc | 98 |
1 files changed, 92 insertions, 6 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index f80ebdb5e..e4ccd9651 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -1,5 +1,4 @@ /* - * * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -421,9 +420,9 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction, return true; } -bool HGraphBuilder::BuildFieldAccess(const Instruction& instruction, - uint32_t dex_offset, - bool is_put) { +bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, + uint32_t dex_offset, + bool is_put) { uint32_t source_or_dest_reg = instruction.VRegA_22c(); uint32_t obj_reg = instruction.VRegB_22c(); uint16_t field_index = instruction.VRegC_22c(); @@ -469,6 +468,67 @@ bool HGraphBuilder::BuildFieldAccess(const Instruction& instruction, return true; } + + +bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, + uint32_t dex_offset, + bool is_put) { + uint32_t source_or_dest_reg = instruction.VRegA_21c(); + uint16_t field_index = instruction.VRegB_21c(); + + uint32_t storage_index; + bool is_referrers_class; + bool is_initialized; + bool is_volatile; + MemberOffset field_offset(0u); + Primitive::Type field_type; + + bool fast_path = compiler_driver_->ComputeStaticFieldInfo(field_index, + dex_compilation_unit_, + is_put, + &field_offset, + &storage_index, + &is_referrers_class, + &is_volatile, + &is_initialized, + &field_type); + if (!fast_path) { + return false; + } + + if (is_volatile) { + return false; + } + + if (!IsTypeSupported(field_type)) { + return false; + } + + HLoadClass* constant = new (arena_) HLoadClass( + storage_index, is_referrers_class, is_initialized, dex_offset); + current_block_->AddInstruction(constant); + + HInstruction* cls = constant; + if (constant->NeedsInitialization()) { + cls = new (arena_) HClinitCheck(constant, dex_offset); + current_block_->AddInstruction(cls); + } + + if (is_put) { + // We need to keep the class alive before loading the value. + Temporaries temps(graph_, 1); + temps.Add(cls); + HInstruction* value = LoadLocal(source_or_dest_reg, field_type); + DCHECK_EQ(value->GetType(), field_type); + current_block_->AddInstruction( + new (arena_) HStaticFieldSet(cls, value, field_type, field_offset)); + } else { + current_block_->AddInstruction(new (arena_) HStaticFieldGet(cls, field_type, field_offset)); + UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction()); + } + return true; +} + void HGraphBuilder::BuildArrayAccess(const Instruction& instruction, uint32_t dex_offset, bool is_put, @@ -1043,7 +1103,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 case Instruction::IGET_BYTE: case Instruction::IGET_CHAR: case Instruction::IGET_SHORT: { - if (!BuildFieldAccess(instruction, dex_offset, false)) { + if (!BuildInstanceFieldAccess(instruction, dex_offset, false)) { return false; } break; @@ -1056,7 +1116,33 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32 case Instruction::IPUT_BYTE: case Instruction::IPUT_CHAR: case Instruction::IPUT_SHORT: { - if (!BuildFieldAccess(instruction, dex_offset, true)) { + if (!BuildInstanceFieldAccess(instruction, dex_offset, true)) { + return false; + } + break; + } + + case Instruction::SGET: + case Instruction::SGET_WIDE: + case Instruction::SGET_OBJECT: + case Instruction::SGET_BOOLEAN: + case Instruction::SGET_BYTE: + case Instruction::SGET_CHAR: + case Instruction::SGET_SHORT: { + if (!BuildStaticFieldAccess(instruction, dex_offset, false)) { + return false; + } + break; + } + + case Instruction::SPUT: + case Instruction::SPUT_WIDE: + case Instruction::SPUT_OBJECT: + case Instruction::SPUT_BOOLEAN: + case Instruction::SPUT_BYTE: + case Instruction::SPUT_CHAR: + case Instruction::SPUT_SHORT: { + if (!BuildStaticFieldAccess(instruction, dex_offset, true)) { return false; } break; |