diff options
31 files changed, 371 insertions, 44 deletions
diff --git a/cmdline/cmdline.h b/cmdline/cmdline.h index 4dcaf804de..dec9c83165 100644 --- a/cmdline/cmdline.h +++ b/cmdline/cmdline.h @@ -293,7 +293,7 @@ struct CmdlineArgs { template <typename Args = CmdlineArgs> struct CmdlineMain { int Main(int argc, char** argv) { - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); std::unique_ptr<Args> args = std::unique_ptr<Args>(CreateArguments()); args_ = args.get(); diff --git a/cmdline/cmdline_parser_test.cc b/cmdline/cmdline_parser_test.cc index 5809dcd4e1..cad51045aa 100644 --- a/cmdline/cmdline_parser_test.cc +++ b/cmdline/cmdline_parser_test.cc @@ -122,7 +122,7 @@ class CmdlineParserTest : public ::testing::Test { using RuntimeParser = ParsedOptions::RuntimeParser; static void SetUpTestCase() { - art::InitLogging(nullptr); // argv = null + art::InitLogging(nullptr, art::Runtime::Aborter); // argv = null } virtual void SetUp() { diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index fbdb1155dc..8f15ea4a05 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -461,6 +461,12 @@ void ImageWriter::PrepareDexCacheArraySlots() { dex_cache); DCHECK_EQ(dex_file->NumStringIds() != 0u, dex_cache->GetStrings() != nullptr); AddDexCacheArrayRelocation(dex_cache->GetStrings(), start + layout.StringsOffset(), dex_cache); + + if (dex_cache->GetResolvedMethodTypes() != nullptr) { + AddDexCacheArrayRelocation(dex_cache->GetResolvedMethodTypes(), + start + layout.MethodTypesOffset(), + dex_cache); + } } } @@ -2170,6 +2176,14 @@ void ImageWriter::FixupDexCache(mirror::DexCache* orig_dex_cache, mirror::DexCache::SetElementPtrSize(copy_fields, i, copy, target_ptr_size_); } } + mirror::MethodTypeDexCacheType* orig_method_types = orig_dex_cache->GetResolvedMethodTypes(); + if (orig_method_types != nullptr) { + copy_dex_cache->SetFieldPtrWithSize<false>(mirror::DexCache::ResolvedMethodTypesOffset(), + NativeLocationInImage(orig_method_types), + PointerSize::k64); + orig_dex_cache->FixupResolvedMethodTypes(NativeCopyLocation(orig_method_types, orig_dex_cache), + ImageAddressVisitor(this)); + } // Remove the DexFile pointers. They will be fixed up when the runtime loads the oat file. Leaving // compiler pointers in here will make the output non-deterministic. diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 57d4386553..0ce13626a2 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1090,7 +1090,7 @@ class Dex2Oat FINAL { original_argc = argc; original_argv = argv; - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); // Skip over argv[0]. argv++; diff --git a/dexdump/dexdump_main.cc b/dexdump/dexdump_main.cc index 5c032a0bb6..74cae3c961 100644 --- a/dexdump/dexdump_main.cc +++ b/dexdump/dexdump_main.cc @@ -29,6 +29,7 @@ #include <unistd.h> #include "base/logging.h" +#include "runtime.h" #include "mem_map.h" namespace art { @@ -59,7 +60,7 @@ static void usage(void) { */ int dexdumpDriver(int argc, char** argv) { // Art specific set up. - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); MemMap::Init(); // Reset options. diff --git a/dexlayout/dexlayout_main.cc b/dexlayout/dexlayout_main.cc index 728e389fcf..2203fba325 100644 --- a/dexlayout/dexlayout_main.cc +++ b/dexlayout/dexlayout_main.cc @@ -31,6 +31,7 @@ #include "base/logging.h" #include "jit/offline_profiling_info.h" +#include "runtime.h" #include "mem_map.h" namespace art { @@ -65,7 +66,7 @@ static void Usage(void) { */ int DexlayoutDriver(int argc, char** argv) { // Art specific set up. - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); MemMap::Init(); // Reset options. diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc index a1bde0e919..68473c43ae 100644 --- a/dexlist/dexlist.cc +++ b/dexlist/dexlist.cc @@ -213,7 +213,7 @@ static void usage(void) { */ int dexlistDriver(int argc, char** argv) { // Art specific set up. - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); MemMap::Init(); // Reset options. diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index d6b52dbe63..986f265b3f 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -677,6 +677,16 @@ void PatchOat::PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots mirror::DexCache::SetElementPtrSize(copy_fields, j, copy, pointer_size); } } + mirror::MethodTypeDexCacheType* orig_method_types = orig_dex_cache->GetResolvedMethodTypes(); + mirror::MethodTypeDexCacheType* relocated_method_types = + RelocatedAddressOfPointer(orig_method_types); + copy_dex_cache->SetField64<false>( + mirror::DexCache::ResolvedMethodTypesOffset(), + static_cast<int64_t>(reinterpret_cast<uintptr_t>(relocated_method_types))); + if (orig_method_types != nullptr) { + orig_dex_cache->FixupResolvedMethodTypes(RelocatedCopyOf(orig_method_types), + RelocatedPointerVisitor(this)); + } } } @@ -1360,15 +1370,13 @@ static int ParseFd(const StringPiece& option, const char* cmdline_arg) { } static int patchoat(int argc, char **argv) { - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); MemMap::Init(); const bool debug = kIsDebugBuild; orig_argc = argc; orig_argv = argv; TimingLogger timings("patcher", false, false); - InitLogging(argv); - // Skip over the command name. argv++; argc--; diff --git a/profman/profman.cc b/profman/profman.cc index 7722e8041a..b17816be0c 100644 --- a/profman/profman.cc +++ b/profman/profman.cc @@ -33,6 +33,7 @@ #include "base/unix_file/fd_file.h" #include "dex_file.h" #include "jit/offline_profiling_info.h" +#include "runtime.h" #include "utils.h" #include "zip_archive.h" #include "profile_assistant.h" @@ -143,7 +144,7 @@ class ProfMan FINAL { original_argc = argc; original_argv = argv; - InitLogging(argv); + InitLogging(argv, Runtime::Aborter); // Skip over the command name. argv++; diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 73c6cf16d4..1aa6a00495 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -227,9 +227,10 @@ inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) { case kDirect: return !IsDirect() || IsStatic(); case kVirtual: { - // We have an error if we are direct or a non-default, non-miranda interface method. + // We have an error if we are direct or a non-copied (i.e. not part of a real class) interface + // method. mirror::Class* methods_class = GetDeclaringClass(); - return IsDirect() || (methods_class->IsInterface() && !IsDefault() && !IsMiranda()); + return IsDirect() || (methods_class->IsInterface() && !IsCopied()); } case kSuper: // Constructors and static methods are called with invoke-direct. diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc index 08c036e60e..6b21a566ee 100644 --- a/runtime/base/logging.cc +++ b/runtime/base/logging.cc @@ -21,14 +21,12 @@ #include <sstream> #include "base/mutex.h" -#include "runtime.h" #include "thread-inl.h" #include "utils.h" // Headers for LogMessage::LogLine. #ifdef ART_TARGET_ANDROID #include <android/log.h> -#include <android/set_abort_message.h> #else #include <sys/types.h> #include <unistd.h> @@ -57,17 +55,7 @@ const char* ProgramInvocationShortName() { : "art"; } -NO_RETURN -static void RuntimeAborter(const char* abort_message) { -#ifdef __ANDROID__ - android_set_abort_message(abort_message); -#else - UNUSED(abort_message); -#endif - Runtime::Abort(abort_message); -} - -void InitLogging(char* argv[]) { +void InitLogging(char* argv[], AbortFunction& abort_function) { if (gCmdLine.get() != nullptr) { return; } @@ -97,7 +85,8 @@ void InitLogging(char* argv[]) { #else #define INIT_LOGGING_DEFAULT_LOGGER android::base::StderrLogger #endif - android::base::InitLogging(argv, INIT_LOGGING_DEFAULT_LOGGER, RuntimeAborter); + android::base::InitLogging(argv, INIT_LOGGING_DEFAULT_LOGGER, + std::move<AbortFunction>(abort_function)); #undef INIT_LOGGING_DEFAULT_LOGGER } diff --git a/runtime/base/logging.h b/runtime/base/logging.h index 5f84204a2c..a173ac2d4d 100644 --- a/runtime/base/logging.h +++ b/runtime/base/logging.h @@ -29,6 +29,9 @@ namespace art { using ::android::base::LogSeverity; using ::android::base::ScopedLogSeverity; +// Abort function. +using AbortFunction = void(const char*); + // The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code, // and the "-verbose:" command line argument. struct LogVerbosity { @@ -71,7 +74,7 @@ extern unsigned int gAborting; // The tag (or '*' for the global level) comes first, followed by a colon // and a letter indicating the minimum priority level we're expected to log. // This can be used to reveal or conceal logs with specific tags. -extern void InitLogging(char* argv[]); +extern void InitLogging(char* argv[], AbortFunction& default_aborter); // Returns the command line used to invoke the current tool or null if InitLogging hasn't been // performed. diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 239cdaea69..d07aa89ee4 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1374,6 +1374,7 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( std::memory_order_relaxed); } + mirror::MethodTypeDexCachePair::Initialize(method_types); dex_cache->SetResolvedMethodTypes(method_types); } } diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index 193f6ee7d9..5409fcbf2f 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -57,7 +57,7 @@ int main(int argc, char **argv) { // everything else. In case you want to see all messages, comment out the line. setenv("ANDROID_LOG_TAGS", "*:e", 1); - art::InitLogging(argv); + art::InitLogging(argv, art::Runtime::Aborter); LOG(INFO) << "Running main() from common_runtime_test.cc..."; testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 81850067e6..e9c8b9520c 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1255,6 +1255,16 @@ class ImageSpaceLoader { } } } + + mirror::MethodTypeDexCacheType* method_types = dex_cache->GetResolvedMethodTypes(); + if (method_types != nullptr) { + mirror::MethodTypeDexCacheType* new_method_types = + fixup_adapter.ForwardObject(method_types); + if (method_types != new_method_types) { + dex_cache->SetResolvedMethodTypes(new_method_types); + } + dex_cache->FixupResolvedMethodTypes<kWithoutReadBarrier>(new_method_types, fixup_adapter); + } } } { diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index bed489f357..36e860837d 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -650,7 +650,11 @@ void Instrumentation::SetEntrypointsInstrumented(bool instrumented) { // Note: ResetQuickAllocEntryPoints only works when the runtime is started. Manually run the // update for just this thread. - ResetQuickAllocEntryPointsForThread(self, nullptr); + // Note: self may be null. One of those paths is setting instrumentation in the Heap + // constructor for gcstress mode. + if (self != nullptr) { + ResetQuickAllocEntryPointsForThread(self, nullptr); + } alloc_entrypoints_instrumented_ = instrumented; } diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index 13d0108b2f..86b5e7a6d1 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -208,6 +208,19 @@ inline void DexCache::FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visi } } +template <ReadBarrierOption kReadBarrierOption, typename Visitor> +inline void DexCache::FixupResolvedMethodTypes(mirror::MethodTypeDexCacheType* dest, + const Visitor& visitor) { + mirror::MethodTypeDexCacheType* src = GetResolvedMethodTypes(); + for (size_t i = 0, count = NumResolvedMethodTypes(); i < count; ++i) { + MethodTypeDexCachePair source = src[i].load(std::memory_order_relaxed); + mirror::MethodType* ptr = source.object.Read<kReadBarrierOption>(); + mirror::MethodType* new_source = visitor(ptr); + source.object = GcRoot<MethodType>(new_source); + dest[i].store(source, std::memory_order_relaxed); + } +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index bbe98c2d53..c3c7ab424a 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -160,6 +160,10 @@ class MANAGED DexCache FINAL : public Object { void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor) REQUIRES_SHARED(Locks::mutator_lock_); + template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor> + void FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, const Visitor& visitor) + REQUIRES_SHARED(Locks::mutator_lock_); + String* GetLocation() REQUIRES_SHARED(Locks::mutator_lock_) { return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_)); } @@ -283,7 +287,7 @@ class MANAGED DexCache FINAL : public Object { MethodTypeDexCacheType* GetResolvedMethodTypes() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) { - return GetFieldPtr<MethodTypeDexCacheType*>(ResolvedMethodTypesOffset()); + return GetFieldPtr64<MethodTypeDexCacheType*>(ResolvedMethodTypesOffset()); } void SetResolvedMethodTypes(MethodTypeDexCacheType* resolved_method_types) diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc index 0d1839baf4..1dd60f8d78 100644 --- a/runtime/monitor_android.cc +++ b/runtime/monitor_android.cc @@ -21,7 +21,7 @@ #include <sys/stat.h> #include <sys/types.h> -#include <android/log.h> +#include <log/log.h> #define EVENT_LOG_TAG_dvm_lock_sample 20003 diff --git a/runtime/runtime.cc b/runtime/runtime.cc index baa4046334..6e15c38a53 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -147,6 +147,10 @@ #include "verifier/method_verifier.h" #include "well_known_classes.h" +#ifdef ART_TARGET_ANDROID +#include <android/set_abort_message.h> +#endif + namespace art { // If a signal isn't handled properly, enable a handler that attempts to dump the Java stack. @@ -495,7 +499,7 @@ void Runtime::SweepSystemWeaks(IsMarkedVisitor* visitor) { bool Runtime::ParseOptions(const RuntimeOptions& raw_options, bool ignore_unrecognized, RuntimeArgumentMap* runtime_options) { - InitLogging(/* argv */ nullptr); // Calls Locks::Init() as a side effect. + InitLogging(/* argv */ nullptr, Aborter); // Calls Locks::Init() as a side effect. bool parsed = ParsedOptions::Parse(raw_options, ignore_unrecognized, runtime_options); if (!parsed) { LOG(ERROR) << "Failed to parse options"; @@ -2095,4 +2099,12 @@ void Runtime::RemoveSystemWeakHolder(gc::AbstractSystemWeakHolder* holder) { } } +NO_RETURN +void Runtime::Aborter(const char* abort_message) { +#ifdef __ANDROID__ + android_set_abort_message(abort_message); +#endif + Runtime::Abort(abort_message); +} + } // namespace art diff --git a/runtime/runtime.h b/runtime/runtime.h index 66fd058bb2..e2ba2626e9 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -662,6 +662,9 @@ class Runtime { void AddSystemWeakHolder(gc::AbstractSystemWeakHolder* holder); void RemoveSystemWeakHolder(gc::AbstractSystemWeakHolder* holder); + NO_RETURN + static void Aborter(const char* abort_message); + private: static void InitPlatformSignalHandlers(); diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h index 5ccd446e0f..5ca7684565 100644 --- a/runtime/utils/dex_cache_arrays_layout-inl.h +++ b/runtime/utils/dex_cache_arrays_layout-inl.h @@ -39,7 +39,7 @@ inline DexCacheArraysLayout::DexCacheArraysLayout(PointerSize pointer_size, fields_offset_( RoundUp(strings_offset_ + StringsSize(header.string_ids_size_), FieldsAlignment())), method_types_offset_( - RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), Alignment())), + RoundUp(fields_offset_ + FieldsSize(header.field_ids_size_), MethodTypesAlignment())), size_( RoundUp(method_types_offset_ + MethodTypesSize(header.proto_ids_size_), Alignment())) { } @@ -51,7 +51,11 @@ inline DexCacheArraysLayout::DexCacheArraysLayout(PointerSize pointer_size, cons inline constexpr size_t DexCacheArraysLayout::Alignment() { // GcRoot<> alignment is 4, i.e. lower than or equal to the pointer alignment. static_assert(alignof(GcRoot<mirror::Class>) == 4, "Expecting alignof(GcRoot<>) == 4"); - static_assert(alignof(mirror::StringDexCacheType) == 8, "Expecting alignof(StringDexCacheType) == 8"); + static_assert(alignof(mirror::StringDexCacheType) == 8, + "Expecting alignof(StringDexCacheType) == 8"); + static_assert(alignof(mirror::MethodTypeDexCacheType) == 8, + "Expecting alignof(MethodTypeDexCacheType) == 8"); + // This is the same as alignof(MethodTypeDexCacheType). return alignof(mirror::StringDexCacheType); } @@ -120,12 +124,6 @@ inline size_t DexCacheArraysLayout::FieldsAlignment() const { return static_cast<size_t>(pointer_size_); } -inline size_t DexCacheArraysLayout::MethodTypeOffset(uint32_t proto_idx) const { - return strings_offset_ - + ElementOffset(PointerSize::k64, - proto_idx % mirror::DexCache::kDexCacheMethodTypeCacheSize); -} - inline size_t DexCacheArraysLayout::MethodTypesSize(size_t num_elements) const { size_t cache_size = mirror::DexCache::kDexCacheMethodTypeCacheSize; if (num_elements < cache_size) { diff --git a/runtime/utils/dex_cache_arrays_layout.h b/runtime/utils/dex_cache_arrays_layout.h index e222b46ef7..ae3bfab38c 100644 --- a/runtime/utils/dex_cache_arrays_layout.h +++ b/runtime/utils/dex_cache_arrays_layout.h @@ -99,8 +99,6 @@ class DexCacheArraysLayout { return method_types_offset_; } - size_t MethodTypeOffset(uint32_t method_type_idx) const; - size_t MethodTypesSize(size_t num_elements) const; size_t MethodTypesAlignment() const; diff --git a/test/978-virtual-interface/build b/test/978-virtual-interface/build new file mode 100755 index 0000000000..14230c2e1d --- /dev/null +++ b/test/978-virtual-interface/build @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright 2015 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. + +# make us exit on a failure +set -e + +./default-build "$@" --experimental default-methods diff --git a/test/978-virtual-interface/expected.txt b/test/978-virtual-interface/expected.txt new file mode 100644 index 0000000000..99071b1d4e --- /dev/null +++ b/test/978-virtual-interface/expected.txt @@ -0,0 +1 @@ +Recieved expected ICCE error! diff --git a/test/978-virtual-interface/info.txt b/test/978-virtual-interface/info.txt new file mode 100644 index 0000000000..0b8a39f550 --- /dev/null +++ b/test/978-virtual-interface/info.txt @@ -0,0 +1,7 @@ +Smali-based regression test for b/32201623 + +This test cannot be run with --jvm. + +This test checks that we correctly detect when one attempts to invoke an +interface method via the invoke-virtual opcode and that correct exceptions are +sent. diff --git a/test/978-virtual-interface/smali/Iface.smali b/test/978-virtual-interface/smali/Iface.smali new file mode 100644 index 0000000000..9c3ef7a0b4 --- /dev/null +++ b/test/978-virtual-interface/smali/Iface.smali @@ -0,0 +1,110 @@ +# /* +# * Copyright (C) 2015 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. +# */ +# +# // Methods are sorted in alphabetical order in dex file. We need 10 padding +# // methods to ensure the 11'th target lines up to the same vtable slot as the +# // first Subtype virtual method (the other 10 are the java/lang/Object; +# // methods). +# interface Iface { +# public default void fakeMethod_A() {} +# public default void fakeMethod_B() {} +# public default void fakeMethod_C() {} +# public default void fakeMethod_D() {} +# public default void fakeMethod_E() {} +# public default void fakeMethod_F() {} +# public default void fakeMethod_G() {} +# public default void fakeMethod_H() {} +# public default void fakeMethod_I() {} +# public default void fakeMethod_J() {} +# public default void fakeMethod_K() {} +# public default void fakeMethod_Target() {} +# } + +.class public abstract interface LIface; + +.super Ljava/lang/Object; + +# // 1 +.method public fakeMethod_A()V + .locals 0 + return-void +.end method + +# // 2 +.method public fakeMethod_B()V + .locals 0 + return-void +.end method + +# // 3 +.method public fakeMethod_C()V + .locals 0 + return-void +.end method + +# // 4 +.method public fakeMethod_D()V + .locals 0 + return-void +.end method + +# // 5 +.method public fakeMethod_E()V + .locals 0 + return-void +.end method + +# // 5 +.method public fakeMethod_F()V + .locals 0 + return-void +.end method + +# // 6 +.method public fakeMethod_G()V + .locals 0 + return-void +.end method + +# // 7 +.method public fakeMethod_H()V + .locals 0 + return-void +.end method + +# // 8 +.method public fakeMethod_I()V + .locals 0 + return-void +.end method + +# // 9 +.method public fakeMethod_J()V + .locals 0 + return-void +.end method + +# // 10 +.method public fakeMethod_K()V + .locals 0 + return-void +.end method + +# // 11 +.method public fakeMethod_Target()V + .locals 0 + return-void +.end method diff --git a/test/978-virtual-interface/smali/Main.smali b/test/978-virtual-interface/smali/Main.smali new file mode 100644 index 0000000000..61b82f3f7b --- /dev/null +++ b/test/978-virtual-interface/smali/Main.smali @@ -0,0 +1,50 @@ +# /* +# * Copyright (C) 2015 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. +# */ +# +# public class Main { +# public static void main(String[] s) { +# Subtype s = new Subtype(); +# try { +# s.callPackage(); +# System.out.println("No error thrown!"); +# } catch (IncompatibleClassChangeError e) { +# System.out.println("Recieved expected ICCE error!"); +# } +# } +# } + +.class public LMain; + +.super Ljava/lang/Object; + +.method public static main([Ljava/lang/String;)V + .locals 3 + + new-instance v0, LSubtype; + invoke-direct {v0}, LSubtype;-><init>()V + sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream; + :try_start + invoke-virtual {v0}, LSubtype;->callPackage()V + const-string v1, "No error thrown!" + invoke-virtual {v2, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + return-void + :try_end + .catch Ljava/lang/IncompatibleClassChangeError; {:try_start .. :try_end} :error_start + :error_start + const-string v1, "Recieved expected ICCE error!" + invoke-virtual {v2, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + return-void +.end method diff --git a/test/978-virtual-interface/smali/Subtype.smali b/test/978-virtual-interface/smali/Subtype.smali new file mode 100644 index 0000000000..f876cf961b --- /dev/null +++ b/test/978-virtual-interface/smali/Subtype.smali @@ -0,0 +1,40 @@ +# /* +# * Copyright (C) 2015 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. +# */ +# +# public class Subtype extends pkg.Target implements Iface{ +# public void callPackage() { +# // Fake into a virtual call. +# // ((Iface)this).fakeMethod_Target(); +# } +# } + +.class public LSubtype; + +.super Lpkg/Target; + +.implements LIface; + +.method public constructor <init>()V + .locals 0 + invoke-direct {p0}, Lpkg/Target;-><init>()V + return-void +.end method + +.method public callPackage()V + .locals 0 + invoke-virtual {p0}, LIface;->fakeMethod_Target()V + return-void +.end method diff --git a/test/978-virtual-interface/smali/Target.smali b/test/978-virtual-interface/smali/Target.smali new file mode 100644 index 0000000000..70108fb6bf --- /dev/null +++ b/test/978-virtual-interface/smali/Target.smali @@ -0,0 +1,40 @@ +# /* +# * Copyright (C) 2015 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. +# */ +# +# package pkg; +# public class Target { +# public void packageMethod() { +# System.out.println("Package method called!"); +# } +# } + +.class public Lpkg/Target; + +.super Ljava/lang/Object; + +.method public constructor <init>()V + .locals 0 + invoke-direct {p0}, Ljava/lang/Object;-><init>()V + return-void +.end method + +.method packageMethod()V + .locals 2 + const-string v1, "Package method called!" + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + return-void +.end method diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index 7a5dab0203..34f8838a99 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -233,11 +233,9 @@ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES), # Disable 149-suspend-all-stress, its output is flaky (b/28988206). # Disable 577-profile-foreign-dex (b/27454772). -# Disable 955-methodhandles-smali until the accompanying smali change has been landed. TEST_ART_BROKEN_ALL_TARGET_TESTS := \ 149-suspend-all-stress \ 577-profile-foreign-dex \ - 955-methodhandles-smali \ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ $(COMPILER_TYPES), $(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \ |