Expose inline method identification for debugger.
Also, record only those getter/setter functions which
we really intend to inline in the short term (and which
actually have a special implementation emitted).
Change-Id: Icb8d71707a65cb6fabae5bc9118e5f3eaf7b63dd
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 389dd9a..4c791a2 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -271,6 +271,13 @@
}
bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) {
+ InlineMethod method;
+ bool success = AnalyseMethodCode(verifier, &method);
+ return success && AddInlineMethod(verifier->GetMethodReference().dex_method_index, method);
+}
+
+bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier,
+ InlineMethod* method) {
// We currently support only plain return or 2-instruction methods.
const DexFile::CodeItem* code_item = verifier->CodeItem();
@@ -278,27 +285,22 @@
const Instruction* instruction = Instruction::At(code_item->insns_);
Instruction::Code opcode = instruction->Opcode();
- InlineMethod method;
- bool success;
switch (opcode) {
case Instruction::RETURN_VOID:
- method.opcode = kInlineOpNop;
- method.flags = kInlineSpecial;
- method.d.data = 0u;
- success = true;
- break;
+ method->opcode = kInlineOpNop;
+ method->flags = kInlineSpecial;
+ method->d.data = 0u;
+ return true;
case Instruction::RETURN:
case Instruction::RETURN_OBJECT:
case Instruction::RETURN_WIDE:
- success = AnalyseReturnMethod(code_item, &method);
- break;
+ return AnalyseReturnMethod(code_item, method);
case Instruction::CONST:
case Instruction::CONST_4:
case Instruction::CONST_16:
case Instruction::CONST_HIGH16:
// TODO: Support wide constants (RETURN_WIDE).
- success = AnalyseConstMethod(code_item, &method);
- break;
+ return AnalyseConstMethod(code_item, method);
case Instruction::IGET:
case Instruction::IGET_OBJECT:
case Instruction::IGET_BOOLEAN:
@@ -306,8 +308,7 @@
case Instruction::IGET_CHAR:
case Instruction::IGET_SHORT:
case Instruction::IGET_WIDE:
- success = AnalyseIGetMethod(verifier, &method);
- break;
+ return AnalyseIGetMethod(verifier, method);
case Instruction::IPUT:
case Instruction::IPUT_OBJECT:
case Instruction::IPUT_BOOLEAN:
@@ -315,13 +316,10 @@
case Instruction::IPUT_CHAR:
case Instruction::IPUT_SHORT:
case Instruction::IPUT_WIDE:
- success = AnalyseIPutMethod(verifier, &method);
- break;
+ return AnalyseIPutMethod(verifier, method);
default:
- success = false;
- break;
+ return false;
}
- return success && AddInlineMethod(verifier->GetMethodReference().dex_method_index, method);
}
bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index) {
@@ -633,6 +631,11 @@
return false; // Not returning the value retrieved by IGET?
}
+ if ((verifier->GetAccessFlags() & kAccStatic) != 0 || object_reg != arg_start) {
+ // TODO: Support inlining IGET on other register than "this".
+ return false;
+ }
+
if (!CompilerDriver::ComputeSpecialAccessorInfo(field_idx, false, verifier,
&result->d.ifield_data)) {
return false;
@@ -645,6 +648,7 @@
data->is_object = (opcode == Instruction::IGET_OBJECT) ? 1u : 0u;
data->object_arg = object_reg - arg_start; // Allow IGET on any register, not just "this".
data->src_arg = 0;
+ data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0;
data->reserved = 0;
return true;
}
@@ -676,6 +680,11 @@
DCHECK_GE(src_reg, arg_start);
DCHECK_LT(size == kLong ? src_reg + 1 : src_reg, code_item->registers_size_);
+ if ((verifier->GetAccessFlags() & kAccStatic) != 0 || object_reg != arg_start) {
+ // TODO: Support inlining IPUT on other register than "this".
+ return false;
+ }
+
if (!CompilerDriver::ComputeSpecialAccessorInfo(field_idx, true, verifier,
&result->d.ifield_data)) {
return false;
@@ -688,6 +697,7 @@
data->is_object = (opcode == Instruction::IPUT_OBJECT) ? 1u : 0u;
data->object_arg = object_reg - arg_start; // Allow IPUT on any register, not just "this".
data->src_arg = src_reg - arg_start;
+ data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0;
data->reserved = 0;
return true;
}
diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h
index fb7528e..ab96715 100644
--- a/compiler/dex/quick/dex_file_method_inliner.h
+++ b/compiler/dex/quick/dex_file_method_inliner.h
@@ -150,13 +150,24 @@
* Analyse method code to determine if the method is a candidate for inlining.
* If it is, record its data for later.
*
- * @param method_idx the index of the inlining candidate.
- * @param code_item a previously verified code item of the method.
+ * @param verifier the method verifier holding data about the method to analyse.
+ * @return true if the method is a candidate for inlining, false otherwise.
*/
bool AnalyseMethodCode(verifier::MethodVerifier* verifier)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(lock_);
/**
+ * Analyse method code to determine if the method is a candidate for inlining.
+ * If it is, record the inlining data.
+ *
+ * @param verifier the method verifier holding data about the method to analyse.
+ * @param method placeholder for the inline method data.
+ * @return true if the method is a candidate for inlining, false otherwise.
+ */
+ bool AnalyseMethodCode(verifier::MethodVerifier* verifier, InlineMethod* method)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(lock_);
+
+ /**
* Check whether a particular method index corresponds to an intrinsic function.
*/
bool IsIntrinsic(uint32_t method_index) LOCKS_EXCLUDED(lock_);
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 8678ad9..cd089ab 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1017,7 +1017,6 @@
return false;
}
DCHECK_GE(field->GetOffset().Int32Value(), 0);
- result->method_is_static = method->IsStatic();
result->field_idx = field_idx;
result->field_offset = field->GetOffset().Int32Value();
result->is_volatile = field->IsVolatile();