diff options
author | David Sehr <sehr@google.com> | 2018-01-25 17:11:07 -0800 |
---|---|---|
committer | David Sehr <sehr@google.com> | 2018-01-30 01:17:58 -0800 |
commit | b40b7e73469339a6b667b4a2e2b8690112a74dc9 (patch) | |
tree | 7e8a34d9c7894c4c946f674f19f0a0a512b95184 | |
parent | 9690ad794b324ba54e936608881ac0f62538b97a (diff) | |
download | android_art-b40b7e73469339a6b667b4a2e2b8690112a74dc9.tar.gz android_art-b40b7e73469339a6b667b4a2e2b8690112a74dc9.tar.bz2 android_art-b40b7e73469339a6b667b4a2e2b8690112a74dc9.zip |
Make libdexfile build independent of runtime dir
Remove libdexfile's dependency on utils.cc and move utf.cc into
/dex. Remove libdexfile's constituent sources from libart and
use libdexfile wherever libart is. Also remove some ART-specific
interfaces. Libdexfile's tests remain to be converted, plus
moving the files to a new directory peer to runtime/.
Bug: 22322814
Test: make -j 50 test-art-host
Change-Id: Ifaf695216e4a0e43d3aa377984d933f7a2a243c2
81 files changed, 864 insertions, 369 deletions
diff --git a/Android.bp b/Android.bp index caf4f9a325..4bcceffcd1 100644 --- a/Android.bp +++ b/Android.bp @@ -1,6 +1,7 @@ // TODO: These should be handled with transitive static library dependencies art_static_dependencies = [ // Note: the order is important because of static linking resolution. + "libdexfile", "libziparchive", "libnativehelper", "libnativebridge", diff --git a/compiler/Android.bp b/compiler/Android.bp index 2e60e7d658..453965947d 100644 --- a/compiler/Android.bp +++ b/compiler/Android.bp @@ -184,6 +184,7 @@ art_cc_defaults { }, generated_sources: ["art_compiler_operator_srcs"], shared_libs: [ + "libdexfile", "libbase", "libcutils", // for atrace. "liblzma", diff --git a/compiler/dex/inline_method_analyser.cc b/compiler/dex/inline_method_analyser.cc index ce67b85b99..dc044c1210 100644 --- a/compiler/dex/inline_method_analyser.cc +++ b/compiler/dex/inline_method_analyser.cc @@ -142,7 +142,7 @@ ArtMethod* GetTargetConstructor(ArtMethod* method, const Instruction* invoke_dir REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK_EQ(invoke_direct->Opcode(), Instruction::INVOKE_DIRECT); if (kIsDebugBuild) { - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); DCHECK_EQ(invoke_direct->VRegC_35c(), accessor.RegistersSize() - accessor.InsSize()); } @@ -324,9 +324,9 @@ bool DoAnalyseConstructor(const CodeItemDataAccessor* code_item, return false; } if (target_method->GetDeclaringClass()->IsObjectClass()) { - DCHECK_EQ(CodeItemDataAccessor(target_method).begin()->Opcode(), Instruction::RETURN_VOID); + DCHECK_EQ(target_method->DexInstructionData().begin()->Opcode(), Instruction::RETURN_VOID); } else { - CodeItemDataAccessor target_code_item(target_method); + CodeItemDataAccessor target_code_item(target_method->DexInstructionData()); if (!target_code_item.HasCodeItem()) { return false; // Native constructor? } @@ -430,7 +430,7 @@ static_assert(InlineMethodAnalyser::IGetVariant(Instruction::IGET_SHORT) == InlineMethodAnalyser::IPutVariant(Instruction::IPUT_SHORT), "iget/iput_short variant"); bool InlineMethodAnalyser::AnalyseMethodCode(ArtMethod* method, InlineMethod* result) { - CodeItemDataAccessor code_item(method); + CodeItemDataAccessor code_item(method->DexInstructionData()); if (!code_item.HasCodeItem()) { // Native or abstract. return false; diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 60537fd5c8..c617f54f55 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -932,7 +932,7 @@ class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor { if (method->GetCodeItem() == nullptr) { return; // native or abstract method } - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); if (accessor.TriesSize() == 0) { return; // nothing to process } diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 452be6feae..035e5ce3e1 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -392,8 +392,9 @@ ArtMethod* HInliner::TryCHADevirtualization(ArtMethod* resolved_method) { return single_impl; } -static bool AlwaysThrows(ArtMethod* method) { - CodeItemDataAccessor accessor(method); +static bool AlwaysThrows(ArtMethod* method) + REQUIRES_SHARED(Locks::mutator_lock_) { + CodeItemDataAccessor accessor(method->DexInstructionData()); // Skip native methods, methods with try blocks, and methods that are too large. if (!accessor.HasCodeItem() || accessor.TriesSize() != 0 || @@ -1418,7 +1419,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, bool same_dex_file = IsSameDexFile(*outer_compilation_unit_.GetDexFile(), *method->GetDexFile()); - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); if (!accessor.HasCodeItem()) { LOG_FAIL_NO_STAT() @@ -1697,7 +1698,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, const DexFile::CodeItem* code_item = resolved_method->GetCodeItem(); const DexFile& callee_dex_file = *resolved_method->GetDexFile(); uint32_t method_index = resolved_method->GetDexMethodIndex(); - CodeItemDebugInfoAccessor code_item_accessor(resolved_method); + CodeItemDebugInfoAccessor code_item_accessor(resolved_method->DexInstructionDebugInfo()); ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); Handle<mirror::DexCache> dex_cache = NewHandleIfDifferent(resolved_method->GetDexCache(), caller_compilation_unit_.GetDexCache(), diff --git a/dex2oat/Android.bp b/dex2oat/Android.bp index 9876febfc5..ab06ddda2d 100644 --- a/dex2oat/Android.bp +++ b/dex2oat/Android.bp @@ -106,7 +106,6 @@ cc_defaults { compile_multilib: "prefer32", }, }, - header_libs: [ "dex2oat_headers", "art_cmdlineparser_headers", @@ -122,6 +121,7 @@ art_cc_binary { "libart-compiler", "libart-dexlayout", "libart", + "libdexfile", "libbase", "liblz4", "libsigchain", @@ -152,6 +152,7 @@ art_cc_binary { "libartd-compiler", "libartd-dexlayout", "libartd", + "libdexfile", "libbase", "liblz4", "libsigchain", diff --git a/dexdump/Android.bp b/dexdump/Android.bp index eca08448bc..f6b7a6b68a 100644 --- a/dexdump/Android.bp +++ b/dexdump/Android.bp @@ -45,7 +45,6 @@ art_cc_binary { host_supported: true, device_supported: false, static_libs: [ - "libdexfile", "libbase", ] + art_static_dependencies, target: { diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 24f41aba2e..01b28b55cf 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -50,7 +50,7 @@ #include "android-base/logging.h" #include "android-base/stringprintf.h" -#include "dex/code_item_accessors-no_art-inl.h" +#include "dex/code_item_accessors-inl.h" #include "dex/dex_file-inl.h" #include "dex/dex_file_exception_helpers.h" #include "dex/dex_file_loader.h" diff --git a/dexdump/dexdump_cfg.cc b/dexdump/dexdump_cfg.cc index 0e313572bc..69ee0682a3 100644 --- a/dexdump/dexdump_cfg.cc +++ b/dexdump/dexdump_cfg.cc @@ -25,7 +25,7 @@ #include <set> #include <sstream> -#include "dex/code_item_accessors-no_art-inl.h" +#include "dex/code_item_accessors-inl.h" #include "dex/dex_file-inl.h" #include "dex/dex_file_exception_helpers.h" #include "dex/dex_instruction-inl.h" diff --git a/dexlayout/Android.bp b/dexlayout/Android.bp index 63650bf121..3ea7f4ba82 100644 --- a/dexlayout/Android.bp +++ b/dexlayout/Android.bp @@ -26,7 +26,10 @@ art_cc_defaults { "dex_writer.cc", ], export_include_dirs: ["."], - shared_libs: ["libbase"], + shared_libs: [ + "libdexfile", + "libbase", + ], static_libs: ["libz"], } diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h index 1a84d2307d..d28b824c7b 100644 --- a/dexlayout/dex_ir.h +++ b/dexlayout/dex_ir.h @@ -27,8 +27,8 @@ #include "base/stl_util.h" #include "dex/dex_file-inl.h" #include "dex/dex_file_types.h" +#include "dex/utf.h" #include "leb128.h" -#include "utf.h" namespace art { namespace dex_ir { diff --git a/dexlayout/dex_writer.cc b/dexlayout/dex_writer.cc index 778681e7b7..808bfad029 100644 --- a/dexlayout/dex_writer.cc +++ b/dexlayout/dex_writer.cc @@ -25,8 +25,8 @@ #include "dex/dex_file_layout.h" #include "dex/dex_file_types.h" #include "dex/standard_dex_file.h" +#include "dex/utf.h" #include "dexlayout.h" -#include "utf.h" namespace art { diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc index ca02052299..31a146d90e 100644 --- a/dexlist/dexlist.cc +++ b/dexlist/dexlist.cc @@ -34,7 +34,7 @@ #include <android-base/logging.h> -#include "dex/code_item_accessors-no_art-inl.h" +#include "dex/code_item_accessors-inl.h" #include "dex/dex_file-inl.h" #include "dex/dex_file_loader.h" diff --git a/oatdump/Android.bp b/oatdump/Android.bp index 4851722734..c93c172eb4 100644 --- a/oatdump/Android.bp +++ b/oatdump/Android.bp @@ -36,6 +36,7 @@ art_cc_binary { "libart", "libart-compiler", "libart-disassembler", + "libdexfile", "libbase", ], } @@ -50,6 +51,7 @@ art_cc_binary { "libartd", "libartd-compiler", "libartd-disassembler", + "libdexfile", "libbase", ], } diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 4324dbad65..6c9f569b19 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -2548,7 +2548,7 @@ class ImageDumper { } } } else { - CodeItemDataAccessor code_item_accessor(method); + CodeItemDataAccessor code_item_accessor(method->DexInstructionData()); size_t dex_instruction_bytes = code_item_accessor.InsnsSizeInCodeUnits() * 2; stats_.dex_instruction_bytes += dex_instruction_bytes; diff --git a/openjdkjvmti/Android.bp b/openjdkjvmti/Android.bp index 0283999d54..1500bcae24 100644 --- a/openjdkjvmti/Android.bp +++ b/openjdkjvmti/Android.bp @@ -58,6 +58,7 @@ cc_defaults { "libopenjdkjvmti_headers", ], shared_libs: [ + "libdexfile", "libbase", ], } diff --git a/openjdkjvmti/ti_class_loader.h b/openjdkjvmti/ti_class_loader.h index 27ea3f5191..ceb7b331de 100644 --- a/openjdkjvmti/ti_class_loader.h +++ b/openjdkjvmti/ti_class_loader.h @@ -41,6 +41,7 @@ #include "base/array_slice.h" #include "class_linker.h" #include "dex/dex_file.h" +#include "dex/utf.h" #include "gc_root-inl.h" #include "globals.h" #include "jni_env_ext-inl.h" @@ -60,7 +61,6 @@ #include "thread_list.h" #include "ti_class_definition.h" #include "transform.h" -#include "utf.h" #include "utils/dex_cache_arrays_layout-inl.h" namespace openjdkjvmti { diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc index 3f144c8f0f..83d64ef1d8 100644 --- a/openjdkjvmti/ti_method.cc +++ b/openjdkjvmti/ti_method.cc @@ -123,7 +123,7 @@ jvmtiError MethodUtil::GetBytecodes(jvmtiEnv* env, } art::ScopedObjectAccess soa(art::Thread::Current()); - art::CodeItemInstructionAccessor accessor(art_method); + art::CodeItemInstructionAccessor accessor(art_method->DexInstructions()); if (!accessor.HasCodeItem()) { *size_ptr = 0; *bytecode_ptr = nullptr; @@ -168,7 +168,7 @@ jvmtiError MethodUtil::GetArgumentsSize(jvmtiEnv* env ATTRIBUTE_UNUSED, } DCHECK_NE(art_method->GetCodeItemOffset(), 0u); - *size_ptr = art::CodeItemDataAccessor(art_method).InsSize(); + *size_ptr = art_method->DexInstructionData().InsSize(); return ERR(NONE); } @@ -200,7 +200,7 @@ jvmtiError MethodUtil::GetLocalVariableTable(jvmtiEnv* env, // TODO HasCodeItem == false means that the method is abstract (or native, but we check that // earlier). We should check what is returned by the RI in this situation since it's not clear // what the appropriate return value is from the spec. - art::CodeItemDebugInfoAccessor accessor(art_method); + art::CodeItemDebugInfoAccessor accessor(art_method->DexInstructionDebugInfo()); if (!accessor.HasCodeItem()) { return ERR(ABSENT_INFORMATION); } @@ -301,7 +301,7 @@ jvmtiError MethodUtil::GetMaxLocals(jvmtiEnv* env ATTRIBUTE_UNUSED, } DCHECK_NE(art_method->GetCodeItemOffset(), 0u); - *max_ptr = art::CodeItemDataAccessor(art_method).RegistersSize(); + *max_ptr = art_method->DexInstructionData().RegistersSize(); return ERR(NONE); } @@ -480,7 +480,7 @@ jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env, return ERR(NULL_POINTER); } - accessor = art::CodeItemDebugInfoAccessor(art_method); + accessor = art::CodeItemDebugInfoAccessor(art_method->DexInstructionDebugInfo()); dex_file = art_method->GetDexFile(); DCHECK(accessor.HasCodeItem()) << art_method->PrettyMethod() << " " << dex_file->GetLocation(); } @@ -567,7 +567,7 @@ class CommonLocalVariableClosure : public art::Closure { // TODO It might be useful to fake up support for get at least on proxy frames. result_ = ERR(OPAQUE_FRAME); return; - } else if (art::CodeItemDataAccessor(method).RegistersSize() <= slot_) { + } else if (method->DexInstructionData().RegistersSize() <= slot_) { result_ = ERR(INVALID_SLOT); return; } @@ -618,7 +618,7 @@ class CommonLocalVariableClosure : public art::Closure { if (dex_file == nullptr) { return ERR(OPAQUE_FRAME); } - art::CodeItemDebugInfoAccessor accessor(method); + art::CodeItemDebugInfoAccessor accessor(method->DexInstructionDebugInfo()); if (!accessor.HasCodeItem()) { return ERR(OPAQUE_FRAME); } diff --git a/openjdkjvmti/ti_redefine.h b/openjdkjvmti/ti_redefine.h index b537e1b01c..c920707afd 100644 --- a/openjdkjvmti/ti_redefine.h +++ b/openjdkjvmti/ti_redefine.h @@ -41,6 +41,7 @@ #include "base/array_ref.h" #include "class_linker.h" #include "dex/dex_file.h" +#include "dex/utf.h" #include "gc_root-inl.h" #include "globals.h" #include "jni_env_ext-inl.h" @@ -60,7 +61,6 @@ #include "thread_list.h" #include "ti_class_definition.h" #include "transform.h" -#include "utf.h" #include "utils/dex_cache_arrays_layout-inl.h" namespace openjdkjvmti { diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc index bc77753f8f..373944f179 100644 --- a/openjdkjvmti/ti_stack.cc +++ b/openjdkjvmti/ti_stack.cc @@ -1045,7 +1045,7 @@ jvmtiError StackUtil::NotifyFramePop(jvmtiEnv* env, jthread thread, jint depth) if (shadow_frame == nullptr) { needs_instrument = true; const size_t frame_id = visitor.GetFrameId(); - const uint16_t num_regs = art::CodeItemDataAccessor(method).RegistersSize(); + const uint16_t num_regs = method->DexInstructionData().RegistersSize(); shadow_frame = target->FindOrCreateDebuggerShadowFrame(frame_id, num_regs, method, diff --git a/openjdkjvmti/transform.cc b/openjdkjvmti/transform.cc index 3a5fcccf35..181db15d82 100644 --- a/openjdkjvmti/transform.cc +++ b/openjdkjvmti/transform.cc @@ -39,6 +39,7 @@ #include "class_linker.h" #include "dex/dex_file.h" #include "dex/dex_file_types.h" +#include "dex/utf.h" #include "events-inl.h" #include "gc_root-inl.h" #include "globals.h" @@ -58,7 +59,6 @@ #include "thread_list.h" #include "ti_redefine.h" #include "transform.h" -#include "utf.h" #include "utils/dex_cache_arrays_layout-inl.h" namespace openjdkjvmti { diff --git a/profman/Android.bp b/profman/Android.bp index ea682b40a0..6592b9dec0 100644 --- a/profman/Android.bp +++ b/profman/Android.bp @@ -31,6 +31,7 @@ cc_defaults { }, shared_libs: [ + "libdexfile", "libbase", ], } diff --git a/runtime/Android.bp b/runtime/Android.bp index a759cf700f..db9bceaf29 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -21,6 +21,7 @@ cc_defaults { srcs: [ "dex/compact_dex_debug_info.cc", "dex/compact_dex_file.cc", + "dex/descriptors_names.cc", "dex/dex_file.cc", "dex/dex_file_exception_helpers.cc", "dex/dex_file_loader.cc", @@ -29,8 +30,7 @@ cc_defaults { "dex/dex_instruction.cc", "dex/modifiers.cc", "dex/standard_dex_file.cc", - "utf.cc", - "utils.cc", + "dex/utf.cc", ], target: { @@ -51,7 +51,7 @@ cc_defaults { ], }, }, - generated_sources: ["art_operator_srcs"], + generated_sources: ["dexfile_operator_srcs"], include_dirs: [ "external/zlib", ], @@ -133,19 +133,9 @@ cc_defaults { "common_throws.cc", "compiler_filter.cc", "debugger.cc", - "dex/compact_dex_debug_info.cc", - "dex/compact_dex_file.cc", - "dex/dex_file.cc", "dex/dex_file_annotations.cc", - "dex/dex_file_exception_helpers.cc", "dex/dex_file_layout.cc", - "dex/dex_file_loader.cc", "dex/art_dex_file_loader.cc", - "dex/dex_file_tracking_registrar.cc", - "dex/dex_file_verifier.cc", - "dex/dex_instruction.cc", - "dex/modifiers.cc", - "dex/standard_dex_file.cc", "dex_to_dex_decompiler.cc", "elf_file.cc", "exec_utils.cc", @@ -302,7 +292,6 @@ cc_defaults { "trace.cc", "transaction.cc", "type_lookup_table.cc", - "utf.cc", "utils.cc", "vdex_file.cc", "verifier/instruction_flags.cc", @@ -498,6 +487,7 @@ cc_defaults { "jni_platform_headers", ], shared_libs: [ + "libdexfile", "libnativebridge", "libnativeloader", "libbacktrace", @@ -534,11 +524,7 @@ gensrcs { "debugger.h", "base/unix_file/fd_file.h", "class_status.h", - "dex/dex_file.h", "dex/dex_file_layout.h", - "dex/dex_instruction.h", - "dex/dex_instruction_utils.h", - "dex/invoke_type.h", "gc_root.h", "gc/allocator_type.h", "gc/allocator/rosalloc.h", @@ -657,6 +643,7 @@ art_cc_test { "dex/dex_file_test.cc", "dex/dex_file_verifier_test.cc", "dex/dex_instruction_test.cc", + "dex/utf_test.cc", "entrypoints/math_entrypoints_test.cc", "entrypoints/quick/quick_trampoline_entrypoints_test.cc", "entrypoints_order_test.cc", @@ -710,7 +697,6 @@ art_cc_test { "thread_pool_test.cc", "transaction_test.cc", "type_lookup_table_test.cc", - "utf_test.cc", "utils_test.cc", "vdex_file_test.cc", "verifier/method_verifier_test.cc", diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 65bacd8237..17ac7fc462 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -466,7 +466,15 @@ inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize poi } inline CodeItemInstructionAccessor ArtMethod::DexInstructions() { - return CodeItemInstructionAccessor(this); + return CodeItemInstructionAccessor(*GetDexFile(), GetCodeItem()); +} + +inline CodeItemDataAccessor ArtMethod::DexInstructionData() { + return CodeItemDataAccessor(*GetDexFile(), GetCodeItem()); +} + +inline CodeItemDebugInfoAccessor ArtMethod::DexInstructionDebugInfo() { + return CodeItemDebugInfoAccessor(*GetDexFile(), GetCodeItem(), GetDexMethodIndex()); } } // namespace art diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 96468bba60..efdf5991ec 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -272,7 +272,7 @@ uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type, // Default to handler not found. uint32_t found_dex_pc = dex::kDexNoIndex; // Iterate over the catch handlers associated with dex_pc. - CodeItemDataAccessor accessor(this); + CodeItemDataAccessor accessor(DexInstructionData()); for (CatchHandlerIterator it(accessor, dex_pc); it.HasNext(); it.Next()) { dex::TypeIndex iter_type_idx = it.GetHandlerTypeIndex(); // Catch all case diff --git a/runtime/art_method.h b/runtime/art_method.h index ce8e8ac612..3838d85659 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -727,6 +727,14 @@ class ArtMethod FINAL { ALWAYS_INLINE CodeItemInstructionAccessor DexInstructions() REQUIRES_SHARED(Locks::mutator_lock_); + // Returns the dex code item data section of the DexFile for the art method. + ALWAYS_INLINE CodeItemDataAccessor DexInstructionData() + REQUIRES_SHARED(Locks::mutator_lock_); + + // Returns the dex code item debug info section of the DexFile for the art method. + ALWAYS_INLINE CodeItemDebugInfoAccessor DexInstructionDebugInfo() + REQUIRES_SHARED(Locks::mutator_lock_); + protected: // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". // The class we are a part of. diff --git a/runtime/base/file_utils.cc b/runtime/base/file_utils.cc index d22fd994ee..58990f344b 100644 --- a/runtime/base/file_utils.cc +++ b/runtime/base/file_utils.cc @@ -50,10 +50,10 @@ #include "dex/dex_file-inl.h" #include "dex/dex_file_loader.h" #include "dex/dex_instruction.h" +#include "dex/utf-inl.h" #include "oat_quick_method_header.h" #include "os.h" #include "scoped_thread_state_change-inl.h" -#include "utf-inl.h" #if defined(__APPLE__) #include <crt_externs.h> diff --git a/runtime/check_reference_map_visitor.h b/runtime/check_reference_map_visitor.h index 0c29e257a1..e2ad7fd83f 100644 --- a/runtime/check_reference_map_visitor.h +++ b/runtime/check_reference_map_visitor.h @@ -67,7 +67,7 @@ class CheckReferenceMapVisitor : public StackVisitor { CodeInfo code_info = GetCurrentOatQuickMethodHeader()->GetOptimizedCodeInfo(); CodeInfoEncoding encoding = code_info.ExtractEncoding(); StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding); - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); uint16_t number_of_dex_registers = accessor.RegistersSize(); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index af45a69bd5..32d304073c 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -53,6 +53,7 @@ #include "dex/dex_file-inl.h" #include "dex/dex_file_exception_helpers.h" #include "dex/dex_file_loader.h" +#include "dex/utf.h" #include "entrypoints/entrypoint_utils.h" #include "entrypoints/runtime_asm_entrypoints.h" #include "experimental_flags.h" @@ -115,7 +116,6 @@ #include "thread-inl.h" #include "thread_list.h" #include "trace.h" -#include "utf.h" #include "utils.h" #include "utils/dex_cache_arrays_layout-inl.h" #include "verifier/method_verifier.h" @@ -4329,7 +4329,7 @@ void ClassLinker::ResolveClassExceptionHandlerTypes(Handle<mirror::Class> klass) void ClassLinker::ResolveMethodExceptionHandlerTypes(ArtMethod* method) { // similar to DexVerifier::ScanTryCatchBlocks and dex2oat's ResolveExceptionsForMethod. - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); if (!accessor.HasCodeItem()) { return; // native or abstract method } diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc index 03774f45cd..19e7f7686d 100644 --- a/runtime/common_throws.cc +++ b/runtime/common_throws.cc @@ -551,7 +551,7 @@ static bool IsValidImplicitCheck(uintptr_t addr, const Instruction& instr) void ThrowNullPointerExceptionFromDexPC(bool check_address, uintptr_t addr) { uint32_t throw_dex_pc; ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc); - CodeItemInstructionAccessor accessor(method); + CodeItemInstructionAccessor accessor(method->DexInstructions()); CHECK_LT(throw_dex_pc, accessor.InsnsSizeInCodeUnits()); const Instruction& instr = accessor.InstructionAt(throw_dex_pc); if (check_address && !IsValidImplicitCheck(addr, instr)) { diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 842cd7330c..61ad725b79 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -37,6 +37,7 @@ #include "dex/dex_file_annotations.h" #include "dex/dex_file_types.h" #include "dex/dex_instruction.h" +#include "dex/utf.h" #include "entrypoints/runtime_asm_entrypoints.h" #include "gc/accounting/card_table-inl.h" #include "gc/allocation_record.h" @@ -66,7 +67,6 @@ #include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread_list.h" -#include "utf.h" #include "well_known_classes.h" namespace art { @@ -1533,7 +1533,7 @@ static uint32_t MangleAccessFlags(uint32_t accessFlags) { */ static uint16_t MangleSlot(uint16_t slot, ArtMethod* m) REQUIRES_SHARED(Locks::mutator_lock_) { - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); if (!accessor.HasCodeItem()) { // We should not get here for a method without code (native, proxy or abstract). Log it and // return the slot as is since all registers are arguments. @@ -1564,7 +1564,7 @@ static size_t GetMethodNumArgRegistersIncludingThis(ArtMethod* method) */ static uint16_t DemangleSlot(uint16_t slot, ArtMethod* m, JDWP::JdwpError* error) REQUIRES_SHARED(Locks::mutator_lock_) { - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); if (!accessor.HasCodeItem()) { // We should not get here for a method without code (native, proxy or abstract). Log it and // return the slot as is since all registers are arguments. @@ -1675,7 +1675,7 @@ void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::Expan } }; ArtMethod* m = FromMethodId(method_id); - CodeItemDebugInfoAccessor accessor(m); + CodeItemDebugInfoAccessor accessor(m->DexInstructionDebugInfo()); uint64_t start, end; if (!accessor.HasCodeItem()) { DCHECK(m->IsNative() || m->IsProxyMethod()); @@ -1741,7 +1741,7 @@ void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool wi } }; ArtMethod* m = FromMethodId(method_id); - CodeItemDebugInfoAccessor accessor(m); + CodeItemDebugInfoAccessor accessor(m->DexInstructionDebugInfo()); // arg_count considers doubles and longs to take 2 units. // variable_count considers everything to take 1 unit. @@ -1791,7 +1791,7 @@ JDWP::JdwpError Dbg::GetBytecodes(JDWP::RefTypeId, JDWP::MethodId method_id, if (m == nullptr) { return JDWP::ERR_INVALID_METHODID; } - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); size_t byte_count = accessor.InsnsSizeInCodeUnits() * 2; const uint8_t* begin = reinterpret_cast<const uint8_t*>(accessor.Insns()); const uint8_t* end = begin + byte_count; @@ -3908,7 +3908,7 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize // Note: if the thread is not running Java code (pure native thread), there is no "current" // method on the stack (and no line number either). if (m != nullptr && !m->IsNative()) { - CodeItemDebugInfoAccessor accessor(m); + CodeItemDebugInfoAccessor accessor(m->DexInstructionDebugInfo()); DebugCallbackContext context(single_step_control, line_number, accessor.InsnsSizeInCodeUnits()); m->GetDexFile()->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), DebugCallbackContext::Callback, diff --git a/runtime/dex/code_item_accessors-inl.h b/runtime/dex/code_item_accessors-inl.h index 63fd120991..9c39935d3b 100644 --- a/runtime/dex/code_item_accessors-inl.h +++ b/runtime/dex/code_item_accessors-inl.h @@ -17,26 +17,187 @@ #ifndef ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_INL_H_ #define ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_INL_H_ -#include "code_item_accessors-no_art-inl.h" +#include "code_item_accessors.h" -#include "art_method-inl.h" #include "compact_dex_file.h" #include "dex_file-inl.h" -#include "oat_file.h" #include "standard_dex_file.h" +// The no ART version is used by binaries that don't include the whole runtime. namespace art { -inline CodeItemInstructionAccessor::CodeItemInstructionAccessor(ArtMethod* method) - : CodeItemInstructionAccessor(*method->GetDexFile(), method->GetCodeItem()) {} +inline void CodeItemInstructionAccessor::Init(uint32_t insns_size_in_code_units, + const uint16_t* insns) { + insns_size_in_code_units_ = insns_size_in_code_units; + insns_ = insns; +} -inline CodeItemDataAccessor::CodeItemDataAccessor(ArtMethod* method) - : CodeItemDataAccessor(*method->GetDexFile(), method->GetCodeItem()) {} +inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) { + uint32_t insns_size_in_code_units; + code_item.DecodeFields</*kDecodeOnlyInstructionCount*/ true>( + &insns_size_in_code_units, + /*registers_size*/ nullptr, + /*ins_size*/ nullptr, + /*outs_size*/ nullptr, + /*tries_size*/ nullptr); + Init(insns_size_in_code_units, code_item.insns_); +} -inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(ArtMethod* method) - : CodeItemDebugInfoAccessor(*method->GetDexFile(), - method->GetCodeItem(), - method->GetDexMethodIndex()) {} +inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) { + Init(code_item.insns_size_in_code_units_, code_item.insns_); +} + +inline void CodeItemInstructionAccessor::Init(const DexFile& dex_file, + const DexFile::CodeItem* code_item) { + if (code_item != nullptr) { + DCHECK(dex_file.IsInDataSection(code_item)); + if (dex_file.IsCompactDexFile()) { + Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); + } else { + DCHECK(dex_file.IsStandardDexFile()); + Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } + } +} + +inline CodeItemInstructionAccessor::CodeItemInstructionAccessor( + const DexFile& dex_file, + const DexFile::CodeItem* code_item) { + Init(dex_file, code_item); +} + +inline DexInstructionIterator CodeItemInstructionAccessor::begin() const { + return DexInstructionIterator(insns_, 0u); +} + +inline DexInstructionIterator CodeItemInstructionAccessor::end() const { + return DexInstructionIterator(insns_, insns_size_in_code_units_); +} + +inline IterationRange<DexInstructionIterator> CodeItemInstructionAccessor::InstructionsFrom( + uint32_t start_dex_pc) const { + DCHECK_LT(start_dex_pc, InsnsSizeInCodeUnits()); + return { + DexInstructionIterator(insns_, start_dex_pc), + DexInstructionIterator(insns_, insns_size_in_code_units_) }; +} + +inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) { + uint32_t insns_size_in_code_units; + code_item.DecodeFields</*kDecodeOnlyInstructionCount*/ false>(&insns_size_in_code_units, + ®isters_size_, + &ins_size_, + &outs_size_, + &tries_size_); + CodeItemInstructionAccessor::Init(insns_size_in_code_units, code_item.insns_); +} + +inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) { + CodeItemInstructionAccessor::Init(code_item); + registers_size_ = code_item.registers_size_; + ins_size_ = code_item.ins_size_; + outs_size_ = code_item.outs_size_; + tries_size_ = code_item.tries_size_; +} + +inline void CodeItemDataAccessor::Init(const DexFile& dex_file, + const DexFile::CodeItem* code_item) { + if (code_item != nullptr) { + if (dex_file.IsCompactDexFile()) { + CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); + } else { + DCHECK(dex_file.IsStandardDexFile()); + CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } + } +} + +inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile& dex_file, + const DexFile::CodeItem* code_item) { + Init(dex_file, code_item); +} + +inline IterationRange<const DexFile::TryItem*> CodeItemDataAccessor::TryItems() const { + const DexFile::TryItem* try_items = DexFile::GetTryItems(end(), 0u); + return { + try_items, + try_items + TriesSize() }; +} + +inline const uint8_t* CodeItemDataAccessor::GetCatchHandlerData(size_t offset) const { + return DexFile::GetCatchHandlerData(end(), TriesSize(), offset); +} + +inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_dex_pc) const { + IterationRange<const DexFile::TryItem*> try_items(TryItems()); + int32_t index = DexFile::FindTryItem(try_items.begin(), + try_items.end() - try_items.begin(), + try_dex_pc); + return index != -1 ? &try_items.begin()[index] : nullptr; +} + +inline const void* CodeItemDataAccessor::CodeItemDataEnd() const { + const uint8_t* handler_data = GetCatchHandlerData(); + + if (TriesSize() == 0 || handler_data == nullptr) { + return &end().Inst(); + } + // Get the start of the handler data. + const uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data); + // Manually read each handler. + for (uint32_t i = 0; i < handlers_size; ++i) { + int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2; + if (uleb128_count <= 0) { + uleb128_count = -uleb128_count + 1; + } + for (int32_t j = 0; j < uleb128_count; ++j) { + DecodeUnsignedLeb128(&handler_data); + } + } + return reinterpret_cast<const void*>(handler_data); +} + +inline void CodeItemDebugInfoAccessor::Init(const DexFile& dex_file, + const DexFile::CodeItem* code_item, + uint32_t dex_method_index) { + if (code_item == nullptr) { + return; + } + dex_file_ = &dex_file; + if (dex_file.IsCompactDexFile()) { + Init(down_cast<const CompactDexFile::CodeItem&>(*code_item), dex_method_index); + } else { + DCHECK(dex_file.IsStandardDexFile()); + Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } +} + +inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item, + uint32_t dex_method_index) { + debug_info_offset_ = down_cast<const CompactDexFile*>(dex_file_)->GetDebugInfoOffset( + dex_method_index); + CodeItemDataAccessor::Init(code_item); +} + +inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) { + debug_info_offset_ = code_item.debug_info_off_; + CodeItemDataAccessor::Init(code_item); +} + +template<typename NewLocalCallback> +inline bool CodeItemDebugInfoAccessor::DecodeDebugLocalInfo(bool is_static, + uint32_t method_idx, + NewLocalCallback new_local, + void* context) const { + return dex_file_->DecodeDebugLocalInfo(RegistersSize(), + InsSize(), + InsnsSizeInCodeUnits(), + DebugInfoOffset(), + is_static, + method_idx, + new_local, + context); +} } // namespace art diff --git a/runtime/dex/code_item_accessors-no_art-inl.h b/runtime/dex/code_item_accessors-no_art-inl.h index a243a4a6f4..8082be3818 100644 --- a/runtime/dex/code_item_accessors-no_art-inl.h +++ b/runtime/dex/code_item_accessors-no_art-inl.h @@ -17,188 +17,7 @@ #ifndef ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_NO_ART_INL_H_ #define ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_NO_ART_INL_H_ -#include "code_item_accessors.h" - -#include "compact_dex_file.h" -#include "dex_file-inl.h" -#include "standard_dex_file.h" - -// The no ART version is used by binaries that don't include the whole runtime. -namespace art { - -inline void CodeItemInstructionAccessor::Init(uint32_t insns_size_in_code_units, - const uint16_t* insns) { - insns_size_in_code_units_ = insns_size_in_code_units; - insns_ = insns; -} - -inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) { - uint32_t insns_size_in_code_units; - code_item.DecodeFields</*kDecodeOnlyInstructionCount*/ true>( - &insns_size_in_code_units, - /*registers_size*/ nullptr, - /*ins_size*/ nullptr, - /*outs_size*/ nullptr, - /*tries_size*/ nullptr); - Init(insns_size_in_code_units, code_item.insns_); -} - -inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) { - Init(code_item.insns_size_in_code_units_, code_item.insns_); -} - -inline void CodeItemInstructionAccessor::Init(const DexFile& dex_file, - const DexFile::CodeItem* code_item) { - if (code_item != nullptr) { - DCHECK(dex_file.IsInDataSection(code_item)); - if (dex_file.IsCompactDexFile()) { - Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); - } else { - DCHECK(dex_file.IsStandardDexFile()); - Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); - } - } -} - -inline CodeItemInstructionAccessor::CodeItemInstructionAccessor( - const DexFile& dex_file, - const DexFile::CodeItem* code_item) { - Init(dex_file, code_item); -} - -inline DexInstructionIterator CodeItemInstructionAccessor::begin() const { - return DexInstructionIterator(insns_, 0u); -} - -inline DexInstructionIterator CodeItemInstructionAccessor::end() const { - return DexInstructionIterator(insns_, insns_size_in_code_units_); -} - -inline IterationRange<DexInstructionIterator> CodeItemInstructionAccessor::InstructionsFrom( - uint32_t start_dex_pc) const { - DCHECK_LT(start_dex_pc, InsnsSizeInCodeUnits()); - return { - DexInstructionIterator(insns_, start_dex_pc), - DexInstructionIterator(insns_, insns_size_in_code_units_) }; -} - -inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) { - uint32_t insns_size_in_code_units; - code_item.DecodeFields</*kDecodeOnlyInstructionCount*/ false>(&insns_size_in_code_units, - ®isters_size_, - &ins_size_, - &outs_size_, - &tries_size_); - CodeItemInstructionAccessor::Init(insns_size_in_code_units, code_item.insns_); -} - -inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) { - CodeItemInstructionAccessor::Init(code_item); - registers_size_ = code_item.registers_size_; - ins_size_ = code_item.ins_size_; - outs_size_ = code_item.outs_size_; - tries_size_ = code_item.tries_size_; -} - -inline void CodeItemDataAccessor::Init(const DexFile& dex_file, - const DexFile::CodeItem* code_item) { - if (code_item != nullptr) { - if (dex_file.IsCompactDexFile()) { - CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); - } else { - DCHECK(dex_file.IsStandardDexFile()); - CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); - } - } -} - -inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile& dex_file, - const DexFile::CodeItem* code_item) { - Init(dex_file, code_item); -} - -inline IterationRange<const DexFile::TryItem*> CodeItemDataAccessor::TryItems() const { - const DexFile::TryItem* try_items = DexFile::GetTryItems(end(), 0u); - return { - try_items, - try_items + TriesSize() }; -} - -inline const uint8_t* CodeItemDataAccessor::GetCatchHandlerData(size_t offset) const { - return DexFile::GetCatchHandlerData(end(), TriesSize(), offset); -} - -inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_dex_pc) const { - IterationRange<const DexFile::TryItem*> try_items(TryItems()); - int32_t index = DexFile::FindTryItem(try_items.begin(), - try_items.end() - try_items.begin(), - try_dex_pc); - return index != -1 ? &try_items.begin()[index] : nullptr; -} - -inline const void* CodeItemDataAccessor::CodeItemDataEnd() const { - const uint8_t* handler_data = GetCatchHandlerData(); - - if (TriesSize() == 0 || handler_data == nullptr) { - return &end().Inst(); - } - // Get the start of the handler data. - const uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data); - // Manually read each handler. - for (uint32_t i = 0; i < handlers_size; ++i) { - int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2; - if (uleb128_count <= 0) { - uleb128_count = -uleb128_count + 1; - } - for (int32_t j = 0; j < uleb128_count; ++j) { - DecodeUnsignedLeb128(&handler_data); - } - } - return reinterpret_cast<const void*>(handler_data); -} - -inline void CodeItemDebugInfoAccessor::Init(const DexFile& dex_file, - const DexFile::CodeItem* code_item, - uint32_t dex_method_index) { - if (code_item == nullptr) { - return; - } - dex_file_ = &dex_file; - if (dex_file.IsCompactDexFile()) { - Init(down_cast<const CompactDexFile::CodeItem&>(*code_item), dex_method_index); - } else { - DCHECK(dex_file.IsStandardDexFile()); - Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); - } -} - -inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item, - uint32_t dex_method_index) { - debug_info_offset_ = down_cast<const CompactDexFile*>(dex_file_)->GetDebugInfoOffset( - dex_method_index); - CodeItemDataAccessor::Init(code_item); -} - -inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) { - debug_info_offset_ = code_item.debug_info_off_; - CodeItemDataAccessor::Init(code_item); -} - -template<typename NewLocalCallback> -inline bool CodeItemDebugInfoAccessor::DecodeDebugLocalInfo(bool is_static, - uint32_t method_idx, - NewLocalCallback new_local, - void* context) const { - return dex_file_->DecodeDebugLocalInfo(RegistersSize(), - InsSize(), - InsnsSizeInCodeUnits(), - DebugInfoOffset(), - is_static, - method_idx, - new_local, - context); -} - -} // namespace art +// TODO: delete this file once system/core is updated. +#include "code_item_accessors-inl.h" #endif // ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_NO_ART_INL_H_ diff --git a/runtime/dex/code_item_accessors.h b/runtime/dex/code_item_accessors.h index 08f823cae8..beb78f6e4f 100644 --- a/runtime/dex/code_item_accessors.h +++ b/runtime/dex/code_item_accessors.h @@ -85,8 +85,6 @@ class CodeItemDataAccessor : public CodeItemInstructionAccessor { public: ALWAYS_INLINE CodeItemDataAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item); - ALWAYS_INLINE explicit CodeItemDataAccessor(ArtMethod* method); - uint16_t RegistersSize() const { return registers_size_; } diff --git a/runtime/dex/code_item_accessors_test.cc b/runtime/dex/code_item_accessors_test.cc index 8e2548bf3d..1bd12a6f09 100644 --- a/runtime/dex/code_item_accessors_test.cc +++ b/runtime/dex/code_item_accessors_test.cc @@ -16,6 +16,7 @@ #include "code_item_accessors-inl.h" +#include <sys/mman.h> #include <memory> #include "common_runtime_test.h" diff --git a/runtime/dex/compact_dex_file.cc b/runtime/dex/compact_dex_file.cc index 37f5d0074c..ce289d4d7b 100644 --- a/runtime/dex/compact_dex_file.cc +++ b/runtime/dex/compact_dex_file.cc @@ -16,7 +16,7 @@ #include "compact_dex_file.h" -#include "code_item_accessors-no_art-inl.h" +#include "code_item_accessors-inl.h" #include "dex_file-inl.h" #include "leb128.h" diff --git a/runtime/dex/descriptors_names.cc b/runtime/dex/descriptors_names.cc new file mode 100644 index 0000000000..8124e7256f --- /dev/null +++ b/runtime/dex/descriptors_names.cc @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "descriptors_names.h" + +#include "android-base/stringprintf.h" +#include "android-base/strings.h" + +#include "dex/utf-inl.h" + +namespace art { + +using android::base::StringAppendF; +using android::base::StringPrintf; + +void AppendPrettyDescriptor(const char* descriptor, std::string* result) { + // Count the number of '['s to get the dimensionality. + const char* c = descriptor; + size_t dim = 0; + while (*c == '[') { + dim++; + c++; + } + + // Reference or primitive? + if (*c == 'L') { + // "[[La/b/C;" -> "a.b.C[][]". + c++; // Skip the 'L'. + } else { + // "[[B" -> "byte[][]". + // To make life easier, we make primitives look like unqualified + // reference types. + switch (*c) { + case 'B': c = "byte;"; break; + case 'C': c = "char;"; break; + case 'D': c = "double;"; break; + case 'F': c = "float;"; break; + case 'I': c = "int;"; break; + case 'J': c = "long;"; break; + case 'S': c = "short;"; break; + case 'Z': c = "boolean;"; break; + case 'V': c = "void;"; break; // Used when decoding return types. + default: result->append(descriptor); return; + } + } + + // At this point, 'c' is a string of the form "fully/qualified/Type;" + // or "primitive;". Rewrite the type with '.' instead of '/': + const char* p = c; + while (*p != ';') { + char ch = *p++; + if (ch == '/') { + ch = '.'; + } + result->push_back(ch); + } + // ...and replace the semicolon with 'dim' "[]" pairs: + for (size_t i = 0; i < dim; ++i) { + result->append("[]"); + } +} + +std::string PrettyDescriptor(const char* descriptor) { + std::string result; + AppendPrettyDescriptor(descriptor, &result); + return result; +} + +std::string GetJniShortName(const std::string& class_descriptor, const std::string& method) { + // Remove the leading 'L' and trailing ';'... + std::string class_name(class_descriptor); + CHECK_EQ(class_name[0], 'L') << class_name; + CHECK_EQ(class_name[class_name.size() - 1], ';') << class_name; + class_name.erase(0, 1); + class_name.erase(class_name.size() - 1, 1); + + std::string short_name; + short_name += "Java_"; + short_name += MangleForJni(class_name); + short_name += "_"; + short_name += MangleForJni(method); + return short_name; +} + +// See http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp615 for the full rules. +std::string MangleForJni(const std::string& s) { + std::string result; + size_t char_count = CountModifiedUtf8Chars(s.c_str()); + const char* cp = &s[0]; + for (size_t i = 0; i < char_count; ++i) { + uint32_t ch = GetUtf16FromUtf8(&cp); + if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) { + result.push_back(ch); + } else if (ch == '.' || ch == '/') { + result += "_"; + } else if (ch == '_') { + result += "_1"; + } else if (ch == ';') { + result += "_2"; + } else if (ch == '[') { + result += "_3"; + } else { + const uint16_t leading = GetLeadingUtf16Char(ch); + const uint32_t trailing = GetTrailingUtf16Char(ch); + + StringAppendF(&result, "_0%04x", leading); + if (trailing != 0) { + StringAppendF(&result, "_0%04x", trailing); + } + } + } + return result; +} + +std::string DotToDescriptor(const char* class_name) { + std::string descriptor(class_name); + std::replace(descriptor.begin(), descriptor.end(), '.', '/'); + if (descriptor.length() > 0 && descriptor[0] != '[') { + descriptor = "L" + descriptor + ";"; + } + return descriptor; +} + +std::string DescriptorToDot(const char* descriptor) { + size_t length = strlen(descriptor); + if (length > 1) { + if (descriptor[0] == 'L' && descriptor[length - 1] == ';') { + // Descriptors have the leading 'L' and trailing ';' stripped. + std::string result(descriptor + 1, length - 2); + std::replace(result.begin(), result.end(), '/', '.'); + return result; + } else { + // For arrays the 'L' and ';' remain intact. + std::string result(descriptor); + std::replace(result.begin(), result.end(), '/', '.'); + return result; + } + } + // Do nothing for non-class/array descriptors. + return descriptor; +} + +std::string DescriptorToName(const char* descriptor) { + size_t length = strlen(descriptor); + if (descriptor[0] == 'L' && descriptor[length - 1] == ';') { + std::string result(descriptor + 1, length - 2); + return result; + } + return descriptor; +} + +// Helper for IsValidPartOfMemberNameUtf8(), a bit vector indicating valid low ascii. +static uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = { + 0x00000000, // 00..1f low control characters; nothing valid + 0x03ff2010, // 20..3f digits and symbols; valid: '0'..'9', '$', '-' + 0x87fffffe, // 40..5f uppercase etc.; valid: 'A'..'Z', '_' + 0x07fffffe // 60..7f lowercase etc.; valid: 'a'..'z' +}; + +// Helper for IsValidPartOfMemberNameUtf8(); do not call directly. +static bool IsValidPartOfMemberNameUtf8Slow(const char** pUtf8Ptr) { + /* + * It's a multibyte encoded character. Decode it and analyze. We + * accept anything that isn't (a) an improperly encoded low value, + * (b) an improper surrogate pair, (c) an encoded '\0', (d) a high + * control character, or (e) a high space, layout, or special + * character (U+00a0, U+2000..U+200f, U+2028..U+202f, + * U+fff0..U+ffff). This is all specified in the dex format + * document. + */ + + const uint32_t pair = GetUtf16FromUtf8(pUtf8Ptr); + const uint16_t leading = GetLeadingUtf16Char(pair); + + // We have a surrogate pair resulting from a valid 4 byte UTF sequence. + // No further checks are necessary because 4 byte sequences span code + // points [U+10000, U+1FFFFF], which are valid codepoints in a dex + // identifier. Furthermore, GetUtf16FromUtf8 guarantees that each of + // the surrogate halves are valid and well formed in this instance. + if (GetTrailingUtf16Char(pair) != 0) { + return true; + } + + + // We've encountered a one, two or three byte UTF-8 sequence. The + // three byte UTF-8 sequence could be one half of a surrogate pair. + switch (leading >> 8) { + case 0x00: + // It's only valid if it's above the ISO-8859-1 high space (0xa0). + return (leading > 0x00a0); + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + { + // We found a three byte sequence encoding one half of a surrogate. + // Look for the other half. + const uint32_t pair2 = GetUtf16FromUtf8(pUtf8Ptr); + const uint16_t trailing = GetLeadingUtf16Char(pair2); + + return (GetTrailingUtf16Char(pair2) == 0) && (0xdc00 <= trailing && trailing <= 0xdfff); + } + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // It's a trailing surrogate, which is not valid at this point. + return false; + case 0x20: + case 0xff: + // It's in the range that has spaces, controls, and specials. + switch (leading & 0xfff8) { + case 0x2000: + case 0x2008: + case 0x2028: + case 0xfff0: + case 0xfff8: + return false; + } + return true; + default: + return true; + } + + UNREACHABLE(); +} + +/* Return whether the pointed-at modified-UTF-8 encoded character is + * valid as part of a member name, updating the pointer to point past + * the consumed character. This will consume two encoded UTF-16 code + * points if the character is encoded as a surrogate pair. Also, if + * this function returns false, then the given pointer may only have + * been partially advanced. + */ +static bool IsValidPartOfMemberNameUtf8(const char** pUtf8Ptr) { + uint8_t c = (uint8_t) **pUtf8Ptr; + if (LIKELY(c <= 0x7f)) { + // It's low-ascii, so check the table. + uint32_t wordIdx = c >> 5; + uint32_t bitIdx = c & 0x1f; + (*pUtf8Ptr)++; + return (DEX_MEMBER_VALID_LOW_ASCII[wordIdx] & (1 << bitIdx)) != 0; + } + + // It's a multibyte encoded character. Call a non-inline function + // for the heavy lifting. + return IsValidPartOfMemberNameUtf8Slow(pUtf8Ptr); +} + +bool IsValidMemberName(const char* s) { + bool angle_name = false; + + switch (*s) { + case '\0': + // The empty string is not a valid name. + return false; + case '<': + angle_name = true; + s++; + break; + } + + while (true) { + switch (*s) { + case '\0': + return !angle_name; + case '>': + return angle_name && s[1] == '\0'; + } + + if (!IsValidPartOfMemberNameUtf8(&s)) { + return false; + } + } +} + +enum ClassNameType { kName, kDescriptor }; +template<ClassNameType kType, char kSeparator> +static bool IsValidClassName(const char* s) { + int arrayCount = 0; + while (*s == '[') { + arrayCount++; + s++; + } + + if (arrayCount > 255) { + // Arrays may have no more than 255 dimensions. + return false; + } + + ClassNameType type = kType; + if (type != kDescriptor && arrayCount != 0) { + /* + * If we're looking at an array of some sort, then it doesn't + * matter if what is being asked for is a class name; the + * format looks the same as a type descriptor in that case, so + * treat it as such. + */ + type = kDescriptor; + } + + if (type == kDescriptor) { + /* + * We are looking for a descriptor. Either validate it as a + * single-character primitive type, or continue on to check the + * embedded class name (bracketed by "L" and ";"). + */ + switch (*(s++)) { + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': + // These are all single-character descriptors for primitive types. + return (*s == '\0'); + case 'V': + // Non-array void is valid, but you can't have an array of void. + return (arrayCount == 0) && (*s == '\0'); + case 'L': + // Class name: Break out and continue below. + break; + default: + // Oddball descriptor character. + return false; + } + } + + /* + * We just consumed the 'L' that introduces a class name as part + * of a type descriptor, or we are looking for an unadorned class + * name. + */ + + bool sepOrFirst = true; // first character or just encountered a separator. + for (;;) { + uint8_t c = (uint8_t) *s; + switch (c) { + case '\0': + /* + * Premature end for a type descriptor, but valid for + * a class name as long as we haven't encountered an + * empty component (including the degenerate case of + * the empty string ""). + */ + return (type == kName) && !sepOrFirst; + case ';': + /* + * Invalid character for a class name, but the + * legitimate end of a type descriptor. In the latter + * case, make sure that this is the end of the string + * and that it doesn't end with an empty component + * (including the degenerate case of "L;"). + */ + return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0'); + case '/': + case '.': + if (c != kSeparator) { + // The wrong separator character. + return false; + } + if (sepOrFirst) { + // Separator at start or two separators in a row. + return false; + } + sepOrFirst = true; + s++; + break; + default: + if (!IsValidPartOfMemberNameUtf8(&s)) { + return false; + } + sepOrFirst = false; + break; + } + } +} + +bool IsValidBinaryClassName(const char* s) { + return IsValidClassName<kName, '.'>(s); +} + +bool IsValidJniClassName(const char* s) { + return IsValidClassName<kName, '/'>(s); +} + +bool IsValidDescriptor(const char* s) { + return IsValidClassName<kDescriptor, '/'>(s); +} + +void Split(const std::string& s, char separator, std::vector<std::string>* result) { + const char* p = s.data(); + const char* end = p + s.size(); + while (p != end) { + if (*p == separator) { + ++p; + } else { + const char* start = p; + while (++p != end && *p != separator) { + // Skip to the next occurrence of the separator. + } + result->push_back(std::string(start, p - start)); + } + } +} + +std::string PrettyDescriptor(Primitive::Type type) { + return PrettyDescriptor(Primitive::Descriptor(type)); +} + +} // namespace art diff --git a/runtime/dex/descriptors_names.h b/runtime/dex/descriptors_names.h new file mode 100644 index 0000000000..22e9573556 --- /dev/null +++ b/runtime/dex/descriptors_names.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_DEX_DESCRIPTORS_NAMES_H_ +#define ART_RUNTIME_DEX_DESCRIPTORS_NAMES_H_ + +#include <string> + +#include "primitive.h" + +namespace art { + +// Used to implement PrettyClass, PrettyField, PrettyMethod, and PrettyTypeOf, +// one of which is probably more useful to you. +// Returns a human-readable equivalent of 'descriptor'. So "I" would be "int", +// "[[I" would be "int[][]", "[Ljava/lang/String;" would be +// "java.lang.String[]", and so forth. +void AppendPrettyDescriptor(const char* descriptor, std::string* result); +std::string PrettyDescriptor(const char* descriptor); +std::string PrettyDescriptor(Primitive::Type type); + +// Performs JNI name mangling as described in section 11.3 "Linking Native Methods" +// of the JNI spec. +std::string MangleForJni(const std::string& s); + +std::string GetJniShortName(const std::string& class_name, const std::string& method_name); + +// Turn "java.lang.String" into "Ljava/lang/String;". +std::string DotToDescriptor(const char* class_name); + +// Turn "Ljava/lang/String;" into "java.lang.String" using the conventions of +// java.lang.Class.getName(). +std::string DescriptorToDot(const char* descriptor); + +// Turn "Ljava/lang/String;" into "java/lang/String" using the opposite conventions of +// java.lang.Class.getName(). +std::string DescriptorToName(const char* descriptor); + +// Tests for whether 's' is a valid class name in the three common forms: +bool IsValidBinaryClassName(const char* s); // "java.lang.String" +bool IsValidJniClassName(const char* s); // "java/lang/String" +bool IsValidDescriptor(const char* s); // "Ljava/lang/String;" + +// Returns whether the given string is a valid field or method name, +// additionally allowing names that begin with '<' and end with '>'. +bool IsValidMemberName(const char* s); + +} // namespace art + +#endif // ART_RUNTIME_DEX_DESCRIPTORS_NAMES_H_ diff --git a/runtime/dex/dex_file.cc b/runtime/dex/dex_file.cc index f0209f7bec..18eb903551 100644 --- a/runtime/dex/dex_file.cc +++ b/runtime/dex/dex_file.cc @@ -30,11 +30,11 @@ #include "base/enums.h" #include "base/stl_util.h" +#include "descriptors_names.h" #include "dex_file-inl.h" #include "leb128.h" #include "standard_dex_file.h" #include "utf-inl.h" -#include "utils.h" namespace art { diff --git a/runtime/dex/dex_file_annotations.cc b/runtime/dex/dex_file_annotations.cc index 72b18fb420..e01890f541 100644 --- a/runtime/dex/dex_file_annotations.cc +++ b/runtime/dex/dex_file_annotations.cc @@ -1559,7 +1559,7 @@ int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t re return -2; } - CodeItemDebugInfoAccessor accessor(method); + CodeItemDebugInfoAccessor accessor(method->DexInstructionDebugInfo()); DCHECK(accessor.HasCodeItem()) << method->PrettyMethod() << " " << dex_file->GetLocation(); // A method with no line number info should return -1 diff --git a/runtime/dex/dex_file_exception_helpers.cc b/runtime/dex/dex_file_exception_helpers.cc index ad56eb0a0b..8e597fd3dd 100644 --- a/runtime/dex/dex_file_exception_helpers.cc +++ b/runtime/dex/dex_file_exception_helpers.cc @@ -16,7 +16,7 @@ #include "dex_file_exception_helpers.h" -#include "code_item_accessors-no_art-inl.h" +#include "code_item_accessors-inl.h" namespace art { diff --git a/runtime/dex/dex_file_layout.cc b/runtime/dex/dex_file_layout.cc index 1973440d55..312898d82f 100644 --- a/runtime/dex/dex_file_layout.cc +++ b/runtime/dex/dex_file_layout.cc @@ -19,8 +19,8 @@ #include <sys/mman.h> #include "base/file_utils.h" +#include "descriptors_names.h" #include "dex_file.h" -#include "utils.h" namespace art { diff --git a/runtime/dex/dex_file_test.cc b/runtime/dex/dex_file_test.cc index cb721af754..998bfd6c7f 100644 --- a/runtime/dex/dex_file_test.cc +++ b/runtime/dex/dex_file_test.cc @@ -25,13 +25,13 @@ #include "base/unix_file/fd_file.h" #include "code_item_accessors-inl.h" #include "common_runtime_test.h" +#include "descriptors_names.h" #include "dex_file-inl.h" #include "dex_file_loader.h" #include "mem_map.h" #include "os.h" #include "scoped_thread_state_change-inl.h" #include "thread-current-inl.h" -#include "utils.h" namespace art { diff --git a/runtime/dex/dex_file_verifier.cc b/runtime/dex/dex_file_verifier.cc index f7fdbb027c..62667052ad 100644 --- a/runtime/dex/dex_file_verifier.cc +++ b/runtime/dex/dex_file_verifier.cc @@ -23,14 +23,12 @@ #include "android-base/stringprintf.h" -#include "code_item_accessors-no_art-inl.h" +#include "code_item_accessors-inl.h" +#include "descriptors_names.h" #include "dex_file-inl.h" -#include "experimental_flags.h" #include "leb128.h" #include "modifiers.h" -#include "safe_map.h" #include "utf-inl.h" -#include "utils.h" namespace art { diff --git a/runtime/dex/dex_file_verifier_test.cc b/runtime/dex/dex_file_verifier_test.cc index 9759685961..d73a7fbfa3 100644 --- a/runtime/dex/dex_file_verifier_test.cc +++ b/runtime/dex/dex_file_verifier_test.cc @@ -27,6 +27,7 @@ #include "base/macros.h" #include "base/unix_file/fd_file.h" #include "common_runtime_test.h" +#include "descriptors_names.h" #include "dex_file-inl.h" #include "dex_file_loader.h" #include "dex_file_types.h" @@ -34,7 +35,6 @@ #include "scoped_thread_state_change-inl.h" #include "standard_dex_file.h" #include "thread-current-inl.h" -#include "utils.h" namespace art { diff --git a/runtime/dex/dex_instruction.cc b/runtime/dex/dex_instruction.cc index 6ebe2286e8..b84791ffae 100644 --- a/runtime/dex/dex_instruction.cc +++ b/runtime/dex/dex_instruction.cc @@ -24,7 +24,7 @@ #include "android-base/stringprintf.h" #include "dex_file-inl.h" -#include "utils.h" +#include "utf.h" namespace art { diff --git a/runtime/dex/standard_dex_file.cc b/runtime/dex/standard_dex_file.cc index 024f73b4e5..f7317eb997 100644 --- a/runtime/dex/standard_dex_file.cc +++ b/runtime/dex/standard_dex_file.cc @@ -17,7 +17,7 @@ #include "standard_dex_file.h" #include "base/casts.h" -#include "code_item_accessors-no_art-inl.h" +#include "code_item_accessors-inl.h" #include "dex_file-inl.h" #include "leb128.h" diff --git a/runtime/utf-inl.h b/runtime/dex/utf-inl.h index b2d6765fb0..4f626a8580 100644 --- a/runtime/utf-inl.h +++ b/runtime/dex/utf-inl.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_UTF_INL_H_ -#define ART_RUNTIME_UTF_INL_H_ +#ifndef ART_RUNTIME_DEX_UTF_INL_H_ +#define ART_RUNTIME_DEX_UTF_INL_H_ #include "utf.h" @@ -96,4 +96,4 @@ inline int CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(const char* u } // namespace art -#endif // ART_RUNTIME_UTF_INL_H_ +#endif // ART_RUNTIME_DEX_UTF_INL_H_ diff --git a/runtime/utf.cc b/runtime/dex/utf.cc index 32ae187297..772a610140 100644 --- a/runtime/utf.cc +++ b/runtime/dex/utf.cc @@ -17,12 +17,17 @@ #include "utf.h" #include <android-base/logging.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> #include "base/casts.h" #include "utf-inl.h" namespace art { +using android::base::StringAppendF; +using android::base::StringPrintf; + // This is used only from debugger and test code. size_t CountModifiedUtf8Chars(const char* utf8) { return CountModifiedUtf8Chars(utf8, strlen(utf8)); @@ -262,4 +267,55 @@ size_t CountUtf8Bytes(const uint16_t* chars, size_t char_count) { return result; } +static inline constexpr bool NeedsEscaping(uint16_t ch) { + return (ch < ' ' || ch > '~'); +} + +std::string PrintableChar(uint16_t ch) { + std::string result; + result += '\''; + if (NeedsEscaping(ch)) { + StringAppendF(&result, "\\u%04x", ch); + } else { + result += static_cast<std::string::value_type>(ch); + } + result += '\''; + return result; +} + +std::string PrintableString(const char* utf) { + std::string result; + result += '"'; + const char* p = utf; + size_t char_count = CountModifiedUtf8Chars(p); + for (size_t i = 0; i < char_count; ++i) { + uint32_t ch = GetUtf16FromUtf8(&p); + if (ch == '\\') { + result += "\\\\"; + } else if (ch == '\n') { + result += "\\n"; + } else if (ch == '\r') { + result += "\\r"; + } else if (ch == '\t') { + result += "\\t"; + } else { + const uint16_t leading = GetLeadingUtf16Char(ch); + + if (NeedsEscaping(leading)) { + StringAppendF(&result, "\\u%04x", leading); + } else { + result += static_cast<std::string::value_type>(leading); + } + + const uint32_t trailing = GetTrailingUtf16Char(ch); + if (trailing != 0) { + // All high surrogates will need escaping. + StringAppendF(&result, "\\u%04x", trailing); + } + } + } + result += '"'; + return result; +} + } // namespace art diff --git a/runtime/utf.h b/runtime/dex/utf.h index cbb32fa6cd..4adfc4af8c 100644 --- a/runtime/utf.h +++ b/runtime/dex/utf.h @@ -14,14 +14,16 @@ * limitations under the License. */ -#ifndef ART_RUNTIME_UTF_H_ -#define ART_RUNTIME_UTF_H_ +#ifndef ART_RUNTIME_DEX_UTF_H_ +#define ART_RUNTIME_DEX_UTF_H_ #include "base/macros.h" #include <stddef.h> #include <stdint.h> +#include <string> + /* * All UTF-8 in art is actually modified UTF-8. Mostly, this distinction * doesn't matter. @@ -121,6 +123,13 @@ ALWAYS_INLINE uint16_t GetLeadingUtf16Char(uint32_t maybe_pair); */ ALWAYS_INLINE uint16_t GetTrailingUtf16Char(uint32_t maybe_pair); +// Returns a printable (escaped) version of a character. +std::string PrintableChar(uint16_t ch); + +// Returns an ASCII string corresponding to the given UTF-8 string. +// Java escapes are used for non-ASCII characters. +std::string PrintableString(const char* utf8); + } // namespace art -#endif // ART_RUNTIME_UTF_H_ +#endif // ART_RUNTIME_DEX_UTF_H_ diff --git a/runtime/utf_test.cc b/runtime/dex/utf_test.cc index d1e97515d3..d1e97515d3 100644 --- a/runtime/utf_test.cc +++ b/runtime/dex/utf_test.cc diff --git a/runtime/entrypoints/quick/quick_throw_entrypoints.cc b/runtime/entrypoints/quick/quick_throw_entrypoints.cc index 565b4edcc3..9b0756b529 100644 --- a/runtime/entrypoints/quick/quick_throw_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_throw_entrypoints.cc @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "art_method-inl.h" #include "callee_save_frame.h" #include "common_throws.h" #include "mirror/object-inl.h" diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index f727690c11..c5157ce9f4 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -785,7 +785,7 @@ extern "C" uint64_t artQuickToInterpreterBridge(ArtMethod* method, Thread* self, uint32_t shorty_len = 0; ArtMethod* non_proxy_method = method->GetInterfaceMethodIfProxy(kRuntimePointerSize); DCHECK(non_proxy_method->GetCodeItem() != nullptr) << method->PrettyMethod(); - CodeItemDataAccessor accessor(non_proxy_method); + CodeItemDataAccessor accessor(non_proxy_method->DexInstructionData()); const char* shorty = non_proxy_method->GetShorty(&shorty_len); JValue result; @@ -1121,7 +1121,7 @@ extern "C" const void* artQuickResolutionTrampoline( // code. if (!found_stack_map || kIsDebugBuild) { uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); - CodeItemInstructionAccessor accessor(caller); + CodeItemInstructionAccessor accessor(caller->DexInstructions()); CHECK_LT(dex_pc, accessor.InsnsSizeInCodeUnits()); const Instruction& instr = accessor.InstructionAt(dex_pc); Instruction::Code instr_code = instr.Opcode(); diff --git a/runtime/imtable-inl.h b/runtime/imtable-inl.h index 6237cca9e4..93346f6151 100644 --- a/runtime/imtable-inl.h +++ b/runtime/imtable-inl.h @@ -21,7 +21,7 @@ #include "art_method-inl.h" #include "dex/dex_file.h" -#include "utf.h" +#include "dex/utf.h" namespace art { diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc index 5b93d3b873..4b964f648b 100644 --- a/runtime/intern_table.cc +++ b/runtime/intern_table.cc @@ -18,6 +18,7 @@ #include <memory> +#include "dex/utf.h" #include "gc/collector/garbage_collector.h" #include "gc/space/image_space.h" #include "gc/weak_root_state.h" @@ -30,7 +31,6 @@ #include "object_callbacks.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" -#include "utf.h" namespace art { diff --git a/runtime/intern_table_test.cc b/runtime/intern_table_test.cc index 9c3ea8d864..b56c48d78c 100644 --- a/runtime/intern_table_test.cc +++ b/runtime/intern_table_test.cc @@ -18,12 +18,12 @@ #include "base/hash_set.h" #include "common_runtime_test.h" +#include "dex/utf.h" #include "gc_root-inl.h" #include "handle_scope-inl.h" #include "mirror/object.h" #include "mirror/string.h" #include "scoped_thread_state_change-inl.h" -#include "utf.h" namespace art { diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index 54db87297d..735c0e815a 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -389,7 +389,7 @@ void EnterInterpreterFromInvoke(Thread* self, } const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); uint16_t num_regs; uint16_t num_ins; if (accessor.HasCodeItem()) { @@ -499,7 +499,7 @@ void EnterInterpreterFromDeoptimize(Thread* self, DCHECK(!shadow_frame->GetMethod()->MustCountLocks()); self->SetTopOfShadowStack(shadow_frame); - CodeItemDataAccessor accessor(shadow_frame->GetMethod()); + CodeItemDataAccessor accessor(shadow_frame->GetMethod()->DexInstructionData()); const uint32_t dex_pc = shadow_frame->GetDexPC(); uint32_t new_dex_pc = dex_pc; if (UNLIKELY(self->IsExceptionPending())) { diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 475f93803d..d53da215a2 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -1320,7 +1320,7 @@ static inline bool DoCallCommon(ArtMethod* called_method, } // Compute method information. - CodeItemDataAccessor accessor(called_method); + CodeItemDataAccessor accessor(called_method->DexInstructionData()); // Number of registers for the callee's call frame. uint16_t num_regs; // Test whether to use the interpreter or compiler entrypoint, and save that result to pass to diff --git a/runtime/interpreter/shadow_frame.cc b/runtime/interpreter/shadow_frame.cc index fe7e3e0a9b..264ec6a997 100644 --- a/runtime/interpreter/shadow_frame.cc +++ b/runtime/interpreter/shadow_frame.cc @@ -28,7 +28,7 @@ mirror::Object* ShadowFrame::GetThisObject() const { return GetVRegReference(0); } else { CHECK(m->GetCodeItem() != nullptr) << ArtMethod::PrettyMethod(m); - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); uint16_t reg = accessor.RegistersSize() - accessor.InsSize(); return GetVRegReference(reg); } diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc index 89eef88b88..90cac853ff 100644 --- a/runtime/jdwp/jdwp_handler.cc +++ b/runtime/jdwp/jdwp_handler.cc @@ -27,6 +27,7 @@ #include "base/logging.h" // For VLOG. #include "base/macros.h" #include "debugger.h" +#include "dex/utf.h" #include "jdwp/jdwp_constants.h" #include "jdwp/jdwp_event.h" #include "jdwp/jdwp_expand_buf.h" @@ -34,7 +35,6 @@ #include "runtime.h" #include "scoped_thread_state_change-inl.h" #include "thread-current-inl.h" -#include "utils.h" namespace art { diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 12bf79d7ca..1baa613bb5 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -467,7 +467,7 @@ bool Jit::MaybeDoOnStackReplacement(Thread* thread, // Fetch some data before looking up for an OSR method. We don't want thread // suspension once we hold an OSR method, as the JIT code cache could delete the OSR // method while we are being suspended. - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); const size_t number_of_vregs = accessor.RegistersSize(); const char* shorty = method->GetShorty(); std::string method_name(VLOG_IS_ON(jit) ? method->PrettyMethod() : ""); diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index c40360f612..dc0d65dcc1 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -33,6 +33,7 @@ #include "base/stl_util.h" #include "class_linker-inl.h" #include "dex/dex_file-inl.h" +#include "dex/utf.h" #include "fault_handler.h" #include "hidden_api.h" #include "gc/accounting/card_table-inl.h" @@ -57,7 +58,6 @@ #include "safe_map.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" -#include "utf.h" #include "well_known_classes.h" namespace { diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index 8bb3bec9ac..2701ec66a4 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -415,7 +415,7 @@ static inline bool MethodHandleInvokeMethod(ArtMethod* called_method, const InstructionOperands* const operands, JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) { // Compute method information. - CodeItemDataAccessor accessor(called_method); + CodeItemDataAccessor accessor(called_method->DexInstructionData()); // Number of registers for the callee's call frame. Note that for non-exact // invokes, we always derive this information from the callee method. We @@ -557,7 +557,7 @@ static inline bool MethodHandleInvokeTransform(ArtMethod* called_method, // - One for the only method argument (an EmulatedStackFrame). static constexpr size_t kNumRegsForTransform = 2; - CodeItemDataAccessor accessor(called_method); + CodeItemDataAccessor accessor(called_method->DexInstructionData()); DCHECK_EQ(kNumRegsForTransform, accessor.RegistersSize()); DCHECK_EQ(kNumRegsForTransform, accessor.InsSize()); @@ -1041,7 +1041,7 @@ static inline bool MethodHandleInvokeExactInternal( } // Compute method information. - CodeItemDataAccessor accessor(called_method); + CodeItemDataAccessor accessor(called_method->DexInstructionData()); uint16_t num_regs; size_t num_input_regs; size_t first_dest_reg; diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h index 24c75ec0d8..8c2a49c5f6 100644 --- a/runtime/mirror/string-inl.h +++ b/runtime/mirror/string-inl.h @@ -24,11 +24,11 @@ #include "base/bit_utils.h" #include "class.h" #include "common_throws.h" +#include "dex/utf.h" #include "gc/heap-inl.h" #include "globals.h" #include "runtime.h" #include "thread.h" -#include "utf.h" #include "utils.h" namespace art { diff --git a/runtime/mirror/string.cc b/runtime/mirror/string.cc index 82ff6ddead..cad84ceecb 100644 --- a/runtime/mirror/string.cc +++ b/runtime/mirror/string.cc @@ -21,6 +21,7 @@ #include "base/array_ref.h" #include "base/stl_util.h" #include "class-inl.h" +#include "dex/utf-inl.h" #include "gc/accounting/card_table-inl.h" #include "gc_root-inl.h" #include "handle_scope-inl.h" @@ -29,7 +30,6 @@ #include "runtime.h" #include "string-inl.h" #include "thread.h" -#include "utf-inl.h" namespace art { namespace mirror { diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 325591fb53..0c9c65a401 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -1378,7 +1378,7 @@ void Monitor::VisitLocks(StackVisitor* stack_visitor, void (*callback)(mirror::O // Is there any reason to believe there's any synchronization in this method? CHECK(m->GetCodeItem() != nullptr) << m->PrettyMethod(); - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); if (accessor.TriesSize() == 0) { return; // No "tries" implies no synchronization, so no held locks to report. } diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 5544275984..a1f23bdfb8 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -25,6 +25,7 @@ #include "common_throws.h" #include "dex/dex_file-inl.h" #include "dex/dex_file_annotations.h" +#include "dex/utf.h" #include "hidden_api.h" #include "jni_internal.h" #include "mirror/class-inl.h" @@ -43,7 +44,6 @@ #include "reflection.h" #include "scoped_fast_native_object_access-inl.h" #include "scoped_thread_state_change-inl.h" -#include "utf.h" #include "well_known_classes.h" namespace art { diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 307f7b96ed..dc4bae3415 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -47,6 +47,7 @@ #include "dex/dex_file_loader.h" #include "dex/dex_file_types.h" #include "dex/standard_dex_file.h" +#include "dex/utf-inl.h" #include "elf_file.h" #include "elf_utils.h" #include "gc_root.h" @@ -60,7 +61,6 @@ #include "os.h" #include "runtime.h" #include "type_lookup_table.h" -#include "utf-inl.h" #include "utils.h" #include "vdex_file.h" diff --git a/runtime/oat_file.h b/runtime/oat_file.h index 50a706d1ba..46c692e568 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -28,12 +28,12 @@ #include "compiler_filter.h" #include "dex/dex_file.h" #include "dex/dex_file_layout.h" +#include "dex/utf.h" #include "index_bss_mapping.h" #include "mirror/object.h" #include "oat.h" #include "os.h" #include "type_lookup_table.h" -#include "utf.h" #include "utils.h" namespace art { diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 3a7640fa8b..006405f095 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -222,7 +222,7 @@ void QuickExceptionHandler::SetCatchEnvironmentForOptimizedHandler(StackVisitor* self_->DumpStack(LOG_STREAM(INFO) << "Setting catch phis: "); } - CodeItemDataAccessor accessor(handler_method_); + CodeItemDataAccessor accessor(handler_method_->DexInstructionData()); const size_t number_of_vregs = accessor.RegistersSize(); CodeInfo code_info = handler_method_header_->GetOptimizedCodeInfo(); CodeInfoEncoding encoding = code_info.ExtractEncoding(); @@ -360,7 +360,7 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { const size_t frame_id = GetFrameId(); ShadowFrame* new_frame = GetThread()->FindDebuggerShadowFrame(frame_id); const bool* updated_vregs; - CodeItemDataAccessor accessor(method); + CodeItemDataAccessor accessor(method->DexInstructionData()); const size_t num_regs = accessor.RegistersSize(); if (new_frame == nullptr) { new_frame = ShadowFrame::CreateDeoptimizedFrame(num_regs, nullptr, method, GetDexPc()); @@ -408,7 +408,7 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { uintptr_t native_pc_offset = method_header->NativeQuickPcOffset(GetCurrentQuickFramePc()); CodeInfoEncoding encoding = code_info.ExtractEncoding(); StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset, encoding); - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); const size_t number_of_vregs = accessor.RegistersSize(); uint32_t register_mask = code_info.GetRegisterMaskOf(encoding, stack_map); BitMemoryRegion stack_mask = code_info.GetStackMaskOf(encoding, stack_map); diff --git a/runtime/stack.cc b/runtime/stack.cc index dfdea28ae8..229238e0f7 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -154,7 +154,7 @@ mirror::Object* StackVisitor::GetThisObject() const { return cur_shadow_frame_->GetVRegReference(0); } } else { - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); if (!accessor.HasCodeItem()) { UNIMPLEMENTED(ERROR) << "Failed to determine this object of abstract or proxy method: " << ArtMethod::PrettyMethod(m); @@ -225,7 +225,7 @@ bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKin DCHECK_EQ(m, GetMethod()); // Can't be null or how would we compile its instructions? DCHECK(m->GetCodeItem() != nullptr) << m->PrettyMethod(); - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); uint16_t number_of_dex_registers = accessor.RegistersSize(); DCHECK_LT(vreg, number_of_dex_registers); const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); @@ -395,7 +395,7 @@ bool StackVisitor::SetVReg(ArtMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind) { - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); if (!accessor.HasCodeItem()) { return false; } @@ -432,7 +432,7 @@ bool StackVisitor::SetVRegPair(ArtMethod* m, LOG(FATAL) << "Expected long or double: kind_lo=" << kind_lo << ", kind_hi=" << kind_hi; UNREACHABLE(); } - CodeItemDataAccessor accessor(m); + CodeItemDataAccessor accessor(m->DexInstructionData()); if (!accessor.HasCodeItem()) { return false; } diff --git a/runtime/string_reference.h b/runtime/string_reference.h index 97661c6019..1ee5d6d53a 100644 --- a/runtime/string_reference.h +++ b/runtime/string_reference.h @@ -24,7 +24,7 @@ #include "dex/dex_file-inl.h" #include "dex/dex_file_reference.h" #include "dex/dex_file_types.h" -#include "utf-inl.h" +#include "dex/utf-inl.h" namespace art { diff --git a/runtime/thread.cc b/runtime/thread.cc index 46cb751b93..3fe954c895 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -3618,7 +3618,7 @@ class ReferenceMapVisitor : public StackVisitor { const CodeInfoEncoding& _encoding, const StackMap& map, RootVisitor& _visitor) - : number_of_dex_registers(CodeItemDataAccessor(method).RegistersSize()), + : number_of_dex_registers(method->DexInstructionData().RegistersSize()), code_info(_code_info), encoding(_encoding), dex_register_map(code_info.GetDexRegisterMapOf(map, diff --git a/runtime/type_lookup_table.cc b/runtime/type_lookup_table.cc index 649a4f9547..925a9089cb 100644 --- a/runtime/type_lookup_table.cc +++ b/runtime/type_lookup_table.cc @@ -21,7 +21,7 @@ #include "base/bit_utils.h" #include "dex/dex_file-inl.h" -#include "utf-inl.h" +#include "dex/utf-inl.h" #include "utils.h" namespace art { diff --git a/runtime/type_lookup_table.h b/runtime/type_lookup_table.h index 50c93ad9f0..a1f9519f18 100644 --- a/runtime/type_lookup_table.h +++ b/runtime/type_lookup_table.h @@ -18,8 +18,8 @@ #define ART_RUNTIME_TYPE_LOOKUP_TABLE_H_ #include "dex/dex_file_types.h" +#include "dex/utf.h" #include "leb128.h" -#include "utf.h" namespace art { diff --git a/runtime/type_lookup_table_test.cc b/runtime/type_lookup_table_test.cc index d04652a8e7..b6ab6da78c 100644 --- a/runtime/type_lookup_table_test.cc +++ b/runtime/type_lookup_table_test.cc @@ -20,8 +20,8 @@ #include "common_runtime_test.h" #include "dex/dex_file-inl.h" +#include "dex/utf-inl.h" #include "scoped_thread_state_change-inl.h" -#include "utf-inl.h" namespace art { diff --git a/runtime/utils.cc b/runtime/utils.cc index b2ec669f32..393b18e1b3 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -30,8 +30,8 @@ #include "android-base/stringprintf.h" #include "android-base/strings.h" +#include "dex/utf-inl.h" #include "os.h" -#include "utf-inl.h" #if defined(__APPLE__) #include <crt_externs.h> @@ -151,57 +151,6 @@ std::string PrettySize(int64_t byte_count) { negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]); } -static inline constexpr bool NeedsEscaping(uint16_t ch) { - return (ch < ' ' || ch > '~'); -} - -std::string PrintableChar(uint16_t ch) { - std::string result; - result += '\''; - if (NeedsEscaping(ch)) { - StringAppendF(&result, "\\u%04x", ch); - } else { - result += static_cast<std::string::value_type>(ch); - } - result += '\''; - return result; -} - -std::string PrintableString(const char* utf) { - std::string result; - result += '"'; - const char* p = utf; - size_t char_count = CountModifiedUtf8Chars(p); - for (size_t i = 0; i < char_count; ++i) { - uint32_t ch = GetUtf16FromUtf8(&p); - if (ch == '\\') { - result += "\\\\"; - } else if (ch == '\n') { - result += "\\n"; - } else if (ch == '\r') { - result += "\\r"; - } else if (ch == '\t') { - result += "\\t"; - } else { - const uint16_t leading = GetLeadingUtf16Char(ch); - - if (NeedsEscaping(leading)) { - StringAppendF(&result, "\\u%04x", leading); - } else { - result += static_cast<std::string::value_type>(leading); - } - - const uint32_t trailing = GetTrailingUtf16Char(ch); - if (trailing != 0) { - // All high surrogates will need escaping. - StringAppendF(&result, "\\u%04x", trailing); - } - } - } - result += '"'; - return result; -} - std::string GetJniShortName(const std::string& class_descriptor, const std::string& method) { // Remove the leading 'L' and trailing ';'... std::string class_name(class_descriptor); diff --git a/runtime/utils.h b/runtime/utils.h index abdafcc9f7..443b0cc398 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -67,12 +67,6 @@ static inline uint32_t PointerToLowMemUInt32(const void* p) { return intp & 0xFFFFFFFFU; } -std::string PrintableChar(uint16_t ch); - -// Returns an ASCII string corresponding to the given UTF-8 string. -// Java escapes are used for non-ASCII characters. -std::string PrintableString(const char* utf8); - // Used to implement PrettyClass, PrettyField, PrettyMethod, and PrettyTypeOf, // one of which is probably more useful to you. // Returns a human-readable equivalent of 'descriptor'. So "I" would be "int", diff --git a/test/466-get-live-vreg/get_live_vreg_jni.cc b/test/466-get-live-vreg/get_live_vreg_jni.cc index aeb9e44541..44ea0c9877 100644 --- a/test/466-get-live-vreg/get_live_vreg_jni.cc +++ b/test/466-get-live-vreg/get_live_vreg_jni.cc @@ -42,7 +42,8 @@ class TestVisitor : public StackVisitor { CHECK(GetVReg(m, 0, kIntVReg, &value)); CHECK_EQ(value, 42u); } else if (m_name.compare("$opt$noinline$testIntervalHole") == 0) { - uint32_t number_of_dex_registers = CodeItemDataAccessor(m).RegistersSize(); + uint32_t number_of_dex_registers = + CodeItemDataAccessor(m->DexInstructionData()).RegistersSize(); uint32_t dex_register_of_first_parameter = number_of_dex_registers - 2; found_method_ = true; uint32_t value = 0; diff --git a/test/Android.bp b/test/Android.bp index 470a68f386..2985077cc4 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -62,6 +62,7 @@ art_cc_defaults { "libvixld-arm", "libvixld-arm64", "libart-gtest", + "libdexfile", "libbase", "libicuuc", @@ -113,6 +114,7 @@ art_cc_defaults { shared_libs: [ "libartd", "libartd-compiler", + "libdexfile", ], static_libs: [ "libgtest", @@ -149,6 +151,7 @@ art_cc_library { shared_libs: [ "libartd", "libartd-compiler", + "libdexfile", "libbase", "libbacktrace", ], @@ -166,6 +169,7 @@ cc_defaults { "art_defaults", ], shared_libs: [ + "libdexfile", "libbacktrace", "libbase", "libnativehelper", @@ -264,6 +268,7 @@ art_cc_defaults { "1943-suspend-raw-monitor-wait/native_suspend_monitor.cc", ], shared_libs: [ + "libdexfile", "libbase", ], header_libs: [ @@ -393,6 +398,7 @@ cc_defaults { "708-jit-cache-churn/jit.cc", ], shared_libs: [ + "libdexfile", "libbacktrace", "libbase", "libnativehelper", diff --git a/tools/hiddenapi/Android.bp b/tools/hiddenapi/Android.bp index a78bc43aa4..f9824f1fa3 100644 --- a/tools/hiddenapi/Android.bp +++ b/tools/hiddenapi/Android.bp @@ -30,6 +30,7 @@ cc_defaults { }, shared_libs: [ + "libdexfile", "libbase", ], } |