Add support for static fields in optimizing compiler.
Change-Id: Id2f010589e2bd6faf42c05bb33abf6816ebe9fa9
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index f80ebdb..e4ccd96 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 @@
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 @@
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 @@
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 @@
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;