diff options
author | Vladimir Marko <vmarko@google.com> | 2014-02-18 14:41:21 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-02-18 14:41:21 +0000 |
commit | 2befd09cf4fe89a18a655f3e1dd310831bfa769f (patch) | |
tree | 9329308374370e1db721cb4d1e4723daa6001fdf | |
parent | 46861fccd9b5efb3226e2003310f01e748aec0a1 (diff) | |
parent | 84c072c348006d87a370ad6e746e2d976cbe62f2 (diff) | |
download | art-2befd09cf4fe89a18a655f3e1dd310831bfa769f.tar.gz art-2befd09cf4fe89a18a655f3e1dd310831bfa769f.tar.bz2 art-2befd09cf4fe89a18a655f3e1dd310831bfa769f.zip |
Merge "Expose inline method identification for debugger."
-rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.cc | 46 | ||||
-rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.h | 15 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 1 |
3 files changed, 41 insertions, 21 deletions
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc index 46d846a722..cb424d9169 100644 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ b/compiler/dex/quick/dex_file_method_inliner.cc @@ -271,6 +271,13 @@ DexFileMethodInliner::~DexFileMethodInliner() { } 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 @@ bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) 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 @@ bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) 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 @@ bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) 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) { @@ -631,6 +629,11 @@ bool DexFileMethodInliner::AnalyseIGetMethod(verifier::MethodVerifier* verifier, 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; @@ -643,6 +646,7 @@ bool DexFileMethodInliner::AnalyseIGetMethod(verifier::MethodVerifier* verifier, 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; } @@ -674,6 +678,11 @@ bool DexFileMethodInliner::AnalyseIPutMethod(verifier::MethodVerifier* verifier, 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; @@ -686,6 +695,7 @@ bool DexFileMethodInliner::AnalyseIPutMethod(verifier::MethodVerifier* verifier, 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 f4c2d6704a..3dcb964fab 100644 --- a/compiler/dex/quick/dex_file_method_inliner.h +++ b/compiler/dex/quick/dex_file_method_inliner.h @@ -150,13 +150,24 @@ class DexFileMethodInliner { * 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 c72c1c5580..b46ae2b85d 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -938,7 +938,6 @@ bool CompilerDriver::ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put, 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(); |